kaneo (minimalist kanban) fork to experiment adding a tangled integration
github.com/usekaneo/kaneo
1import type { PluginContext, TaskStatusChangedEvent } from "../../types";
2import type { GitHubConfig } from "../config";
3import {
4 findExternalLinksByTask,
5 updateExternalLink,
6} from "../services/link-manager";
7import { getGithubApp, getInstallationIdForRepo } from "../utils/github-app";
8import { addLabelsToIssue, removeLabel } from "../utils/labels";
9
10export async function handleTaskStatusChanged(
11 event: TaskStatusChangedEvent,
12 context: PluginContext,
13): Promise<void> {
14 const githubApp = getGithubApp();
15 if (!githubApp) {
16 return;
17 }
18
19 const config = context.config as GitHubConfig;
20 const { repositoryOwner, repositoryName } = config;
21
22 try {
23 const links = await findExternalLinksByTask(event.taskId);
24 const issueLink = links.find(
25 (link) =>
26 link.integrationId === context.integrationId &&
27 link.resourceType === "issue",
28 );
29
30 if (!issueLink) {
31 return;
32 }
33
34 let installationId = config.installationId;
35 if (!installationId) {
36 installationId = await getInstallationIdForRepo(
37 repositoryOwner,
38 repositoryName,
39 );
40 }
41
42 const octokit = await githubApp.getInstallationOctokit(installationId);
43 const issueNumber = Number.parseInt(issueLink.externalId, 10);
44
45 await removeLabel(
46 octokit,
47 repositoryOwner,
48 repositoryName,
49 issueNumber,
50 `status:${event.oldStatus}`,
51 );
52
53 await addLabelsToIssue(
54 octokit,
55 repositoryOwner,
56 repositoryName,
57 issueNumber,
58 [`status:${event.newStatus}`],
59 );
60
61 if (event.newStatus === "done") {
62 await octokit.rest.issues.update({
63 owner: repositoryOwner,
64 repo: repositoryName,
65 issue_number: issueNumber,
66 state: "closed",
67 });
68
69 await updateExternalLink(issueLink.id, {
70 metadata: {
71 ...(issueLink.metadata ? JSON.parse(issueLink.metadata) : {}),
72 state: "closed",
73 },
74 });
75 } else if (event.oldStatus === "done" && event.newStatus !== "done") {
76 await octokit.rest.issues.update({
77 owner: repositoryOwner,
78 repo: repositoryName,
79 issue_number: issueNumber,
80 state: "open",
81 });
82
83 await updateExternalLink(issueLink.id, {
84 metadata: {
85 ...(issueLink.metadata ? JSON.parse(issueLink.metadata) : {}),
86 state: "open",
87 },
88 });
89 }
90 } catch (error) {
91 console.error("Failed to update GitHub issue status:", error);
92 }
93}