Compare commits

..

4 Commits

Author SHA1 Message Date
John Sudol
601cc005e7 update README and logs to provide clarity 2022-11-25 21:47:46 +00:00
Iván Reinoso García
65b52aff67 Allow daysBeforeStale options to be float (#841)
* feat: allow daysBeforeStale options to be float

* update dist
2022-10-19 12:08:31 +02:00
Francesco Renzi
0d6f830071 Update changelog for 6.0.1 2022-10-07 11:12:02 +01:00
Francesco Renzi
b909bf8927 Merge pull request #839 from actions/rentziass/update-actions-core
Update @actions/core to 1.10.0
2022-10-07 11:05:38 +01:00
6 changed files with 216 additions and 22 deletions

View File

@@ -1,5 +1,9 @@
# Changelog # Changelog
# [6.0.1]
Update @actions/core to v1.10.0 ([#839](https://github.com/actions/stale/pull/839))
# [6.0.0] # [6.0.0]
:warning: Breaking change :warning: :warning: Breaking change :warning:

View File

@@ -246,8 +246,8 @@ Required Permission: `pull-requests: write`
#### exempt-issue-labels #### exempt-issue-labels
The label(s) that can exempt to automatically mark as stale the issues. Comma separated list of labels that exclude the issue from being marked as stale
It can be a comma separated list of labels (e.g: `question,bug`). (e.g: `question,bug`)
If unset (or an empty string), this option will not alter the stale workflow. If unset (or an empty string), this option will not alter the stale workflow.
@@ -255,8 +255,8 @@ Default value: unset
#### exempt-pr-labels #### exempt-pr-labels
The label(s) that can exempt to automatically mark as stale the pull requests. Comma separated list of labels that exclude the pull request from being marked as stale
It can be a comma separated list of labels (e.g: `need-help,WIP`). (e.g: `need-help,WIP`)
If unset (or an empty string), this option will not alter the stale workflow. If unset (or an empty string), this option will not alter the stale workflow.

View File

@@ -1998,6 +1998,84 @@ test('processing an issue opened since 2 days and with the option "daysBeforeIss
expect(processor.closedIssues).toHaveLength(0); 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 () => { 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); expect.assertions(2);
const opts: IIssuesProcessorOptions = { 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); 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 () => { test('processing a previously closed issue with a close label will remove the close label', async () => {
expect.assertions(1); expect.assertions(1);
const opts: IIssuesProcessorOptions = { const opts: IIssuesProcessorOptions = {

23
dist/index.js vendored
View File

@@ -532,8 +532,10 @@ class IssuesProcessor {
? this.options.exemptPrLabels ? this.options.exemptPrLabels
: this.options.exemptIssueLabels); : this.options.exemptIssueLabels);
if (exemptLabels.some((exemptLabel) => is_labeled_1.isLabeled(issue, exemptLabel))) { if (exemptLabels.some((exemptLabel) => is_labeled_1.isLabeled(issue, exemptLabel))) {
// check to see if the issue is stale and has an exempt label
// see issue #136 for more details
if (issue.isStale) { if (issue.isStale) {
issueLogger.info(`An exempt label was added after the stale label.`); issueLogger.info(`This $$type has both an exempt and stale label, proceeding to remove the stale label.`);
yield this._removeStaleLabel(issue, staleLabel); yield this._removeStaleLabel(issue, staleLabel);
} }
issueLogger.info(`Skipping this $$type because it has an exempt label`); issueLogger.info(`Skipping this $$type because it has an exempt label`);
@@ -2183,9 +2185,9 @@ function _getAndValidateArgs() {
stalePrMessage: core.getInput('stale-pr-message'), stalePrMessage: core.getInput('stale-pr-message'),
closeIssueMessage: core.getInput('close-issue-message'), closeIssueMessage: core.getInput('close-issue-message'),
closePrMessage: core.getInput('close-pr-message'), closePrMessage: core.getInput('close-pr-message'),
daysBeforeStale: parseInt(core.getInput('days-before-stale', { required: true })), daysBeforeStale: parseFloat(core.getInput('days-before-stale', { required: true })),
daysBeforeIssueStale: parseInt(core.getInput('days-before-issue-stale')), daysBeforeIssueStale: parseFloat(core.getInput('days-before-issue-stale')),
daysBeforePrStale: parseInt(core.getInput('days-before-pr-stale')), daysBeforePrStale: parseFloat(core.getInput('days-before-pr-stale')),
daysBeforeClose: parseInt(core.getInput('days-before-close', { required: true })), daysBeforeClose: parseInt(core.getInput('days-before-close', { required: true })),
daysBeforeIssueClose: parseInt(core.getInput('days-before-issue-close')), daysBeforeIssueClose: parseInt(core.getInput('days-before-issue-close')),
daysBeforePrClose: parseInt(core.getInput('days-before-pr-close')), daysBeforePrClose: parseInt(core.getInput('days-before-pr-close')),
@@ -2233,11 +2235,14 @@ function _getAndValidateArgs() {
closeIssueReason: core.getInput('close-issue-reason'), closeIssueReason: core.getInput('close-issue-reason'),
includeOnlyAssigned: core.getInput('include-only-assigned') === 'true' includeOnlyAssigned: core.getInput('include-only-assigned') === 'true'
}; };
for (const numberInput of [ for (const numberInput of ['days-before-stale']) {
'days-before-stale', if (isNaN(parseFloat(core.getInput(numberInput)))) {
'days-before-close', const errorMessage = `Option "${numberInput}" did not parse to a valid float`;
'operations-per-run' core.setFailed(errorMessage);
]) { throw new Error(errorMessage);
}
}
for (const numberInput of ['days-before-close', 'operations-per-run']) {
if (isNaN(parseInt(core.getInput(numberInput)))) { if (isNaN(parseInt(core.getInput(numberInput)))) {
const errorMessage = `Option "${numberInput}" did not parse to a valid integer`; const errorMessage = `Option "${numberInput}" did not parse to a valid integer`;
core.setFailed(errorMessage); core.setFailed(errorMessage);

View File

@@ -337,8 +337,12 @@ export class IssuesProcessor {
isLabeled(issue, exemptLabel) isLabeled(issue, exemptLabel)
) )
) { ) {
// check to see if the issue is stale and has an exempt label
// see issue #136 for more details
if (issue.isStale) { if (issue.isStale) {
issueLogger.info(`An exempt label was added after the stale label.`); issueLogger.info(
`This $$type has both an exempt and stale label, proceeding to remove the stale label.`
);
await this._removeStaleLabel(issue, staleLabel); await this._removeStaleLabel(issue, staleLabel);
} }

View File

@@ -28,11 +28,11 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
stalePrMessage: core.getInput('stale-pr-message'), stalePrMessage: core.getInput('stale-pr-message'),
closeIssueMessage: core.getInput('close-issue-message'), closeIssueMessage: core.getInput('close-issue-message'),
closePrMessage: core.getInput('close-pr-message'), closePrMessage: core.getInput('close-pr-message'),
daysBeforeStale: parseInt( daysBeforeStale: parseFloat(
core.getInput('days-before-stale', {required: true}) core.getInput('days-before-stale', {required: true})
), ),
daysBeforeIssueStale: parseInt(core.getInput('days-before-issue-stale')), daysBeforeIssueStale: parseFloat(core.getInput('days-before-issue-stale')),
daysBeforePrStale: parseInt(core.getInput('days-before-pr-stale')), daysBeforePrStale: parseFloat(core.getInput('days-before-pr-stale')),
daysBeforeClose: parseInt( daysBeforeClose: parseInt(
core.getInput('days-before-close', {required: true}) core.getInput('days-before-close', {required: true})
), ),
@@ -92,11 +92,15 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
includeOnlyAssigned: core.getInput('include-only-assigned') === 'true' includeOnlyAssigned: core.getInput('include-only-assigned') === 'true'
}; };
for (const numberInput of [ for (const numberInput of ['days-before-stale']) {
'days-before-stale', if (isNaN(parseFloat(core.getInput(numberInput)))) {
'days-before-close', const errorMessage = `Option "${numberInput}" did not parse to a valid float`;
'operations-per-run' core.setFailed(errorMessage);
]) { throw new Error(errorMessage);
}
}
for (const numberInput of ['days-before-close', 'operations-per-run']) {
if (isNaN(parseInt(core.getInput(numberInput)))) { if (isNaN(parseInt(core.getInput(numberInput)))) {
const errorMessage = `Option "${numberInput}" did not parse to a valid integer`; const errorMessage = `Option "${numberInput}" did not parse to a valid integer`;
core.setFailed(errorMessage); core.setFailed(errorMessage);