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 130 lines 3.2 kB view raw
1import { 2 createExternalLink, 3 findExternalLink, 4} from "../../github/services/link-manager"; 5import { 6 findTaskByNumber, 7 isTaskInFinalState, 8 updateTaskStatus, 9} from "../../github/services/task-service"; 10import type { GiteaConfig } from "../config"; 11import { 12 findAllIntegrationsByGiteaRepo, 13 repoOwnerLogin, 14} from "../services/integration-lookup"; 15import { extractTaskNumberGitea } from "../utils/branch-matcher"; 16import { resolveTargetStatus } from "../utils/resolve-column"; 17import { baseUrlFromRepositoryHtmlUrl } from "../utils/webhook-repo"; 18 19type PROpenedPayload = { 20 action: string; 21 pull_request: { 22 number: number; 23 title: string; 24 body: string | null; 25 html_url: string; 26 state: string; 27 draft?: boolean; 28 merged?: boolean; 29 head: { 30 ref: string; 31 }; 32 user: { login?: string; username?: string } | null; 33 }; 34 repository: { 35 owner: { login?: string; username?: string }; 36 name: string; 37 html_url: string; 38 }; 39}; 40 41export async function handleGiteaPullRequestOpened(payload: PROpenedPayload) { 42 const { pull_request, repository } = payload; 43 44 const baseUrl = baseUrlFromRepositoryHtmlUrl(repository.html_url); 45 if (!baseUrl) return; 46 47 const owner = repoOwnerLogin(repository); 48 const integrations = await findAllIntegrationsByGiteaRepo( 49 baseUrl, 50 owner, 51 repository.name, 52 ); 53 54 for (const integration of integrations) { 55 if (!integration.project) { 56 continue; 57 } 58 59 let config: GiteaConfig; 60 try { 61 config = JSON.parse(integration.config) as GiteaConfig; 62 } catch (error) { 63 console.error("Invalid Gitea config for integration", { 64 integrationId: integration.id, 65 error, 66 }); 67 continue; 68 } 69 const projectSlug = integration.project.slug; 70 const branchName = pull_request.head.ref; 71 72 const taskNumber = extractTaskNumberGitea( 73 branchName, 74 pull_request.title, 75 pull_request.body ?? undefined, 76 config, 77 projectSlug, 78 ); 79 80 if (!taskNumber) { 81 continue; 82 } 83 84 const task = await findTaskByNumber(integration.projectId, taskNumber); 85 86 if (!task) { 87 continue; 88 } 89 90 const existingLink = await findExternalLink( 91 integration.id, 92 "pull_request", 93 pull_request.number.toString(), 94 ); 95 96 if (existingLink) { 97 continue; 98 } 99 100 await createExternalLink({ 101 taskId: task.id, 102 integrationId: integration.id, 103 resourceType: "pull_request", 104 externalId: pull_request.number.toString(), 105 url: pull_request.html_url, 106 title: pull_request.title, 107 metadata: { 108 state: pull_request.state, 109 draft: pull_request.draft, 110 merged: pull_request.merged, 111 branch: branchName, 112 author: pull_request.user?.login ?? pull_request.user?.username, 113 }, 114 }); 115 116 const targetStatus = await resolveTargetStatus( 117 integration.projectId, 118 "pr_opened", 119 config.statusTransitions?.onPROpen || "in-review", 120 ); 121 122 const isTaskFinal = await isTaskInFinalState(task); 123 124 if (task.status !== targetStatus && !isTaskFinal) { 125 await updateTaskStatus(task.id, targetStatus); 126 } 127 128 return; 129 } 130}