From a1c9a63a3dddca65b78c029dec2be10019e50a1c Mon Sep 17 00:00:00 2001 From: JoannaaKL Date: Mon, 12 Sep 2022 09:42:43 +0000 Subject: [PATCH 1/5] Add new 'include-only-assigned' option If set, only issues containing assignees will be processed --- dist/index.js | 11 ++++++++++- src/classes/issues-processor.ts | 12 ++++++++++++ src/interfaces/issues-processor-options.ts | 1 + src/main.ts | 3 ++- 4 files changed, 25 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index 18754b23a..b247d32be 100644 --- a/dist/index.js +++ b/dist/index.js @@ -476,6 +476,11 @@ class IssuesProcessor { IssuesProcessor._endIssueProcessing(issue); return; // Don't process locked issues } + if (this._isIncludeOnlyAssigned(issue)) { + issueLogger.info(`Skipping this $$type because it's assignees list is empty`); + IssuesProcessor._endIssueProcessing(issue); + return; // If the issue has an 'includeOnlyAssigned' option, process only issues with nonempty assignees list + } const onlyLabels = words_to_list_1.wordsToList(this._getOnlyLabels(issue)); if (onlyLabels.length > 0) { issueLogger.info(`The option ${issueLogger.createOptionLink(option_1.Option.OnlyLabels)} was specified to only process issues and pull requests with all those labels (${logger_service_1.LoggerService.cyan(onlyLabels.length)})`); @@ -988,6 +993,9 @@ class IssuesProcessor { } return this.options.onlyLabels; } + _isIncludeOnlyAssigned(issue) { + return this.options.includeOnlyAssigned && !issue.hasAssignees; + } _getAnyOfLabels(issue) { if (issue.isPullRequest) { if (this.options.anyOfPrLabels !== '') { @@ -2207,7 +2215,8 @@ function _getAndValidateArgs() { ignoreIssueUpdates: _toOptionalBoolean('ignore-issue-updates'), ignorePrUpdates: _toOptionalBoolean('ignore-pr-updates'), exemptDraftPr: core.getInput('exempt-draft-pr') === 'true', - closeIssueReason: core.getInput('close-issue-reason') + closeIssueReason: core.getInput('close-issue-reason'), + includeOnlyAssigned: core.getInput('include-only-assigned') === 'true' }; for (const numberInput of [ 'days-before-stale', diff --git a/src/classes/issues-processor.ts b/src/classes/issues-processor.ts index d0397ebcc..e5b657c44 100644 --- a/src/classes/issues-processor.ts +++ b/src/classes/issues-processor.ts @@ -221,6 +221,14 @@ export class IssuesProcessor { return; // Don't process locked issues } + if (this._isIncludeOnlyAssigned(issue)) { + issueLogger.info( + `Skipping this $$type because it's assignees list is empty` + ); + IssuesProcessor._endIssueProcessing(issue); + return; // If the issue has an 'include-only-assigned' option, process only issues with nonempty assignees list + } + const onlyLabels: string[] = wordsToList(this._getOnlyLabels(issue)); if (onlyLabels.length > 0) { @@ -1012,6 +1020,10 @@ export class IssuesProcessor { return this.options.onlyLabels; } + private _isIncludeOnlyAssigned(issue: Issue): boolean { + return this.options.includeOnlyAssigned && !issue.hasAssignees; + } + private _getAnyOfLabels(issue: Issue): string { if (issue.isPullRequest) { if (this.options.anyOfPrLabels !== '') { diff --git a/src/interfaces/issues-processor-options.ts b/src/interfaces/issues-processor-options.ts index 496584e87..b056a28c6 100644 --- a/src/interfaces/issues-processor-options.ts +++ b/src/interfaces/issues-processor-options.ts @@ -52,4 +52,5 @@ export interface IIssuesProcessorOptions { ignorePrUpdates: boolean | undefined; exemptDraftPr: boolean; closeIssueReason: string; + includeOnlyAssigned: boolean; } diff --git a/src/main.ts b/src/main.ts index 770aa1163..4b7adeab6 100644 --- a/src/main.ts +++ b/src/main.ts @@ -88,7 +88,8 @@ function _getAndValidateArgs(): IIssuesProcessorOptions { ignoreIssueUpdates: _toOptionalBoolean('ignore-issue-updates'), ignorePrUpdates: _toOptionalBoolean('ignore-pr-updates'), exemptDraftPr: core.getInput('exempt-draft-pr') === 'true', - closeIssueReason: core.getInput('close-issue-reason') + closeIssueReason: core.getInput('close-issue-reason'), + includeOnlyAssigned: core.getInput('include-only-assigned') === 'true' }; for (const numberInput of [ From e878daaea6a42d84076008cc44062dfdfd441012 Mon Sep 17 00:00:00 2001 From: JoannaaKL Date: Mon, 12 Sep 2022 09:44:00 +0000 Subject: [PATCH 2/5] Test new flag --- .../constants/default-processor-options.ts | 3 +- __tests__/main.spec.ts | 66 +++++++++++++++++++ src/classes/issue.spec.ts | 3 +- 3 files changed, 70 insertions(+), 2 deletions(-) diff --git a/__tests__/constants/default-processor-options.ts b/__tests__/constants/default-processor-options.ts index ee3e7306d..cda29d456 100644 --- a/__tests__/constants/default-processor-options.ts +++ b/__tests__/constants/default-processor-options.ts @@ -51,5 +51,6 @@ export const DefaultProcessorOptions: IIssuesProcessorOptions = Object.freeze({ ignoreIssueUpdates: undefined, ignorePrUpdates: undefined, exemptDraftPr: false, - closeIssueReason: '' + closeIssueReason: '', + includeOnlyAssigned: false }); diff --git a/__tests__/main.spec.ts b/__tests__/main.spec.ts index 2abb5ee44..eba2e9dfe 100644 --- a/__tests__/main.spec.ts +++ b/__tests__/main.spec.ts @@ -2352,3 +2352,69 @@ test('processing a pull request to be stale with the "stalePrMessage" option set expect(processor.closedIssues).toHaveLength(0); expect(processor.statistics?.addedPullRequestsCommentsCount).toStrictEqual(0); }); + +test('processing an issue with the "includeOnlyAssigned" option and nonempty assignee list will stale the issue', async () => { + const issueDate = new Date(); + issueDate.setDate(issueDate.getDate() - 2); + + const opts: IIssuesProcessorOptions = { + ...DefaultProcessorOptions, + staleIssueLabel: 'This issue is stale', + includeOnlyAssigned: true + }; + + const TestIssueList: Issue[] = [ + generateIssue( + opts, + 1, + 'An issue with no label', + issueDate.toDateString(), + issueDate.toDateString(), + false, + [], + false, + false, + undefined, + ['assignee1'] + ) + ]; + const processor = new IssuesProcessorMock( + opts, + async p => (p === 1 ? TestIssueList : []), + async () => [], + async () => new Date().toDateString() + ); + + // process our fake issue list + await processor.processIssues(1); + + expect(processor.staleIssues).toHaveLength(1); + expect(processor.closedIssues).toHaveLength(0); +}); + +test('processing an issue with the "includeOnlyAssigned" option set and no assignees will not stale the issue', async () => { + const issueDate = new Date(); + issueDate.setDate(issueDate.getDate() - 2); + + const opts: IIssuesProcessorOptions = { + ...DefaultProcessorOptions, + staleIssueLabel: 'This issue is stale', + includeOnlyAssigned: true + }; + + const TestIssueList: Issue[] = [ + generateIssue(opts, 1, 'An issue with no label', issueDate.toDateString()) + ]; + const processor = new IssuesProcessorMock( + opts, + async p => (p === 1 ? TestIssueList : []), + async () => [], + async () => new Date().toDateString() + ); + + // process our fake issue list + await processor.processIssues(1); + + expect(processor.staleIssues).toHaveLength(0); + expect(processor.closedIssues).toHaveLength(0); +}); diff --git a/src/classes/issue.spec.ts b/src/classes/issue.spec.ts index 0a60d1a58..977b767cc 100644 --- a/src/classes/issue.spec.ts +++ b/src/classes/issue.spec.ts @@ -62,7 +62,8 @@ describe('Issue', (): void => { ignoreIssueUpdates: undefined, ignorePrUpdates: undefined, exemptDraftPr: false, - closeIssueReason: '' + closeIssueReason: '', + includeOnlyAssigned: false }; issueInterface = { title: 'dummy-title', From 13f3458051cf17229dd0de716ba8c050f733d482 Mon Sep 17 00:00:00 2001 From: JoannaaKL Date: Mon, 12 Sep 2022 10:01:36 +0000 Subject: [PATCH 3/5] Update code comment --- dist/index.js | 2 +- src/classes/issues-processor.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/dist/index.js b/dist/index.js index b247d32be..6eb9b465e 100644 --- a/dist/index.js +++ b/dist/index.js @@ -479,7 +479,7 @@ class IssuesProcessor { if (this._isIncludeOnlyAssigned(issue)) { issueLogger.info(`Skipping this $$type because it's assignees list is empty`); IssuesProcessor._endIssueProcessing(issue); - return; // If the issue has an 'includeOnlyAssigned' option, process only issues with nonempty assignees list + return; // If the issue has an 'include-only-assigned' option set, process only issues with nonempty assignees list } const onlyLabels = words_to_list_1.wordsToList(this._getOnlyLabels(issue)); if (onlyLabels.length > 0) { diff --git a/src/classes/issues-processor.ts b/src/classes/issues-processor.ts index e5b657c44..2123c720d 100644 --- a/src/classes/issues-processor.ts +++ b/src/classes/issues-processor.ts @@ -226,7 +226,7 @@ export class IssuesProcessor { `Skipping this $$type because it's assignees list is empty` ); IssuesProcessor._endIssueProcessing(issue); - return; // If the issue has an 'include-only-assigned' option, process only issues with nonempty assignees list + return; // If the issue has an 'include-only-assigned' option set, process only issues with nonempty assignees list } const onlyLabels: string[] = wordsToList(this._getOnlyLabels(issue)); From 867763412bf1f80cf89b34e0dbc5e02e407046f3 Mon Sep 17 00:00:00 2001 From: JoannaaKL Date: Mon, 12 Sep 2022 13:11:53 +0200 Subject: [PATCH 4/5] Update src/classes/issues-processor.ts Co-authored-by: Francesco Renzi --- src/classes/issues-processor.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/classes/issues-processor.ts b/src/classes/issues-processor.ts index 2123c720d..be2334d1d 100644 --- a/src/classes/issues-processor.ts +++ b/src/classes/issues-processor.ts @@ -223,7 +223,7 @@ export class IssuesProcessor { if (this._isIncludeOnlyAssigned(issue)) { issueLogger.info( - `Skipping this $$type because it's assignees list is empty` + `Skipping this $$type because its assignees list is empty` ); IssuesProcessor._endIssueProcessing(issue); return; // If the issue has an 'include-only-assigned' option set, process only issues with nonempty assignees list From 8d5a27d5ec7497df2e65d3626e982132265a662e Mon Sep 17 00:00:00 2001 From: JoannaaKL Date: Mon, 12 Sep 2022 11:17:34 +0000 Subject: [PATCH 5/5] Update index.js with typo fix --- dist/index.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dist/index.js b/dist/index.js index 6eb9b465e..c4b2c1345 100644 --- a/dist/index.js +++ b/dist/index.js @@ -477,7 +477,7 @@ class IssuesProcessor { return; // Don't process locked issues } if (this._isIncludeOnlyAssigned(issue)) { - issueLogger.info(`Skipping this $$type because it's assignees list is empty`); + issueLogger.info(`Skipping this $$type because its assignees list is empty`); IssuesProcessor._endIssueProcessing(issue); return; // If the issue has an 'include-only-assigned' option set, process only issues with nonempty assignees list }