mirror of
https://github.com/hernikplays/freelo-action.git
synced 2024-11-10 02:38:06 +01:00
feat: complete the other actions
This commit is contained in:
parent
398f274b40
commit
9a098134dd
4 changed files with 607 additions and 222 deletions
|
@ -1,12 +1,12 @@
|
||||||
{
|
{
|
||||||
"action":"opened",
|
"action": "opened",
|
||||||
"issue":{
|
"issue": {
|
||||||
"body":"Testing issue through Act",
|
"body": "Testing issue through Act",
|
||||||
"number":"123",
|
"number": "123",
|
||||||
"title":"GitHub Action Test",
|
"title": "GitHub Action Test",
|
||||||
"url":"https://github.com/hernikplays/freelo-action",
|
"url": "https://github.com/hernikplays/freelo-action",
|
||||||
"user":{
|
"user": {
|
||||||
"login":"hernikplays"
|
"login": "hernikplays"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,15 +1,15 @@
|
||||||
{
|
{
|
||||||
"action":"opened",
|
"action": "opened",
|
||||||
"issue":{
|
"issue": {
|
||||||
"body":"Testing issue through Act",
|
"body": "Testing issue through Act",
|
||||||
"number":"123",
|
"number": "123",
|
||||||
"title":"GitHub Action Test",
|
"title": "GitHub Action Test",
|
||||||
"url":"https://github.com/hernikplays/freelo-action",
|
"url": "https://github.com/hernikplays/freelo-action",
|
||||||
"user":{
|
"user": {
|
||||||
"login":"hernikplays"
|
"login": "hernikplays"
|
||||||
},
|
},
|
||||||
"assignee":{
|
"assignee": {
|
||||||
"login":"hernikplays"
|
"login": "hernikplays"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
310
dist/index.js
vendored
310
dist/index.js
vendored
|
@ -42183,6 +42183,7 @@ var require_sanitize_html = __commonJS((exports, module) => {
|
||||||
// src/index.ts
|
// src/index.ts
|
||||||
var core = __toESM(require_core(), 1);
|
var core = __toESM(require_core(), 1);
|
||||||
var github = __toESM(require_github(), 1);
|
var github = __toESM(require_github(), 1);
|
||||||
|
import {readFile} from "node:fs/promises";
|
||||||
|
|
||||||
// node_modules/axios/lib/helpers/bind.js
|
// node_modules/axios/lib/helpers/bind.js
|
||||||
function bind(fn, thisArg) {
|
function bind(fn, thisArg) {
|
||||||
|
@ -45309,10 +45310,21 @@ var axios_default = axios;
|
||||||
|
|
||||||
// src/index.ts
|
// src/index.ts
|
||||||
var import_sanitize_html = __toESM(require_sanitize_html(), 1);
|
var import_sanitize_html = __toESM(require_sanitize_html(), 1);
|
||||||
import {readFile} from "node:fs/promises";
|
|
||||||
var freeloMention = function(username) {
|
var freeloMention = function(username) {
|
||||||
return Object.keys(userPairing).includes(username) ? `<div><span data-freelo-mention="1" data-freelo-user-id="${userPairing[username]}">@${username}</span></div>` : `<a href="https://github.com/${username}">${username}</a>`;
|
return Object.keys(userPairing).includes(username) ? `<div><span data-freelo-mention="1" data-freelo-user-id="${userPairing[username]}">@${username}</span></div>` : `<a href="https://github.com/${username}">${username}</a>`;
|
||||||
};
|
};
|
||||||
|
async function freeloId(issue_number) {
|
||||||
|
const comment = (await octokit.rest.issues.listComments({
|
||||||
|
...github.context.repo,
|
||||||
|
issue_number,
|
||||||
|
mediaType: {
|
||||||
|
format: "html"
|
||||||
|
}
|
||||||
|
})).data.filter((i) => i.user?.type === "Bot" && i.user.login === "github-actions[bot]");
|
||||||
|
if (comment.length === 0)
|
||||||
|
return;
|
||||||
|
return /https:\/\/app.freelo.io\/task\/(\d+)/.exec(comment[0].body_html ?? "")?.[1];
|
||||||
|
}
|
||||||
var email = core.getInput("email");
|
var email = core.getInput("email");
|
||||||
var apiKey = core.getInput("api-key");
|
var apiKey = core.getInput("api-key");
|
||||||
var projectId = core.getInput("project-id");
|
var projectId = core.getInput("project-id");
|
||||||
|
@ -45358,98 +45370,242 @@ try {
|
||||||
if (!email || !apiKey || !projectId) {
|
if (!email || !apiKey || !projectId) {
|
||||||
throw new Error("You are missing a required parameter. Check the documentation for details.");
|
throw new Error("You are missing a required parameter. Check the documentation for details.");
|
||||||
}
|
}
|
||||||
if (issue) {
|
if (!comment && issue) {
|
||||||
if (issue.pull_request) {
|
|
||||||
throw new Error("Pull requests are not yet supported");
|
|
||||||
}
|
|
||||||
if (!tasklistId && !taskId) {
|
if (!tasklistId && !taskId) {
|
||||||
throw new Error("Either task-id or tasklist-id needs to be set!");
|
throw new Error("Either task-id or tasklist-id needs to be set!");
|
||||||
}
|
}
|
||||||
if (tasklistId) {
|
switch (action) {
|
||||||
switch (action) {
|
case "opened": {
|
||||||
case "opened": {
|
const taskComment = `
|
||||||
const taskComment = `
|
Created by: ${freeloMention(issue.user.login)}<br>
|
||||||
|
Description: ${import_sanitize_html.default(issue.body ?? "None", sanitizeOptions)}<br>
|
||||||
|
GitHub issue: <a href="${issue.pull_request ? issue.pull_request.url : issue.url}">#${issue.number}</a><br>
|
||||||
|
Assigned to: ${issue.assignee ? `${freeloMention(issue.assignee.login)}` : "Nobody"}<br>
|
||||||
|
${issue.pull_request ? "<b>This is a pull request<b><br>" : ""}
|
||||||
|
<i>(This action was performed automatically)</i>
|
||||||
|
`;
|
||||||
|
const labels = [];
|
||||||
|
if (issue.labels) {
|
||||||
|
for (const label of issue.labels) {
|
||||||
|
labels.push({ name: label.name, color: `#${label.color}` });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
const taskContent = {
|
||||||
|
name: issue.title,
|
||||||
|
comment: {
|
||||||
|
content: taskComment
|
||||||
|
},
|
||||||
|
labels
|
||||||
|
};
|
||||||
|
const res = await axios_default.post(!taskId ? `${apiEndpoint}/project/${projectId}/tasklist/${tasklistId}/tasks` : `${apiEndpoint}/task/${taskId}/subtasks`, taskContent, defaultOptions);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
octokit.rest.issues.createComment({
|
||||||
|
issue_number: issue.number,
|
||||||
|
...github.context.repo,
|
||||||
|
body: `Freelo task assigned: <a href="https://app.freelo.io/task/${res.data.id}">${res.data.id}</a><br>Please do not edit or delete this comment as it is used to prevent duplication of tasks.`
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "edited": {
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const titleRes = await axios_default.post(`${apiEndpoint}/task/${currentTaskId[1]}`, {
|
||||||
|
name: issue.title
|
||||||
|
}, defaultOptions);
|
||||||
|
if (titleRes.status > 399) {
|
||||||
|
console.error(titleRes.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
const taskComment = `
|
||||||
Created by: ${freeloMention(issue.user.login)}<br>
|
Created by: ${freeloMention(issue.user.login)}<br>
|
||||||
Description: ${import_sanitize_html.default(issue.body ?? "None", sanitizeOptions)}<br>
|
Description: ${import_sanitize_html.default(issue.body ?? "None", sanitizeOptions)}<br>
|
||||||
GitHub issue: <a href="${issue.url}">#${issue.number}</a><br>
|
GitHub issue: <a href="${issue.url}">#${issue.number}</a><br>
|
||||||
Assigned to: ${issue.assignee ? `${freeloMention(issue.assignee.login)}` : "Nobody"}<br>
|
Assigned to: ${issue.assignee ? `${freeloMention(issue.assignee.login)}` : "Nobody"}<br>
|
||||||
<i>(This action was performed automatically)</i>
|
<i>(This action was performed automatically)</i>
|
||||||
`;
|
`;
|
||||||
const taskContent = {
|
const labels = [];
|
||||||
name: issue.title,
|
if (issue.labels) {
|
||||||
comment: {
|
for (const label of issue.labels) {
|
||||||
content: taskComment
|
labels.push({ name: label.name, color: `#${label.color}` });
|
||||||
}
|
|
||||||
};
|
|
||||||
const res = await axios_default.post(`${apiEndpoint}/project/${projectId}/tasklist/${tasklistId}/tasks`, taskContent, defaultOptions);
|
|
||||||
if (res.status > 399) {
|
|
||||||
console.error(res.data);
|
|
||||||
throw new Error("Got an error response from Freelo API");
|
|
||||||
}
|
}
|
||||||
octokit.rest.issues.createComment({
|
|
||||||
issue_number: issue.number,
|
|
||||||
...github.context.repo,
|
|
||||||
body: `Freelo task assigned: <a href="https://app.freelo.io/task/${res.data.id}">${res.data.id}</a><br>Please do not edit or delete this comment as it is used to prevent duplication of tasks.`
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case "edited":
|
const labelRes = await axios_default.post(`${apiEndpoint}/task-labels/add-to-task/${currentTaskId}`, { labels }, defaultOptions);
|
||||||
break;
|
if (labelRes.status > 399) {
|
||||||
case "closed": {
|
console.error(labelRes.data);
|
||||||
const comment2 = (await octokit.rest.issues.listComments({
|
throw new Error("Got an error response from Freelo API");
|
||||||
...github.context.repo,
|
|
||||||
issue_number: issue.number,
|
|
||||||
mediaType: {
|
|
||||||
format: "html"
|
|
||||||
}
|
|
||||||
})).data.filter((i) => i.user?.type === "Bot" && i.user.login === "github-actions[bot]");
|
|
||||||
if (comment2.length === 0)
|
|
||||||
break;
|
|
||||||
const taskId2 = /https:\/\/app.freelo.io\/task\/(\d+)/.exec(comment2[0].body_html ?? "");
|
|
||||||
if (!taskId2 || taskId2.length === 0) {
|
|
||||||
console.log("Comment found, but no Freelo task ID identified");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const res = await axios_default.post(`${apiEndpoint}/task/${taskId2[1]}/finish`, null, defaultOptions);
|
|
||||||
if (res.status > 399) {
|
|
||||||
console.error(res.data);
|
|
||||||
throw new Error("Got an error response from Freelo API");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case "reopened": {
|
const bodyRes = await axios_default.post(`${apiEndpoint}/task/${currentTaskId[1]}/description`, {
|
||||||
const comment2 = (await octokit.rest.issues.listComments({
|
comment: { content: taskComment },
|
||||||
...github.context.repo,
|
labels
|
||||||
issue_number: issue.number,
|
}, defaultOptions);
|
||||||
mediaType: {
|
if (bodyRes.status > 399) {
|
||||||
format: "html"
|
console.error(bodyRes.data);
|
||||||
}
|
throw new Error("Got an error response from Freelo API");
|
||||||
})).data.filter((i) => i.user?.type === "Bot" && i.user.login === "github-actions[bot]");
|
|
||||||
if (comment2.length === 0)
|
|
||||||
break;
|
|
||||||
const taskId2 = /https:\/\/app.freelo.io\/task\/(\d+)/.exec(comment2[0].body_html ?? "");
|
|
||||||
if (!taskId2 || taskId2.length === 0) {
|
|
||||||
console.log("Comment found, but no Freelo task ID identified");
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
const res = await axios_default.post(`${apiEndpoint}/task/${taskId2[1]}/activate`, null, defaultOptions);
|
|
||||||
if (res.status > 399) {
|
|
||||||
console.error(res.data);
|
|
||||||
throw new Error("Got an error response from Freelo API");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case "assigned":
|
break;
|
||||||
break;
|
|
||||||
case "unassigned":
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
throw new Error("Unknown action passed");
|
|
||||||
}
|
}
|
||||||
|
case "closed": {
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("No Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const res = await axios_default.post(`${apiEndpoint}/task/${currentTaskId[1]}/finish`, null, defaultOptions);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "reopened": {
|
||||||
|
const currentTaskid = await freeloId(issue.number);
|
||||||
|
if (!currentTaskid || currentTaskid.length === 0) {
|
||||||
|
console.log("No Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const res = await axios_default.post(`${apiEndpoint}/task/${currentTaskid[1]}/activate`, null, defaultOptions);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "assigned": {
|
||||||
|
if (!github.context.payload.assignee || !userPairing[github.context.payload.assignee.login])
|
||||||
|
break;
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const res = await axios_default.post(`${apiEndpoint}/task/${currentTaskId[1]}`, {
|
||||||
|
worker: userPairing[github.context.payload.assignee.login]
|
||||||
|
}, defaultOptions);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "unassigned": {
|
||||||
|
if (!github.context.payload.assignee || !userPairing[github.context.payload.assignee.login])
|
||||||
|
break;
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const checkAssignee = await axios_default.get(`${apiEndpoint}/task/${currentTaskId}`, defaultOptions);
|
||||||
|
if (checkAssignee.status > 399) {
|
||||||
|
console.error(checkAssignee.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
if (!checkAssignee.data.worker || checkAssignee.data.worker.id !== userPairing[github.context.payload.assignee.login]) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const res = await axios_default.post(`${apiEndpoint}/task/${currentTaskId[1]}`, {
|
||||||
|
worker: null
|
||||||
|
}, defaultOptions);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
throw new Error("Unknown action passed");
|
||||||
|
}
|
||||||
|
} else if (comment && issue) {
|
||||||
|
switch (action) {
|
||||||
|
case "created": {
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const taskComment = `
|
||||||
|
Comment <a href="${comment.url}">${comment.id}</a> by: ${freeloMention(comment.user.login)}<br>
|
||||||
|
${import_sanitize_html.default(comment.body, sanitizeOptions)}<br>
|
||||||
|
GitHub issue: <a href="${issue.url}">#${issue.number}</a><br>
|
||||||
|
<i>(This action was performed automatically)</i>
|
||||||
|
`;
|
||||||
|
const res = await axios_default.post(`${apiEndpoint}/task/${currentTaskId}/comments`, {
|
||||||
|
content: taskComment
|
||||||
|
});
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
console.log(`Created comment ${res.data.id}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "deleted": {
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const getTaskComments = await axios_default.get(`${apiEndpoint}/task/${currentTaskId}`, defaultOptions);
|
||||||
|
if (getTaskComments.status > 399) {
|
||||||
|
console.error(getTaskComments.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
const findComment = getTaskComments.data.comments.filter((c) => />(\d+)</gm.test(c.content));
|
||||||
|
if (findComment.length === 0) {
|
||||||
|
console.log("Comment found, but no GitHub comment ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const res = await axios_default.delete(`${apiEndpoint}/comment/${findComment[0].id}`);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
console.log(`Deleted comment ${findComment[0].id}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "edited": {
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const getTaskComments = await axios_default.get(`${apiEndpoint}/task/${currentTaskId}`, defaultOptions);
|
||||||
|
if (getTaskComments.status > 399) {
|
||||||
|
console.error(getTaskComments.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
const findComment = getTaskComments.data.comments.filter((c) => />(\d+)</gm.test(c.content));
|
||||||
|
if (findComment.length === 0) {
|
||||||
|
console.log("Comment found, but no GitHub comment ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const taskComment = `
|
||||||
|
Comment <a href="${comment.url}">${comment.id}</a> by: ${freeloMention(comment.user.login)}<br>
|
||||||
|
${import_sanitize_html.default(comment.body, sanitizeOptions)}<br>
|
||||||
|
GitHub issue: <a href="${issue.url}">#${issue.number}</a><br>
|
||||||
|
<i>(This action was performed automatically)</i>
|
||||||
|
`;
|
||||||
|
const res = await axios_default.post(`${apiEndpoint}/comment/${findComment[0].id}`, {
|
||||||
|
content: taskComment
|
||||||
|
});
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
console.log(`Edited comment ${findComment[0].id}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (comment) {
|
|
||||||
} else {
|
} else {
|
||||||
throw new Error("You are running this action through an unsupported trigger");
|
console.error("You are running this through an unsupported trigger!");
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
core.setFailed(error?.message ?? "Unknown error");
|
core.setFailed(error?.message ?? "Unknown error");
|
||||||
|
|
469
src/index.ts
469
src/index.ts
|
@ -1,9 +1,9 @@
|
||||||
|
import { readFile } from "node:fs/promises";
|
||||||
import { getInput, setFailed } from "@actions/core";
|
import { getInput, setFailed } from "@actions/core";
|
||||||
import { context, getOctokit } from "@actions/github";
|
import { context, getOctokit } from "@actions/github";
|
||||||
import axios from "axios";
|
import axios from "axios";
|
||||||
import sanitize from "sanitize-html";
|
import sanitize from "sanitize-html";
|
||||||
import type { NewTask } from "./freelo";
|
import type { Label, NewTask } from "./freelo";
|
||||||
import { readFile } from "node:fs/promises";
|
|
||||||
|
|
||||||
// user input
|
// user input
|
||||||
const email = getInput("email");
|
const email = getInput("email");
|
||||||
|
@ -60,9 +60,29 @@ function freeloMention(username: string): string {
|
||||||
: `<a href="https://github.com/${username}">${username}</a>`;
|
: `<a href="https://github.com/${username}">${username}</a>`;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
async function freeloId(issue_number: number): Promise<string | undefined> {
|
||||||
|
const comment = (
|
||||||
|
await octokit.rest.issues.listComments({
|
||||||
|
...context.repo,
|
||||||
|
issue_number: issue_number,
|
||||||
|
mediaType: {
|
||||||
|
format: "html",
|
||||||
|
},
|
||||||
|
})
|
||||||
|
).data.filter(
|
||||||
|
(i) => i.user?.type === "Bot" && i.user.login === "github-actions[bot]",
|
||||||
|
);
|
||||||
|
if (comment.length === 0) return undefined; // not a Freelo task, skip
|
||||||
|
|
||||||
|
// Finish task in Freelo
|
||||||
|
return /https:\/\/app.freelo.io\/task\/(\d+)/.exec(
|
||||||
|
comment[0].body_html ?? "",
|
||||||
|
)?.[1];
|
||||||
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
if (!action) {
|
if (!action) {
|
||||||
// TODO: Is run manually, check all issues
|
// TODO: Is run manually, check all issues
|
||||||
throw new Error("No action was passed");
|
throw new Error("No action was passed");
|
||||||
}
|
}
|
||||||
if (!email || !apiKey || !projectId) {
|
if (!email || !apiKey || !projectId) {
|
||||||
|
@ -70,22 +90,85 @@ try {
|
||||||
"You are missing a required parameter. Check the documentation for details.",
|
"You are missing a required parameter. Check the documentation for details.",
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
if (issue) {
|
if (!comment && issue) {
|
||||||
// is a created/edited/closed etc. issue
|
// is a created/edited/closed etc. issue
|
||||||
if (issue.pull_request) {
|
|
||||||
throw new Error("Pull requests are not yet supported");
|
|
||||||
}
|
|
||||||
|
|
||||||
// depending on whether taskId or tasklistId is set, do something
|
// depending on whether taskId or tasklistId is set, do something
|
||||||
if (!tasklistId && !taskId) {
|
if (!tasklistId && !taskId) {
|
||||||
throw new Error("Either task-id or tasklist-id needs to be set!");
|
throw new Error("Either task-id or tasklist-id needs to be set!");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tasklistId) {
|
// Use a task inside of a tasklist
|
||||||
switch (action) {
|
switch (action) {
|
||||||
case "opened": {
|
case "opened": {
|
||||||
// New issue has been created, create a task in tasklist
|
// New issue has been created, create a task in tasklist
|
||||||
const taskComment = `
|
const taskComment = `
|
||||||
|
Created by: ${freeloMention(issue.user.login)}<br>
|
||||||
|
Description: ${sanitize(issue.body ?? "None", sanitizeOptions)}<br>
|
||||||
|
GitHub issue: <a href="${issue.pull_request ? issue.pull_request.url : issue.url}">#${issue.number}</a><br>
|
||||||
|
Assigned to: ${issue.assignee ? `${freeloMention(issue.assignee.login)}` : "Nobody"}<br>
|
||||||
|
${issue.pull_request ? "<b>This is a pull request<b><br>" : ""}
|
||||||
|
<i>(This action was performed automatically)</i>
|
||||||
|
`;
|
||||||
|
|
||||||
|
const labels: Label[] = [];
|
||||||
|
if (issue.labels) {
|
||||||
|
for (const label of issue.labels) {
|
||||||
|
labels.push({ name: label.name, color: `#${label.color}` });
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
const taskContent: NewTask = {
|
||||||
|
name: issue.title,
|
||||||
|
comment: {
|
||||||
|
content: taskComment,
|
||||||
|
},
|
||||||
|
labels,
|
||||||
|
};
|
||||||
|
|
||||||
|
const res = await axios.post(
|
||||||
|
!taskId
|
||||||
|
? `${apiEndpoint}/project/${projectId}/tasklist/${tasklistId}/tasks`
|
||||||
|
: `${apiEndpoint}/task/${taskId}/subtasks`,
|
||||||
|
taskContent,
|
||||||
|
defaultOptions,
|
||||||
|
);
|
||||||
|
|
||||||
|
// handle potential error response
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
|
||||||
|
// create an issue comment so we can track if the task has been already created
|
||||||
|
octokit.rest.issues.createComment({
|
||||||
|
issue_number: issue.number,
|
||||||
|
...context.repo,
|
||||||
|
body: `Freelo task assigned: <a href="https://app.freelo.io/task/${res.data.id}">${res.data.id}</a><br>Please do not edit or delete this comment as it is used to prevent duplication of tasks.`,
|
||||||
|
});
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case "edited": {
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Edit task title
|
||||||
|
const titleRes = await axios.post(
|
||||||
|
`${apiEndpoint}/task/${currentTaskId[1]}`,
|
||||||
|
{
|
||||||
|
name: issue.title,
|
||||||
|
},
|
||||||
|
defaultOptions,
|
||||||
|
);
|
||||||
|
if (titleRes.status > 399) {
|
||||||
|
console.error(titleRes.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
const taskComment = `
|
||||||
Created by: ${freeloMention(issue.user.login)}<br>
|
Created by: ${freeloMention(issue.user.login)}<br>
|
||||||
Description: ${sanitize(issue.body ?? "None", sanitizeOptions)}<br>
|
Description: ${sanitize(issue.body ?? "None", sanitizeOptions)}<br>
|
||||||
GitHub issue: <a href="${issue.url}">#${issue.number}</a><br>
|
GitHub issue: <a href="${issue.url}">#${issue.number}</a><br>
|
||||||
|
@ -93,125 +176,271 @@ try {
|
||||||
<i>(This action was performed automatically)</i>
|
<i>(This action was performed automatically)</i>
|
||||||
`;
|
`;
|
||||||
|
|
||||||
const taskContent: NewTask = {
|
const labels: Label[] = [];
|
||||||
name: issue.title,
|
if (issue.labels) {
|
||||||
comment: {
|
for (const label of issue.labels) {
|
||||||
content: taskComment,
|
labels.push({ name: label.name, color: `#${label.color}` });
|
||||||
},
|
|
||||||
};
|
|
||||||
|
|
||||||
const res = await axios.post(
|
|
||||||
`${apiEndpoint}/project/${projectId}/tasklist/${tasklistId}/tasks`,
|
|
||||||
taskContent,
|
|
||||||
defaultOptions,
|
|
||||||
);
|
|
||||||
|
|
||||||
// handle potential error response
|
|
||||||
if (res.status > 399) {
|
|
||||||
console.error(res.data);
|
|
||||||
throw new Error("Got an error response from Freelo API");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// create an issue comment so we can track if the task has been already created
|
|
||||||
octokit.rest.issues.createComment({
|
|
||||||
issue_number: issue.number,
|
|
||||||
...context.repo,
|
|
||||||
body: `Freelo task assigned: <a href="https://app.freelo.io/task/${res.data.id}">${res.data.id}</a><br>Please do not edit or delete this comment as it is used to prevent duplication of tasks.`,
|
|
||||||
});
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
case "edited":
|
// Edit task labels
|
||||||
break;
|
const labelRes = await axios.post(
|
||||||
case "closed": {
|
`${apiEndpoint}/task-labels/add-to-task/${currentTaskId}`,
|
||||||
// Get comments and find the related Freelo task ID
|
{ labels },
|
||||||
const comment = (
|
defaultOptions,
|
||||||
await octokit.rest.issues.listComments({
|
);
|
||||||
...context.repo,
|
if (labelRes.status > 399) {
|
||||||
issue_number: issue.number,
|
console.error(labelRes.data);
|
||||||
mediaType: {
|
throw new Error("Got an error response from Freelo API");
|
||||||
format: "html",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
).data.filter(
|
|
||||||
(i) =>
|
|
||||||
i.user?.type === "Bot" && i.user.login === "github-actions[bot]",
|
|
||||||
);
|
|
||||||
if (comment.length === 0) break; // not a Freelo task, skip
|
|
||||||
|
|
||||||
// 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]}/finish`,
|
|
||||||
null,
|
|
||||||
defaultOptions,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (res.status > 399) {
|
|
||||||
console.error(res.data);
|
|
||||||
throw new Error("Got an error response from Freelo API");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case "reopened": {
|
|
||||||
// Get comments and find the related Freelo task ID
|
|
||||||
const comment = (
|
|
||||||
await octokit.rest.issues.listComments({
|
|
||||||
...context.repo,
|
|
||||||
issue_number: issue.number,
|
|
||||||
mediaType: {
|
|
||||||
format: "html",
|
|
||||||
},
|
|
||||||
})
|
|
||||||
).data.filter(
|
|
||||||
(i) =>
|
|
||||||
i.user?.type === "Bot" && i.user.login === "github-actions[bot]",
|
|
||||||
);
|
|
||||||
if (comment.length === 0) break; // not a Freelo task, skip
|
|
||||||
|
|
||||||
// Finish task in Freelo
|
// Edit task body
|
||||||
const taskId = /https:\/\/app.freelo.io\/task\/(\d+)/.exec(
|
const bodyRes = await axios.post(
|
||||||
comment[0].body_html ?? "",
|
`${apiEndpoint}/task/${currentTaskId[1]}/description`,
|
||||||
);
|
{
|
||||||
if (!taskId || taskId.length === 0) {
|
comment: { content: taskComment },
|
||||||
console.log("Comment found, but no Freelo task ID identified");
|
labels,
|
||||||
break;
|
},
|
||||||
}
|
defaultOptions,
|
||||||
|
);
|
||||||
// Reactivate
|
if (bodyRes.status > 399) {
|
||||||
const res = await axios.post(
|
console.error(bodyRes.data);
|
||||||
`${apiEndpoint}/task/${taskId[1]}/activate`,
|
throw new Error("Got an error response from Freelo API");
|
||||||
null,
|
|
||||||
defaultOptions,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (res.status > 399) {
|
|
||||||
console.error(res.data);
|
|
||||||
throw new Error("Got an error response from Freelo API");
|
|
||||||
}
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
case "assigned":
|
|
||||||
break;
|
|
||||||
case "unassigned":
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
break;
|
||||||
throw new Error("Unknown action passed");
|
|
||||||
}
|
}
|
||||||
|
case "closed": {
|
||||||
|
// Issue closed, finish task
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("No Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const res = await axios.post(
|
||||||
|
`${apiEndpoint}/task/${currentTaskId[1]}/finish`,
|
||||||
|
null,
|
||||||
|
defaultOptions,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "reopened": {
|
||||||
|
// Issue re-opened, activate task
|
||||||
|
const currentTaskid = await freeloId(issue.number);
|
||||||
|
if (!currentTaskid || currentTaskid.length === 0) {
|
||||||
|
console.log("No Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Reactivate
|
||||||
|
const res = await axios.post(
|
||||||
|
`${apiEndpoint}/task/${currentTaskid[1]}/activate`,
|
||||||
|
null,
|
||||||
|
defaultOptions,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "assigned": {
|
||||||
|
// New assignee, check if mapping exists and update in Freelo
|
||||||
|
if (
|
||||||
|
!context.payload.assignee ||
|
||||||
|
!userPairing[context.payload.assignee.login]
|
||||||
|
)
|
||||||
|
break;
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await axios.post(
|
||||||
|
`${apiEndpoint}/task/${currentTaskId[1]}`,
|
||||||
|
{
|
||||||
|
worker: userPairing[context.payload.assignee.login],
|
||||||
|
},
|
||||||
|
defaultOptions,
|
||||||
|
);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "unassigned": {
|
||||||
|
// Unassigned, check if user has Freelo pairing, is currently assigned to the Freelo task and unassign them
|
||||||
|
if (
|
||||||
|
!context.payload.assignee ||
|
||||||
|
!userPairing[context.payload.assignee.login]
|
||||||
|
)
|
||||||
|
break;
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const checkAssignee = await axios.get(
|
||||||
|
`${apiEndpoint}/task/${currentTaskId}`,
|
||||||
|
defaultOptions,
|
||||||
|
);
|
||||||
|
if (checkAssignee.status > 399) {
|
||||||
|
console.error(checkAssignee.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
|
||||||
|
if (
|
||||||
|
!checkAssignee.data.worker ||
|
||||||
|
checkAssignee.data.worker.id !==
|
||||||
|
userPairing[context.payload.assignee.login]
|
||||||
|
) {
|
||||||
|
// if the current user is not assigned, ignore
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const res = await axios.post(
|
||||||
|
`${apiEndpoint}/task/${currentTaskId[1]}`,
|
||||||
|
{
|
||||||
|
worker: null,
|
||||||
|
},
|
||||||
|
defaultOptions,
|
||||||
|
);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new Error("Unknown action passed");
|
||||||
}
|
}
|
||||||
} else if (comment) {
|
} else if (comment && issue) {
|
||||||
// should be an issue comment
|
// should be an issue comment
|
||||||
|
switch (action) {
|
||||||
|
case "created": {
|
||||||
|
// New comment, add to Freelo task
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const taskComment = `
|
||||||
|
Comment <a href="${comment.url}">${comment.id}</a> by: ${freeloMention(comment.user.login)}<br>
|
||||||
|
${sanitize(comment.body, sanitizeOptions)}<br>
|
||||||
|
GitHub issue: <a href="${issue.url}">#${issue.number}</a><br>
|
||||||
|
<i>(This action was performed automatically)</i>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Create comment
|
||||||
|
const res = await axios.post(
|
||||||
|
`${apiEndpoint}/task/${currentTaskId}/comments`,
|
||||||
|
{
|
||||||
|
content: taskComment,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
console.log(`Created comment ${res.data.id}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "deleted": {
|
||||||
|
// Find comment, delete it
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTaskComments = await axios.get(
|
||||||
|
`${apiEndpoint}/task/${currentTaskId}`,
|
||||||
|
defaultOptions,
|
||||||
|
);
|
||||||
|
if (getTaskComments.status > 399) {
|
||||||
|
console.error(getTaskComments.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
|
||||||
|
const findComment = (
|
||||||
|
getTaskComments.data.comments as { id: number; content: string }[]
|
||||||
|
).filter((c) => />(\d+)</gm.test(c.content));
|
||||||
|
if (findComment.length === 0) {
|
||||||
|
console.log("Comment found, but no GitHub comment ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
const res = await axios.delete(
|
||||||
|
`${apiEndpoint}/comment/${findComment[0].id}`,
|
||||||
|
);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
console.log(`Deleted comment ${findComment[0].id}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
case "edited": {
|
||||||
|
// Find comment, edit it
|
||||||
|
const currentTaskId = await freeloId(issue.number);
|
||||||
|
if (!currentTaskId || currentTaskId.length === 0) {
|
||||||
|
console.log("Comment found, but no Freelo task ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const getTaskComments = await axios.get(
|
||||||
|
`${apiEndpoint}/task/${currentTaskId}`,
|
||||||
|
defaultOptions,
|
||||||
|
);
|
||||||
|
if (getTaskComments.status > 399) {
|
||||||
|
console.error(getTaskComments.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
|
||||||
|
const findComment = (
|
||||||
|
getTaskComments.data.comments as { id: number; content: string }[]
|
||||||
|
).filter((c) => />(\d+)</gm.test(c.content));
|
||||||
|
if (findComment.length === 0) {
|
||||||
|
console.log("Comment found, but no GitHub comment ID identified");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
const taskComment = `
|
||||||
|
Comment <a href="${comment.url}">${comment.id}</a> by: ${freeloMention(comment.user.login)}<br>
|
||||||
|
${sanitize(comment.body, sanitizeOptions)}<br>
|
||||||
|
GitHub issue: <a href="${issue.url}">#${issue.number}</a><br>
|
||||||
|
<i>(This action was performed automatically)</i>
|
||||||
|
`;
|
||||||
|
|
||||||
|
// Create comment
|
||||||
|
const res = await axios.post(
|
||||||
|
`${apiEndpoint}/comment/${findComment[0].id}`,
|
||||||
|
{
|
||||||
|
content: taskComment,
|
||||||
|
},
|
||||||
|
);
|
||||||
|
if (res.status > 399) {
|
||||||
|
console.error(res.data);
|
||||||
|
throw new Error("Got an error response from Freelo API");
|
||||||
|
}
|
||||||
|
console.log(`Edited comment ${findComment[0].id}`);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
throw new Error(
|
console.error("You are running this through an unsupported trigger!");
|
||||||
"You are running this action through an unsupported trigger",
|
|
||||||
);
|
|
||||||
}
|
}
|
||||||
} catch (error) {
|
} catch (error) {
|
||||||
setFailed((error as Error)?.message ?? "Unknown error");
|
setFailed((error as Error)?.message ?? "Unknown error");
|
||||||
|
|
Loading…
Reference in a new issue