mirror of
https://gitea.com/Lydanne/issues-helper.git
synced 2025-08-21 19:25:46 +08:00
453 lines
12 KiB
JavaScript
453 lines
12 KiB
JavaScript
require('dotenv').config();
|
||
const core = require("@actions/core");
|
||
const github = require("@actions/github");
|
||
const { Octokit } = require('@octokit/rest');
|
||
|
||
// **************************************************************************
|
||
const ALLREACTIONS = [
|
||
"+1",
|
||
"-1",
|
||
"laugh",
|
||
"confused",
|
||
"heart",
|
||
"hooray",
|
||
"rocket",
|
||
"eyes",
|
||
];
|
||
|
||
const {
|
||
doQueryIssues
|
||
} = require('./public.js');
|
||
|
||
const {
|
||
dealStringToArr,
|
||
dealRandomAssignees,
|
||
testDuplicate,
|
||
} = require('./util.js');
|
||
|
||
// **************************************************************************
|
||
const token = core.getInput('token');
|
||
const octokit = new Octokit({ auth: `token ${token}` });
|
||
const context = github.context;
|
||
|
||
const contents = core.getInput("contents");
|
||
|
||
const randomTo = core.getInput("random-to");
|
||
|
||
// **************************************************************************
|
||
async function doAddAssignees (owner, repo, issueNumber, assignees) {
|
||
const arr = dealRandomAssignees(assignees, randomTo);
|
||
await octokit.issues.addAssignees({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
assignees: arr
|
||
});
|
||
core.info(`Actions: [add-assignees][${arr}] success!`);
|
||
};
|
||
|
||
async function doAddLabels (owner, repo, issueNumber, labels) {
|
||
await octokit.issues.addLabels({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
labels: dealStringToArr(labels)
|
||
});
|
||
core.info(`Actions: [add-labels][${labels}] success!`);
|
||
};
|
||
|
||
async function doCloseIssue (owner, repo, issueNumber) {
|
||
await octokit.issues.update({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
state: 'closed'
|
||
});
|
||
core.info(`Actions: [close-issue][${issueNumber}] success!`);
|
||
};
|
||
|
||
async function doCreateComment (owner, repo, issueNumber, body) {
|
||
const { data } = await octokit.issues.createComment({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
body
|
||
});
|
||
core.info(`Actions: [create-comment][${body}] success!`);
|
||
core.setOutput("comment-id", data.id);
|
||
|
||
if (contents) {
|
||
await doCreateCommentContent(owner, repo, data.id, dealStringToArr(contents));
|
||
}
|
||
};
|
||
|
||
async function doCreateCommentContent(owner, repo, commentId, contents) {
|
||
if (contents.length) {
|
||
contents.forEach(async item => {
|
||
if (testContent(item)) {
|
||
await octokit.reactions.createForIssueComment({
|
||
owner,
|
||
repo,
|
||
comment_id: commentId,
|
||
content: item
|
||
});
|
||
core.info(`Actions: [create-reactions][${item}] success!`);
|
||
}
|
||
})
|
||
}
|
||
};
|
||
|
||
async function doCreateIssue (owner, repo, title, body, labels, assignees) {
|
||
let params = {
|
||
owner,
|
||
repo,
|
||
title,
|
||
body,
|
||
labels: dealStringToArr(labels),
|
||
assignees: dealRandomAssignees(assignees, randomTo),
|
||
};
|
||
|
||
const { data } = await octokit.issues.create(params);
|
||
core.info(`Actions: [create-issue][${title}] success!`);
|
||
core.setOutput("issue-number", data.number);
|
||
|
||
if (contents) {
|
||
await doCreateIssueContent(owner, repo, data.number, dealStringToArr(contents));
|
||
}
|
||
};
|
||
|
||
async function doCreateIssueContent(owner, repo, issueNumber, contents) {
|
||
if (contents.length) {
|
||
contents.forEach(async item => {
|
||
if (testContent(item)) {
|
||
await octokit.reactions.createForIssue({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
content: item
|
||
});
|
||
core.info(`Actions: [create-reactions][${item}] success!`);
|
||
}
|
||
})
|
||
}
|
||
};
|
||
|
||
async function doDeleteComment (owner, repo, commentId) {
|
||
await octokit.issues.deleteComment({
|
||
owner,
|
||
repo,
|
||
comment_id: commentId
|
||
});
|
||
core.info(`Actions: [delete-comment][${commentId}] success!`);
|
||
};
|
||
|
||
async function doLockIssue (owner, repo, issueNumber) {
|
||
await octokit.issues.lock({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
});
|
||
core.info(`Actions: [lock-issue][${issueNumber}] success!`);
|
||
};
|
||
|
||
async function doMarkDuplicate (owner, repo, labels) {
|
||
if (context.eventName != 'issue_comment') {
|
||
core.info(`This actions only support on 'issue_comment'!`);
|
||
return false;
|
||
}
|
||
if (context.payload.action != 'created') {
|
||
core.info(`This actions only support on 'issue_comment' created!`);
|
||
return false;
|
||
}
|
||
|
||
const duplicateCommand = core.getInput("duplicate-command");
|
||
const duplicateLabels = core.getInput("duplicate-labels");
|
||
const removeLables = core.getInput("remove-labels");
|
||
const closeIssue = core.getInput("close-issue");
|
||
|
||
const commentId = context.payload.comment.id;
|
||
const commentBody = context.payload.comment.body;
|
||
const issueNumber = context.payload.issue.number;
|
||
|
||
const ifCommandInput = !!duplicateCommand;
|
||
|
||
if (!commentBody.includes('?') && ((ifCommandInput && commentBody.startsWith(duplicateCommand) && commentBody.split(' ')[0] == duplicateCommand) || testDuplicate(commentBody))) {
|
||
if (ifCommandInput) {
|
||
const nextBody = commentBody.replace(duplicateCommand, 'Duplicate of');
|
||
await doUpdateComment(owner, repo, commentId, nextBody, 'replace', true);
|
||
} else if (contents) {
|
||
await doCreateCommentContent(owner, repo, commentId, dealStringToArr(contents));
|
||
}
|
||
|
||
const issue = await octokit.issues.get({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber
|
||
});
|
||
let newLabels = [];
|
||
if (issue.data.labels.length > 0) {
|
||
newLabels = issue.data.labels.map(({ name }) => name).filter(name => !dealStringToArr(removeLables).includes(name));
|
||
}
|
||
if (duplicateLabels) {
|
||
newLabels = [...newLabels, ...dealStringToArr(duplicateLabels)];
|
||
}
|
||
if (labels) {
|
||
newLabels = dealStringToArr(labels);
|
||
}
|
||
if (newLabels.length > 0) {
|
||
await doSetLabels(owner, repo, issueNumber, newLabels.toString());
|
||
core.info(`Actions: [mark-duplicate-labels][${newLabels}] success!`);
|
||
}
|
||
|
||
if (closeIssue == 'true') {
|
||
await doCloseIssue(owner, repo, issueNumber);
|
||
}
|
||
} else {
|
||
core.info(`This comment body should start whith 'duplicate-command' or 'Duplicate of' and not include '?'`);
|
||
}
|
||
};
|
||
|
||
async function doOpenIssue (owner, repo, issueNumber) {
|
||
await octokit.issues.update({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
state: 'open'
|
||
});
|
||
core.info(`Actions: [open-issue][${issueNumber}] success!`);
|
||
};
|
||
|
||
async function doRemoveAssignees (owner, repo, issueNumber, assignees) {
|
||
await octokit.issues.removeAssignees({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
assignees: dealStringToArr(assignees)
|
||
});
|
||
core.info(`Actions: [remove-assignees][${assignees}] success!`);
|
||
};
|
||
|
||
async function doRemoveLabels (owner, repo, issueNumber, labels) {
|
||
const dealLabels = dealStringToArr(labels);
|
||
for (label of dealLabels) {
|
||
await octokit.issues.removeLabel({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
name: label,
|
||
});
|
||
core.info(`Actions: [remove-labels-foreach][${label}] success!`);
|
||
}
|
||
core.info(`Actions: [remove-labels][${labels}] success!`);
|
||
};
|
||
|
||
async function doSetLabels (owner, repo, issueNumber, labels) {
|
||
// 概率性出现问题:https://github.com/octokit/rest.js/issues/1982,规避 setLabels
|
||
if (labels) {
|
||
// await octokit.issues.setLabels({
|
||
// owner,
|
||
// repo,
|
||
// issue_number: issueNumber,
|
||
// labels: dealStringToArr(labels)
|
||
// });
|
||
const issue = await octokit.issues.get({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber
|
||
});
|
||
const baseLabels = issue.data.labels.map(({ name }) => name);
|
||
const removeLabels = baseLabels.filter(name => !dealStringToArr(labels).includes(name));
|
||
const addLabels = dealStringToArr(labels).filter(name => !baseLabels.includes(name));
|
||
|
||
if (removeLabels.length > 0) {
|
||
await doRemoveLabels(owner, repo, issueNumber, removeLabels.toString());
|
||
core.info(`Actions: [set-labels-remove][${removeLabels}] success!`);
|
||
}
|
||
|
||
if (addLabels.length > 0) {
|
||
await doAddLabels(owner, repo, issueNumber, addLabels.toString());
|
||
core.info(`Actions: [set-labels-add][${addLabels}] success!`);
|
||
}
|
||
|
||
core.info(`Actions: [set-labels][${labels}] success!`);
|
||
}
|
||
};
|
||
|
||
async function doUnlockIssue (owner, repo, issueNumber) {
|
||
await octokit.issues.unlock({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
});
|
||
core.info(`Actions: [unlock-issue][${issueNumber}] success!`);
|
||
};
|
||
|
||
async function doUpdateComment (
|
||
owner,
|
||
repo,
|
||
commentId,
|
||
body,
|
||
updateMode,
|
||
ifUpdateBody,
|
||
) {
|
||
const comment = await octokit.issues.getComment({
|
||
owner,
|
||
repo,
|
||
comment_id: commentId
|
||
})
|
||
const comment_body = comment.data.body;
|
||
|
||
let params = {
|
||
owner,
|
||
repo,
|
||
comment_id: commentId
|
||
};
|
||
|
||
if (core.getInput("body") || ifUpdateBody) {
|
||
if (updateMode === 'append') {
|
||
params.body = `${comment_body}\n${body}`;
|
||
} else {
|
||
params.body = body;
|
||
}
|
||
|
||
await octokit.issues.updateComment(params);
|
||
core.info(`Actions: [update-comment][${commentId}] success!`);
|
||
}
|
||
|
||
if (contents) {
|
||
await doCreateCommentContent(owner, repo, commentId, dealStringToArr(contents));
|
||
}
|
||
};
|
||
|
||
async function doUpdateIssue (
|
||
owner,
|
||
repo,
|
||
issueNumber,
|
||
state,
|
||
title,
|
||
body,
|
||
updateMode,
|
||
assignees,
|
||
labels
|
||
) {
|
||
const issue = await octokit.issues.get({
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber
|
||
})
|
||
const issue_body = issue.data.body;
|
||
const issue_title = issue.data.title;
|
||
|
||
let issue_labels = [];
|
||
if (issue.data.labels.length > 0) {
|
||
issue.data.labels.forEach(it =>{
|
||
issue_labels.push(it.name);
|
||
});
|
||
}
|
||
|
||
let issue_assignees = [];
|
||
if (issue.data.assignees.length > 0) {
|
||
issue.data.assignees.forEach(it =>{
|
||
issue_assignees.push(it.login);
|
||
});
|
||
}
|
||
|
||
let params = {
|
||
owner,
|
||
repo,
|
||
issue_number: issueNumber,
|
||
state
|
||
};
|
||
|
||
params.title = core.getInput("title") ? title : issue_title;
|
||
|
||
let next_body;
|
||
if (core.getInput("body")) {
|
||
if (updateMode === 'append') {
|
||
next_body = `${issue_body}\n${body}`;
|
||
} else {
|
||
next_body = body;
|
||
}
|
||
} else {
|
||
next_body = issue_body;
|
||
}
|
||
params.body = next_body;
|
||
|
||
params.labels = labels ? dealStringToArr(labels) : issue_labels;
|
||
params.assignees = assignees ? dealStringToArr(assignees) : issue_assignees;
|
||
|
||
await octokit.issues.update(params);
|
||
core.info(`Actions: [update-issue][${issueNumber}] success!`);
|
||
|
||
if (contents) {
|
||
await doCreateIssueContent(owner, repo, issueNumber, contents);
|
||
}
|
||
};
|
||
|
||
async function doWelcome (owner, repo, assignees, labels, body) {
|
||
const context = github.context;
|
||
const isIssue = !!context.payload.issue;
|
||
const issueContents = core.getInput("issue-contents");
|
||
if (!isIssue) {
|
||
core.setFailed("The event that triggered this action must be a issue. Error!");
|
||
} else {
|
||
const auth = context.payload.sender.login;
|
||
core.info(`Actions: [welcome: auth=][${auth}]`);
|
||
const issueNumber = context.issue.number;
|
||
const issues = await doQueryIssues(owner, repo, false, 'all', auth);
|
||
if (issues.length == 0 || (issues.length == 1 && issues[0].number == issueNumber)) {
|
||
if (core.getInput("body")) {
|
||
await doCreateComment(owner, repo, issueNumber, body);
|
||
} else {
|
||
core.info(`Actions: [welcome] no body!`);
|
||
}
|
||
|
||
if (assignees) {
|
||
await doAddAssignees(owner, repo, issueNumber, assignees);
|
||
}
|
||
|
||
if (labels) {
|
||
await doAddLabels(owner, repo, issueNumber, labels);
|
||
}
|
||
|
||
if (issueContents) {
|
||
await doCreateIssueContent(owner, repo, issueNumber, dealStringToArr(issueContents));
|
||
}
|
||
} else {
|
||
core.info(`Actions: [welcome][${auth}] is not first time!`);
|
||
}
|
||
}
|
||
};
|
||
|
||
// **************************************************************************
|
||
function testContent(con) {
|
||
if (ALLREACTIONS.includes(con)) {
|
||
return true;
|
||
} else {
|
||
core.setFailed("This actions not supported!");
|
||
return false;
|
||
}
|
||
};
|
||
|
||
// **************************************************************************
|
||
module.exports = {
|
||
doAddAssignees,
|
||
doAddLabels,
|
||
doCloseIssue,
|
||
doCreateComment,
|
||
doCreateCommentContent,
|
||
doCreateIssue,
|
||
doCreateIssueContent,
|
||
doDeleteComment,
|
||
doMarkDuplicate,
|
||
doLockIssue,
|
||
doOpenIssue,
|
||
doRemoveAssignees,
|
||
doRemoveLabels,
|
||
doSetLabels,
|
||
doUnlockIssue,
|
||
doUpdateComment,
|
||
doUpdateIssue,
|
||
doWelcome,
|
||
};
|