mirror of
https://github.com/actions/stale.git
synced 2025-12-29 03:18:17 +00:00
Compare commits
6 Commits
rentziass/
...
johnsudol/
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fde7d4444e | ||
|
|
e27c9afd63 | ||
|
|
52086c38b6 | ||
|
|
65b52aff67 | ||
|
|
0d6f830071 | ||
|
|
b909bf8927 |
@@ -1,5 +1,9 @@
|
||||
# Changelog
|
||||
|
||||
# [6.0.1]
|
||||
|
||||
Update @actions/core to v1.10.0 ([#839](https://github.com/actions/stale/pull/839))
|
||||
|
||||
# [6.0.0]
|
||||
|
||||
:warning: Breaking change :warning:
|
||||
|
||||
@@ -246,8 +246,7 @@ Required Permission: `pull-requests: write`
|
||||
|
||||
#### exempt-issue-labels
|
||||
|
||||
The label(s) that can exempt to automatically mark as stale the issues.
|
||||
It can be a comma separated list of labels (e.g: `question,bug`).
|
||||
A comma separated list of labels, that prevent the issue from being marked as stale. (e.g: `question,bug,wip`)
|
||||
|
||||
If unset (or an empty string), this option will not alter the stale workflow.
|
||||
|
||||
|
||||
@@ -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 = {
|
||||
|
||||
26
dist/index.js
vendored
26
dist/index.js
vendored
@@ -381,7 +381,7 @@ class IssuesProcessor {
|
||||
this.options = options;
|
||||
this.client = github_1.getOctokit(this.options.repoToken);
|
||||
this.operations = new stale_operations_1.StaleOperations(this.options);
|
||||
this._logger.info(logger_service_1.LoggerService.yellow(`Starting the stale action process...`));
|
||||
this._logger.info(logger_service_1.LoggerService.yellow(`Starting the stale action process... logging`));
|
||||
if (this.options.debugOnly) {
|
||||
this._logger.warning(logger_service_1.LoggerService.yellowBright(`Executing in debug mode!`));
|
||||
this._logger.warning(logger_service_1.LoggerService.yellowBright(`The debug output will be written but no issues/PRs will be processed.`));
|
||||
@@ -526,14 +526,15 @@ class IssuesProcessor {
|
||||
issueLogger.info(`This $$type has a stale label`);
|
||||
}
|
||||
else {
|
||||
issueLogger.info(`This $$type hasn't a stale label`);
|
||||
issueLogger.info(`This $$type doesn't have a stale label`);
|
||||
}
|
||||
const exemptLabels = words_to_list_1.wordsToList(issue.isPullRequest
|
||||
? this.options.exemptPrLabels
|
||||
: this.options.exemptIssueLabels);
|
||||
if (exemptLabels.some((exemptLabel) => is_labeled_1.isLabeled(issue, exemptLabel))) {
|
||||
if (issue.isStale) {
|
||||
issueLogger.info(`An exempt label was added after the stale label.`);
|
||||
// issueLogger.info(`An exempt label was added after the stale label.`);
|
||||
issueLogger.info(`This $$type has an exempt label, removing the stale label.`);
|
||||
yield this._removeStaleLabel(issue, staleLabel);
|
||||
}
|
||||
issueLogger.info(`Skipping this $$type because it has an exempt label`);
|
||||
@@ -2183,9 +2184,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 +2234,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);
|
||||
|
||||
@@ -78,7 +78,7 @@ export class IssuesProcessor {
|
||||
this.operations = new StaleOperations(this.options);
|
||||
|
||||
this._logger.info(
|
||||
LoggerService.yellow(`Starting the stale action process...`)
|
||||
LoggerService.yellow(`Starting the stale action process... logging`)
|
||||
);
|
||||
|
||||
if (this.options.debugOnly) {
|
||||
@@ -323,7 +323,7 @@ export class IssuesProcessor {
|
||||
if (issue.isStale) {
|
||||
issueLogger.info(`This $$type has a stale label`);
|
||||
} else {
|
||||
issueLogger.info(`This $$type hasn't a stale label`);
|
||||
issueLogger.info(`This $$type doesn't have a stale label`);
|
||||
}
|
||||
|
||||
const exemptLabels: string[] = wordsToList(
|
||||
@@ -338,7 +338,10 @@ export class IssuesProcessor {
|
||||
)
|
||||
) {
|
||||
if (issue.isStale) {
|
||||
issueLogger.info(`An exempt label was added after the stale label.`);
|
||||
// issueLogger.info(`An exempt label was added after the stale label.`);
|
||||
issueLogger.info(
|
||||
`This $$type has an exempt label, removing the stale label.`
|
||||
);
|
||||
await this._removeStaleLabel(issue, staleLabel);
|
||||
}
|
||||
|
||||
|
||||
20
src/main.ts
20
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);
|
||||
|
||||
Reference in New Issue
Block a user