From b5ab2d9b0cf370bb87a7de05b87576fe5ac7f533 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Maty=C3=A1=C5=A1=20Caras?= Date: Tue, 30 Jul 2024 17:20:00 +0200 Subject: [PATCH] feat: finish tasks on issue closing also sorted some code for better readability --- ..._issue.json => new_issue_no_assignee.json} | 0 act_events/new_issue_w_assignee.json | 15 +++ src/index.ts | 97 +++++++++++++------ 3 files changed, 85 insertions(+), 27 deletions(-) rename act_events/{new_issue.json => new_issue_no_assignee.json} (100%) create mode 100644 act_events/new_issue_w_assignee.json diff --git a/act_events/new_issue.json b/act_events/new_issue_no_assignee.json similarity index 100% rename from act_events/new_issue.json rename to act_events/new_issue_no_assignee.json diff --git a/act_events/new_issue_w_assignee.json b/act_events/new_issue_w_assignee.json new file mode 100644 index 0000000..c49922c --- /dev/null +++ b/act_events/new_issue_w_assignee.json @@ -0,0 +1,15 @@ +{ + "action":"opened", + "issue":{ + "body":"Testing issue through Act", + "number":"123", + "title":"GitHub Action Test", + "url":"https://github.com/hernikplays/freelo-action", + "user":{ + "login":"hernikplays" + }, + "assignee":{ + "login":"hernikplays" + } + } +} \ No newline at end of file diff --git a/src/index.ts b/src/index.ts index a1b3656..86ce3fd 100644 --- a/src/index.ts +++ b/src/index.ts @@ -26,15 +26,40 @@ const comment = context.payload.comment; // constants const apiEndpoint = "https://api.freelo.io/v1"; -const defaultHeaders = { - "User-Agent": "Freelo GitHub Action/1.0.0", - "Content-Type": "application/json", +const defaultOptions = { + auth: { + username: email, + password: apiKey, + }, + headers: { + "User-Agent": "Freelo GitHub Action/1.0.0", + "Content-Type": "application/json", + }, }; const sanitizeOptions: sanitize.IOptions = { allowedTags: ["a", "p", "i", "b", "strong"], allowedAttributes: false, }; +// Load GitHub:Freelo pairing if available +const userPairing: { [key: string]: string } = {}; +try { + for (const u of ( + await readFile("./.github/freelo.txt", { encoding: "utf-8" }) + ).split("\n")) { + const p = u.split(":"); + userPairing[p[0]] = p[1]; + } +} catch (e) { + console.log("No valid freelo.txt found in .github folder, skipping"); +} + +function freeloMention(username: string): string { + return Object.keys(userPairing).includes(username) + ? `
@${username}
` + : `${username}`; +} + try { if (!action) { throw new Error("No action was passed"); @@ -55,28 +80,15 @@ try { throw new Error("Either task-id or tasklist-id needs to be set!"); } - // Load GitHub:Freelo pairing if available - let userPairing: string[] | undefined; - try { - userPairing = (await readFile("./.github/freelo.txt",{encoding:"utf-8"})).split("\n"); - } catch (e) { - console.log("No freelo.txt found in .github folder, skipping"); - } - if (tasklistId) { switch (action) { case "opened": { // New issue has been created, create a task in tasklist - const author = - userPairing && - userPairing.filter((u) => u.includes(issue.user.login)).length > 0 - ? `
@${issue.user.login}
` - : `${issue.user.login}`; - console.log(userPairing?.filter((u) => u.includes(issue.user.login)).length) const taskComment = ` - Created by: ${author}
+ Created by: ${freeloMention(issue.user.login)}
Description: ${sanitize(issue.body ?? "None", sanitizeOptions)}
GitHub issue: #${issue.number}
+ Assigned to: ${issue.assignee ? `${freeloMention(issue.assignee.login)}` : "Nobody"}
(This action was performed automatically) `; @@ -85,18 +97,12 @@ try { comment: { content: taskComment, }, - }; // TODO: assignee + }; const res = await axios.post( `${apiEndpoint}/project/${projectId}/tasklist/${tasklistId}/tasks`, taskContent, - { - headers: defaultHeaders, - auth: { - username: email, - password: apiKey, - }, - }, + defaultOptions, ); // handle potential error response @@ -117,8 +123,45 @@ try { case "edited": break; - case "closed": + case "closed": { + // Get comments and find the related Freelo task ID + const comment = ( + await octokit.rest.issues.listComments({ + owner: context.payload.repository?.owner.login ?? "", + repo: context.payload.repository?.name ?? "", + issue_number: issue.number, + mediaType: { + format: "html", + }, + }) + ).data.filter( + (i) => i.user?.login === "github-actions" && i.user.type === "Bot", + ); + if (comment.length === 0) break; // not a Freelo task, skip + console.log(comment.length); + console.log(comment[0].body_html); + + // Finish task in Freelo + const taskId = /https:\/\/app.freelo.io\/task\/(\d+)/.exec( + comment[0].body_html ?? "", + ); + if (!taskId || taskId.length === 0) { + console.log("Comment found, but no Freelo task ID identified"); + break; + } + + const res = await axios.post( + `${apiEndpoint}/task/${taskId[1]}`, + null, + defaultOptions, + ); + + if (res.status > 399) { + console.error(res.data); + throw new Error("Got an error response from Freelo API"); + } break; + } case "reopened": break; case "assigned":