kaneo (minimalist kanban) fork to experiment adding a tangled integration github.com/usekaneo/kaneo
0
fork

Configure Feed

Select the types of activity you want to include in your feed.

at cd7cada2f86b4e866a15b4323bb8d6d7ab5bba8b 110 lines 3.0 kB view raw
1import { and, eq } from "drizzle-orm"; 2import db from "../../../database"; 3import { externalLinkTable } from "../../../database/schema"; 4import { updateExternalLink } from "../../github/services/link-manager"; 5import { 6 findTaskById, 7 updateTaskStatus, 8} from "../../github/services/task-service"; 9import type { GiteaConfig } from "../config"; 10import { 11 findAllIntegrationsByGiteaRepo, 12 repoOwnerLogin, 13} from "../services/integration-lookup"; 14import { resolveTargetStatus } from "../utils/resolve-column"; 15import { baseUrlFromRepositoryHtmlUrl } from "../utils/webhook-repo"; 16 17type PRClosedPayload = { 18 action: string; 19 pull_request: { 20 number: number; 21 title: string; 22 html_url: string; 23 state: string; 24 merged: boolean; 25 merged_at: string | null; 26 head: { 27 ref: string; 28 }; 29 }; 30 repository: { 31 owner: { login?: string; username?: string }; 32 name: string; 33 html_url: string; 34 }; 35}; 36 37export async function handleGiteaPullRequestClosed(payload: PRClosedPayload) { 38 const { pull_request, repository } = payload; 39 40 const baseUrl = baseUrlFromRepositoryHtmlUrl(repository.html_url); 41 if (!baseUrl) return; 42 43 const owner = repoOwnerLogin(repository); 44 const integrations = await findAllIntegrationsByGiteaRepo( 45 baseUrl, 46 owner, 47 repository.name, 48 ); 49 50 for (const integration of integrations) { 51 const config = JSON.parse(integration.config) as GiteaConfig; 52 53 const externalLink = await db.query.externalLinkTable.findFirst({ 54 where: and( 55 eq(externalLinkTable.integrationId, integration.id), 56 eq(externalLinkTable.resourceType, "pull_request"), 57 eq(externalLinkTable.externalId, pull_request.number.toString()), 58 ), 59 }); 60 61 if (!externalLink) { 62 continue; 63 } 64 65 const task = await findTaskById(externalLink.taskId); 66 67 if (!task) { 68 continue; 69 } 70 71 const existingMetadata = externalLink.metadata 72 ? JSON.parse(externalLink.metadata) 73 : {}; 74 75 await updateExternalLink(externalLink.id, { 76 metadata: { 77 ...existingMetadata, 78 state: "closed", 79 merged: pull_request.merged, 80 mergedAt: pull_request.merged_at, 81 }, 82 }); 83 84 if (pull_request.merged) { 85 const allTaskPRs = await db.query.externalLinkTable.findMany({ 86 where: and( 87 eq(externalLinkTable.taskId, task.id), 88 eq(externalLinkTable.resourceType, "pull_request"), 89 ), 90 }); 91 92 const hasOpenPRs = allTaskPRs.some((pr) => { 93 if (pr.id === externalLink.id) return false; 94 const metadata = pr.metadata ? JSON.parse(pr.metadata) : {}; 95 return metadata.state === "open"; 96 }); 97 98 if (!hasOpenPRs) { 99 const targetStatus = await resolveTargetStatus( 100 integration.projectId, 101 "pr_merged", 102 config.statusTransitions?.onPRMerge || "done", 103 ); 104 await updateTaskStatus(task.id, targetStatus); 105 } 106 } 107 108 return; 109 } 110}