diff --git a/.github/actions/triage/action.yml b/.github/actions/triage/action.yml index d8a12b610..ebe102493 100644 --- a/.github/actions/triage/action.yml +++ b/.github/actions/triage/action.yml @@ -17,9 +17,9 @@ inputs: reproduction-link-section: description: 'A regular expression string with "(.*)" matching a valid URL in the issue body. The result is trimmed. Example: "### Link to reproduction(.*)### To reproduce"' default: '### Link to reproduction(.*)### To reproduce' - tag-only: - description: Log and tag only. Do not perform closing or commenting actions. - default: false + actions-to-perform: + description: 'Comma-separated list of actions to perform on the issue. Example: "tag,comment,close"' + default: 'tag,comment,close' runs: using: 'composite' @@ -37,4 +37,4 @@ runs: 'INPUT_REPRODUCTION_INVALID_LABEL': ${{inputs.reproduction-invalid-label}} 'INPUT_REPRODUCTION_ISSUE_LABELS': ${{inputs.reproduction-issue-labels}} 'INPUT_REPRODUCTION_LINK_SECTION': ${{inputs.reproduction-link-section}} - 'INPUT_TAG_ONLY': ${{inputs.tag-only}} + 'INPUT_ACTIONS_TO_PERFORM': ${{inputs.actions-to-perform}} diff --git a/.github/actions/triage/dist/index.js b/.github/actions/triage/dist/index.js index 66f48971b..233c7e34c 100644 --- a/.github/actions/triage/dist/index.js +++ b/.github/actions/triage/dist/index.js @@ -33843,6 +33843,7 @@ if (!process.env.GITHUB_TOKEN) throw new TypeError('No GITHUB_TOKEN provided'); if (!process.env.GITHUB_WORKSPACE) throw new TypeError('Not a GitHub workspace'); +var validActionsToPerform = ['tag', 'comment', 'close']; var config = { invalidLink: { comment: (0,core.getInput)('reproduction_comment') || '.github/invalid-reproduction.md', @@ -33853,7 +33854,15 @@ var config = { label: (0,core.getInput)('reproduction_invalid_label') || 'invalid-reproduction', linkSection: (0,core.getInput)('reproduction_link_section') || '### Link to reproduction(.*)### To reproduce', }, - tagOnly: getBooleanOrUndefined('tag_only') || false, + actionsToPerform: ((0,core.getInput)('actions_to_perform') || validActionsToPerform.join(',')) + .split(',') + .map(function (a) { + var action = a.trim().toLowerCase(); + if (validActionsToPerform.includes(action)) { + return action; + } + throw new TypeError("Invalid action: ".concat(action)); + }), token: process.env.GITHUB_TOKEN, workspace: process.env.GITHUB_WORKSPACE, }; @@ -33870,7 +33879,7 @@ function tryParse(json) { // Retrieves a boolean input or undefined based on environment variables function getBooleanOrUndefined(value) { var variable = process.env["INPUT_".concat(value.toUpperCase())]; - return variable === undefined || variable === '' ? undefined : (0,core.getBooleanInput)(value); + return variable === undefined || variable === '' ? undefined : getBooleanInput(value); } // Returns the appropriate label match type function getLabelMatch(value) { @@ -33910,36 +33919,47 @@ function checkValidReproduction() { case 3: (0,core.info)("Invalid reproduction, issue will be closed/labeled/commented..."); // Adjust labels - return [4 /*yield*/, Promise.all(labelsToRemove.map(function (label) { return client.issues.removeLabel(__assign(__assign({}, common), { name: label })); }))]; + return [4 /*yield*/, Promise.all(labelsToRemove.map(function (label) { return client.issues.removeLabel(__assign(__assign({}, common), { name: label })); })) + // Tag + ]; case 4: // Adjust labels _f.sent(); - (0,core.info)("Issue #".concat(issue.number, " - validate label removed")); + if (!!config.actionsToPerform.includes('tag')) return [3 /*break*/, 6]; + (0,core.info)("Added label: ".concat(config.invalidLink.label)); return [4 /*yield*/, client.issues.addLabels(__assign(__assign({}, common), { labels: [config.invalidLink.label] }))]; case 5: _f.sent(); - (0,core.info)("Issue #".concat(issue.number, " - labeled")); - // If tagOnly, do not close or comment - if (config.tagOnly) { - (0,core.info)('Tag-only enabled, no closing/commenting actions taken'); - return [2 /*return*/]; - } - // Perform closing and commenting actions - return [4 /*yield*/, client.issues.update(__assign(__assign({}, common), { state: 'closed' }))]; + return [3 /*break*/, 7]; case 6: - // Perform closing and commenting actions - _f.sent(); - (0,core.info)("Issue #".concat(issue.number, " - closed")); + (0,core.info)('Tag - skipped, not provided in actions to perform'); + _f.label = 7; + case 7: + if (!config.actionsToPerform.includes('comment')) return [3 /*break*/, 10]; comment = (0,external_node_path_namespaceObject.join)(config.workspace, config.invalidLink.comment); _c = (_b = client.issues).createComment; _d = [__assign({}, common)]; _e = {}; return [4 /*yield*/, getCommentBody(comment)]; - case 7: return [4 /*yield*/, _c.apply(_b, [__assign.apply(void 0, _d.concat([(_e.body = _f.sent(), _e)]))])]; - case 8: + case 8: return [4 /*yield*/, _c.apply(_b, [__assign.apply(void 0, _d.concat([(_e.body = _f.sent(), _e)]))])]; + case 9: _f.sent(); - (0,core.info)("Issue #".concat(issue.number, " - commented")); - return [2 /*return*/]; + (0,core.info)("Commented with invalid reproduction message"); + return [3 /*break*/, 11]; + case 10: + (0,core.info)('Comment - skipped, not provided in actions to perform'); + _f.label = 11; + case 11: + if (!config.actionsToPerform.includes('close')) return [3 /*break*/, 13]; + return [4 /*yield*/, client.issues.update(__assign(__assign({}, common), { state: 'closed' }))]; + case 12: + _f.sent(); + (0,core.info)("Closed issue #".concat(issue.number)); + return [3 /*break*/, 14]; + case 13: + (0,core.info)('Close - skipped, not provided in actions to perform'); + _f.label = 14; + case 14: return [2 /*return*/]; } }); }); diff --git a/.github/actions/triage/src/index.ts b/.github/actions/triage/src/index.ts index 40fe76fb2..2259815eb 100644 --- a/.github/actions/triage/src/index.ts +++ b/.github/actions/triage/src/index.ts @@ -8,6 +8,9 @@ import { join } from 'node:path' if (!process.env.GITHUB_TOKEN) throw new TypeError('No GITHUB_TOKEN provided') if (!process.env.GITHUB_WORKSPACE) throw new TypeError('Not a GitHub workspace') +const validActionsToPerform = ['tag', 'comment', 'close'] as const +type ActionsToPerform = (typeof validActionsToPerform)[number] + // Define the configuration object interface Config { invalidLink: { @@ -17,7 +20,7 @@ interface Config { label: string linkSection: string } - tagOnly: boolean + actionsToPerform: ActionsToPerform[] token: string workspace: string } @@ -33,7 +36,16 @@ const config: Config = { linkSection: getInput('reproduction_link_section') || '### Link to reproduction(.*)### To reproduce', }, - tagOnly: getBooleanOrUndefined('tag_only') || false, + actionsToPerform: (getInput('actions_to_perform') || validActionsToPerform.join(',')) + .split(',') + .map((a) => { + const action = a.trim().toLowerCase() as ActionsToPerform + if (validActionsToPerform.includes(action)) { + return action + } + + throw new TypeError(`Invalid action: ${action}`) + }), token: process.env.GITHUB_TOKEN, workspace: process.env.GITHUB_WORKSPACE, } @@ -104,23 +116,31 @@ async function checkValidReproduction(): Promise { await Promise.all( labelsToRemove.map((label) => client.issues.removeLabel({ ...common, name: label })), ) - info(`Issue #${issue.number} - validate label removed`) - await client.issues.addLabels({ ...common, labels: [config.invalidLink.label] }) - info(`Issue #${issue.number} - labeled`) - // If tagOnly, do not close or comment - if (config.tagOnly) { - info('Tag-only enabled, no closing/commenting actions taken') - return + // Tag + if (!config.actionsToPerform.includes('tag')) { + info(`Added label: ${config.invalidLink.label}`) + await client.issues.addLabels({ ...common, labels: [config.invalidLink.label] }) + } else { + info('Tag - skipped, not provided in actions to perform') } - // Perform closing and commenting actions - await client.issues.update({ ...common, state: 'closed' }) - info(`Issue #${issue.number} - closed`) + // Comment + if (config.actionsToPerform.includes('comment')) { + const comment = join(config.workspace, config.invalidLink.comment) + await client.issues.createComment({ ...common, body: await getCommentBody(comment) }) + info(`Commented with invalid reproduction message`) + } else { + info('Comment - skipped, not provided in actions to perform') + } - const comment = join(config.workspace, config.invalidLink.comment) - await client.issues.createComment({ ...common, body: await getCommentBody(comment) }) - info(`Issue #${issue.number} - commented`) + // Close + if (config.actionsToPerform.includes('close')) { + await client.issues.update({ ...common, state: 'closed' }) + info(`Closed issue #${issue.number}`) + } else { + info('Close - skipped, not provided in actions to perform') + } } /** diff --git a/.github/comments/invalid-reproduction.md b/.github/comments/invalid-reproduction.md index b9f67ca76..7c11c7106 100644 --- a/.github/comments/invalid-reproduction.md +++ b/.github/comments/invalid-reproduction.md @@ -1,4 +1,6 @@ -We cannot recreate the issue with the provided information. **Please add a reproduction in order for us to be able to investigate.** +**Please add a reproduction in order for us to be able to investigate.** + +Depending on the quality of reproduction steps, this issue may be closed if no reproduction is provided. ### Why was this issue marked with the `invalid-reproduction` label? diff --git a/.github/workflows/triage.yml b/.github/workflows/triage.yml index 7b827c9bc..026822b0c 100644 --- a/.github/workflows/triage.yml +++ b/.github/workflows/triage.yml @@ -99,4 +99,4 @@ jobs: reproduction-comment: '.github/comments/invalid-reproduction.md' reproduction-link-section: '### Link to the code that reproduces this issue(.*)### Reproduction Steps' reproduction-issue-labels: 'validate-reproduction' - tag-only: 'true' + actions-to-perform: 'tag,comment'