diff --git a/__tests__/main.spec.ts b/__tests__/main.spec.ts index eba2e9df..21882547 100644 --- a/__tests__/main.spec.ts +++ b/__tests__/main.spec.ts @@ -1998,6 +1998,84 @@ test('processing an issue opened since 2 days and with the option "daysBeforeIss expect(processor.closedIssues).toHaveLength(0); }); +test('processing an issue opened since 1 hour and with the option "daysBeforeIssueStale" at 0.1666666667 (4 hours) will not make it stale', async () => { + expect.assertions(2); + const opts: IIssuesProcessorOptions = { + ...DefaultProcessorOptions, + daysBeforeStale: 10, + daysBeforeIssueStale: 0.1666666667 + }; + const issueDate = new Date(); + issueDate.setHours(issueDate.getHours() - 1); + const TestIssueList: Issue[] = [ + generateIssue(opts, 1, 'An issue with no label', issueDate.toISOString()) + ]; + const processor = new IssuesProcessorMock( + opts, + async p => (p === 1 ? TestIssueList : []), + async () => [], + async () => new Date().toISOString() + ); + + // process our fake issue list + await processor.processIssues(1); + + expect(processor.staleIssues).toHaveLength(0); + expect(processor.closedIssues).toHaveLength(0); +}); + +test('processing an issue opened since 4 hours and with the option "daysBeforeIssueStale" at 0.1666666667 (4 hours) will make it stale', async () => { + expect.assertions(2); + const opts: IIssuesProcessorOptions = { + ...DefaultProcessorOptions, + daysBeforeStale: 10, + daysBeforeIssueStale: 0.1666666667 + }; + const issueDate = new Date(); + issueDate.setHours(issueDate.getHours() - 4); + const TestIssueList: Issue[] = [ + generateIssue(opts, 1, 'An issue with no label', issueDate.toISOString()) + ]; + const processor = new IssuesProcessorMock( + opts, + async p => (p === 1 ? TestIssueList : []), + async () => [], + async () => new Date().toISOString() + ); + + // process our fake issue list + await processor.processIssues(1); + + expect(processor.staleIssues).toHaveLength(1); + expect(processor.closedIssues).toHaveLength(0); +}); + +test('processing an issue opened since 5 hours and with the option "daysBeforeIssueStale" at 0.1666666667 (4 hours) will make it stale', async () => { + expect.assertions(2); + const opts: IIssuesProcessorOptions = { + ...DefaultProcessorOptions, + daysBeforeStale: 10, + daysBeforeIssueStale: 0.1666666667 + }; + const issueDate = new Date(); + issueDate.setHours(issueDate.getHours() - 5); + const TestIssueList: Issue[] = [ + generateIssue(opts, 1, 'An issue with no label', issueDate.toISOString()) + ]; + const processor = new IssuesProcessorMock( + opts, + async p => (p === 1 ? TestIssueList : []), + async () => [], + async () => new Date().toISOString() + ); + + // process our fake issue list + await processor.processIssues(1); + + expect(processor.staleIssues).toHaveLength(1); + expect(processor.closedIssues).toHaveLength(0); +}); + test('processing a pull request opened since 2 days and with the option "daysBeforePrStale" at 3 will not make it stale', async () => { expect.assertions(2); const opts: IIssuesProcessorOptions = { @@ -2097,6 +2175,105 @@ test('processing a pull request opened since 2 days and with the option "daysBef expect(processor.closedIssues).toHaveLength(0); }); +test('processing a pull request opened since 1 hour and with the option "daysBeforePrStale" at 0.1666666667 (4 hours) will not make it stale', async () => { + expect.assertions(2); + const opts: IIssuesProcessorOptions = { + ...DefaultProcessorOptions, + daysBeforeStale: 10, + daysBeforePrStale: 0.1666666667 + }; + const issueDate = new Date(); + issueDate.setHours(issueDate.getHours() - 1); + const TestIssueList: Issue[] = [ + generateIssue( + opts, + 1, + 'A pull request with no label', + issueDate.toISOString(), + issueDate.toISOString(), + true + ) + ]; + const processor = new IssuesProcessorMock( + opts, + async p => (p === 1 ? TestIssueList : []), + async () => [], + async () => new Date().toISOString() + ); + + // process our fake issue list + await processor.processIssues(1); + + expect(processor.staleIssues).toHaveLength(0); + expect(processor.closedIssues).toHaveLength(0); +}); + +test('processing a pull request opened since 4 hours and with the option "daysBeforePrStale" at 0.1666666667 (4 hours) will make it stale', async () => { + expect.assertions(2); + const opts: IIssuesProcessorOptions = { + ...DefaultProcessorOptions, + daysBeforeStale: 10, + daysBeforePrStale: 0.1666666667 + }; + const issueDate = new Date(); + issueDate.setHours(issueDate.getHours() - 4); + const TestIssueList: Issue[] = [ + generateIssue( + opts, + 1, + 'A pull request with no label', + issueDate.toISOString(), + issueDate.toISOString(), + true + ) + ]; + const processor = new IssuesProcessorMock( + opts, + async p => (p === 1 ? TestIssueList : []), + async () => [], + async () => new Date().toISOString() + ); + + // process our fake issue list + await processor.processIssues(1); + + expect(processor.staleIssues).toHaveLength(1); + expect(processor.closedIssues).toHaveLength(0); +}); + +test('processing a pull request opened since 5 hours and with the option "daysBeforePrStale" at 0.1666666667 (4 hours) will make it stale', async () => { + expect.assertions(2); + const opts: IIssuesProcessorOptions = { + ...DefaultProcessorOptions, + daysBeforeStale: 10, + daysBeforePrStale: 0.1666666667 + }; + const issueDate = new Date(); + issueDate.setHours(issueDate.getHours() - 5); + const TestIssueList: Issue[] = [ + generateIssue( + opts, + 1, + 'A pull request with no label', + issueDate.toISOString(), + issueDate.toISOString(), + true + ) + ]; + const processor = new IssuesProcessorMock( + opts, + async p => (p === 1 ? TestIssueList : []), + async () => [], + async () => new Date().toISOString() + ); + + // process our fake issue list + await processor.processIssues(1); + + expect(processor.staleIssues).toHaveLength(1); + expect(processor.closedIssues).toHaveLength(0); +}); + test('processing a previously closed issue with a close label will remove the close label', async () => { expect.assertions(1); const opts: IIssuesProcessorOptions = { diff --git a/dist/index.js b/dist/index.js index 96ed9e6f..0e78fccc 100644 --- a/dist/index.js +++ b/dist/index.js @@ -2183,9 +2183,9 @@ function _getAndValidateArgs() { stalePrMessage: core.getInput('stale-pr-message'), closeIssueMessage: core.getInput('close-issue-message'), closePrMessage: core.getInput('close-pr-message'), - daysBeforeStale: parseInt(core.getInput('days-before-stale', { required: true })), - daysBeforeIssueStale: parseInt(core.getInput('days-before-issue-stale')), - daysBeforePrStale: parseInt(core.getInput('days-before-pr-stale')), + daysBeforeStale: parseFloat(core.getInput('days-before-stale', { required: true })), + daysBeforeIssueStale: parseFloat(core.getInput('days-before-issue-stale')), + daysBeforePrStale: parseFloat(core.getInput('days-before-pr-stale')), daysBeforeClose: parseInt(core.getInput('days-before-close', { required: true })), daysBeforeIssueClose: parseInt(core.getInput('days-before-issue-close')), daysBeforePrClose: parseInt(core.getInput('days-before-pr-close')), @@ -2233,11 +2233,14 @@ function _getAndValidateArgs() { closeIssueReason: core.getInput('close-issue-reason'), includeOnlyAssigned: core.getInput('include-only-assigned') === 'true' }; - for (const numberInput of [ - 'days-before-stale', - 'days-before-close', - 'operations-per-run' - ]) { + for (const numberInput of ['days-before-stale']) { + if (isNaN(parseFloat(core.getInput(numberInput)))) { + const errorMessage = `Option "${numberInput}" did not parse to a valid float`; + core.setFailed(errorMessage); + throw new Error(errorMessage); + } + } + for (const numberInput of ['days-before-close', 'operations-per-run']) { if (isNaN(parseInt(core.getInput(numberInput)))) { const errorMessage = `Option "${numberInput}" did not parse to a valid integer`; core.setFailed(errorMessage); diff --git a/src/main.ts b/src/main.ts index 4b7adeab..1045d6c5 100644 --- a/src/main.ts +++ b/src/main.ts @@ -28,11 +28,11 @@ function _getAndValidateArgs(): IIssuesProcessorOptions { stalePrMessage: core.getInput('stale-pr-message'), closeIssueMessage: core.getInput('close-issue-message'), closePrMessage: core.getInput('close-pr-message'), - daysBeforeStale: parseInt( + daysBeforeStale: parseFloat( core.getInput('days-before-stale', {required: true}) ), - daysBeforeIssueStale: parseInt(core.getInput('days-before-issue-stale')), - daysBeforePrStale: parseInt(core.getInput('days-before-pr-stale')), + daysBeforeIssueStale: parseFloat(core.getInput('days-before-issue-stale')), + daysBeforePrStale: parseFloat(core.getInput('days-before-pr-stale')), daysBeforeClose: parseInt( core.getInput('days-before-close', {required: true}) ), @@ -92,11 +92,15 @@ function _getAndValidateArgs(): IIssuesProcessorOptions { includeOnlyAssigned: core.getInput('include-only-assigned') === 'true' }; - for (const numberInput of [ - 'days-before-stale', - 'days-before-close', - 'operations-per-run' - ]) { + for (const numberInput of ['days-before-stale']) { + if (isNaN(parseFloat(core.getInput(numberInput)))) { + const errorMessage = `Option "${numberInput}" did not parse to a valid float`; + core.setFailed(errorMessage); + throw new Error(errorMessage); + } + } + + for (const numberInput of ['days-before-close', 'operations-per-run']) { if (isNaN(parseInt(core.getInput(numberInput)))) { const errorMessage = `Option "${numberInput}" did not parse to a valid integer`; core.setFailed(errorMessage);