feat(options): add new options to avoid stale base on comments (#494)
* feat(options): add new options to avoid stale based on comments Helping to close #441, #470, #435? Closes #390 due to no activity BREAKING CHANGES: the options related to remove-stale-when-updated will only check the updates, not the comment. It is only impactint the configurations using the value at false * style(readme): fix table syntax due to rebase * docs(readme): add permissions only for the new options
This commit is contained in:
parent
f1017f33dd
commit
1efddcbe9f
126
README.md
126
README.md
|
@ -14,54 +14,57 @@ The default configuration will:
|
||||||
|
|
||||||
Every argument is optional.
|
Every argument is optional.
|
||||||
|
|
||||||
| Input | Description | Default |
|
| Input | Description | Default |
|
||||||
| ------------------------------------------------------------------- | ------------------------------------------------------------------------ | --------------------- |
|
| ----------------------------------------------------------------------- | ------------------------------------------------------------------------------------ | --------------------- |
|
||||||
| [repo-token](#repo-token) | PAT for GitHub API authentication | `${{ github.token }}` |
|
| [repo-token](#repo-token) | PAT for GitHub API authentication | `${{ github.token }}` |
|
||||||
| [days-before-stale](#days-before-stale) | Idle number of days before marking issues/PRs stale | `60` |
|
| [days-before-stale](#days-before-stale) | Idle number of days before marking issues/PRs stale | `60` |
|
||||||
| [days-before-issue-stale](#days-before-issue-stale) | Override [days-before-stale](#days-before-stale) for issues only | |
|
| [days-before-issue-stale](#days-before-issue-stale) | Override [days-before-stale](#days-before-stale) for issues only | |
|
||||||
| [days-before-pr-stale](#days-before-pr-stale) | Override [days-before-stale](#days-before-stale) for PRs only | |
|
| [days-before-pr-stale](#days-before-pr-stale) | Override [days-before-stale](#days-before-stale) for PRs only | |
|
||||||
| [days-before-close](#days-before-close) | Idle number of days before closing stale issues/PRs | `7` |
|
| [days-before-close](#days-before-close) | Idle number of days before closing stale issues/PRs | `7` |
|
||||||
| [days-before-issue-close](#days-before-issue-close) | Override [days-before-close](#days-before-close) for issues only | |
|
| [days-before-issue-close](#days-before-issue-close) | Override [days-before-close](#days-before-close) for issues only | |
|
||||||
| [days-before-pr-close](#days-before-pr-close) | Override [days-before-close](#days-before-close) for PRs only | |
|
| [days-before-pr-close](#days-before-pr-close) | Override [days-before-close](#days-before-close) for PRs only | |
|
||||||
| [stale-issue-message](#stale-issue-message) | Comment on the staled issues | |
|
| [stale-issue-message](#stale-issue-message) | Comment on the staled issues | |
|
||||||
| [stale-pr-message](#stale-pr-message) | Comment on the staled PRs | |
|
| [stale-pr-message](#stale-pr-message) | Comment on the staled PRs | |
|
||||||
| [close-issue-message](#close-issue-message) | Comment on the staled issues while closed | |
|
| [close-issue-message](#close-issue-message) | Comment on the staled issues while closed | |
|
||||||
| [close-pr-message](#close-pr-message) | Comment on the staled PRs while closed | |
|
| [close-pr-message](#close-pr-message) | Comment on the staled PRs while closed | |
|
||||||
| [stale-issue-label](#stale-issue-label) | Label to apply on staled issues | `Stale` |
|
| [stale-issue-label](#stale-issue-label) | Label to apply on staled issues | `Stale` |
|
||||||
| [close-issue-label](#close-issue-label) | Label to apply on closed issues | |
|
| [close-issue-label](#close-issue-label) | Label to apply on closed issues | |
|
||||||
| [stale-pr-label](#stale-pr-label) | Label to apply on staled PRs | `Stale` |
|
| [stale-pr-label](#stale-pr-label) | Label to apply on staled PRs | `Stale` |
|
||||||
| [close-pr-label](#close-pr-label) | Label to apply on closed PRs | |
|
| [close-pr-label](#close-pr-label) | Label to apply on closed PRs | |
|
||||||
| [exempt-issue-labels](#exempt-issue-labels) | Labels on issues exempted from stale | |
|
| [exempt-issue-labels](#exempt-issue-labels) | Labels on issues exempted from stale | |
|
||||||
| [exempt-pr-labels](#exempt-pr-labels) | Labels on PRs exempted from stale | |
|
| [exempt-pr-labels](#exempt-pr-labels) | Labels on PRs exempted from stale | |
|
||||||
| [only-labels](#only-labels) | Only issues/PRs with ALL these labels are checked | |
|
| [only-labels](#only-labels) | Only issues/PRs with ALL these labels are checked | |
|
||||||
| [only-issue-labels](#only-issue-labels) | Only issues with ALL these labels are checked | |
|
| [only-issue-labels](#only-issue-labels) | Only issues with ALL these labels are checked | |
|
||||||
| [only-pr-labels](#only-pr-labels) | Only PRs with ALL these labels are checked | |
|
| [only-pr-labels](#only-pr-labels) | Only PRs with ALL these labels are checked | |
|
||||||
| [any-of-labels](#any-of-labels) | Only issues/PRs with ANY of these labels are checked | |
|
| [any-of-labels](#any-of-labels) | Only issues/PRs with ANY of these labels are checked | |
|
||||||
| [any-of-issue-labels](#any-of-issue-labels) | Only issues with ANY of these labels are checked | |
|
| [any-of-issue-labels](#any-of-issue-labels) | Only issues with ANY of these labels are checked | |
|
||||||
| [any-of-pr-labels](#any-of-pr-labels) | Only PRs with ANY of these labels are checked | |
|
| [any-of-pr-labels](#any-of-pr-labels) | Only PRs with ANY of these labels are checked | |
|
||||||
| [operations-per-run](#operations-per-run) | Max number of operations per run | `30` |
|
| [operations-per-run](#operations-per-run) | Max number of operations per run | `30` |
|
||||||
| [remove-stale-when-updated](#remove-stale-when-updated) | Remove stale label from issues/PRs on updates/comments | `true` |
|
| [remove-stale-when-updated](#remove-stale-when-updated) | Remove stale label from issues/PRs on updates | `true` |
|
||||||
| [remove-issue-stale-when-updated](#remove-issue-stale-when-updated) | Remove stale label from issues on updates/comments | |
|
| [remove-issue-stale-when-updated](#remove-issue-stale-when-updated) | Override [remove-stale-when-updated](#remove-stale-when-updated) for issues only | |
|
||||||
| [remove-pr-stale-when-updated](#remove-pr-stale-when-updated) | Remove stale label from PRs on updates/comments | |
|
| [remove-pr-stale-when-updated](#remove-pr-stale-when-updated) | Override [remove-stale-when-updated](#remove-stale-when-updated) for PRs only | |
|
||||||
| [labels-to-add-when-unstale](#labels-to-add-when-unstale) | Add specified labels from issues/PRs when they become unstale | |
|
| [remove-stale-when-commented](#remove-stale-when-commented) | Remove stale label from issues/PRs on comments | `true` |
|
||||||
| [labels-to-remove-when-unstale](#labels-to-remove-when-unstale) | Remove specified labels from issues/PRs when they become unstale | |
|
| [remove-issue-stale-when-commented](#remove-issue-stale-when-commented) | Override [remove-stale-when-commented](#remove-stale-when-commented) for issues only | |
|
||||||
| [debug-only](#debug-only) | Dry-run | `false` |
|
| [remove-pr-stale-when-commented](#remove-pr-stale-when-commented) | Override [remove-stale-when-commented](#remove-stale-when-commented) for PRs only | |
|
||||||
| [ascending](#ascending) | Order to get issues/PRs | `false` |
|
| [labels-to-add-when-unstale](#labels-to-add-when-unstale) | Add specified labels from issues/PRs when they become unstale | |
|
||||||
| [start-date](#start-date) | Skip stale action for issues/PRs created before it | |
|
| [labels-to-remove-when-unstale](#labels-to-remove-when-unstale) | Remove specified labels from issues/PRs when they become unstale | |
|
||||||
| [delete-branch](#delete-branch) | Delete branch after closing a stale PR | `false` |
|
| [debug-only](#debug-only) | Dry-run | `false` |
|
||||||
| [exempt-milestones](#exempt-milestones) | Milestones on issues/PRs exempted from stale | |
|
| [ascending](#ascending) | Order to get issues/PRs | `false` |
|
||||||
| [exempt-issue-milestones](#exempt-issue-milestones) | Override [exempt-milestones](#exempt-milestones) for issues only | |
|
| [start-date](#start-date) | Skip stale action for issues/PRs created before it | |
|
||||||
| [exempt-pr-milestones](#exempt-pr-milestones) | Override [exempt-milestones](#exempt-milestones) for PRs only | |
|
| [delete-branch](#delete-branch) | Delete branch after closing a stale PR | `false` |
|
||||||
| [exempt-all-milestones](#exempt-all-milestones) | Exempt all issues/PRs with milestones from stale | |
|
| [exempt-milestones](#exempt-milestones) | Milestones on issues/PRs exempted from stale | |
|
||||||
| [exempt-all-issue-milestones](#exempt-all-issue-milestones) | Override [exempt-all-milestones](#exempt-all-milestones) for issues only | |
|
| [exempt-issue-milestones](#exempt-issue-milestones) | Override [exempt-milestones](#exempt-milestones) for issues only | |
|
||||||
| [exempt-all-pr-milestones](#exempt-all-pr-milestones) | Override [exempt-all-milestones](#exempt-all-milestones) for PRs only | |
|
| [exempt-pr-milestones](#exempt-pr-milestones) | Override [exempt-milestones](#exempt-milestones) for PRs only | |
|
||||||
| [exempt-assignees](#exempt-assignees) | Assignees on issues/PRs exempted from stale | |
|
| [exempt-all-milestones](#exempt-all-milestones) | Exempt all issues/PRs with milestones from stale | |
|
||||||
| [exempt-issue-assignees](#exempt-issue-assignees) | Override [exempt-assignees](#exempt-assignees) for issues only | |
|
| [exempt-all-issue-milestones](#exempt-all-issue-milestones) | Override [exempt-all-milestones](#exempt-all-milestones) for issues only | |
|
||||||
| [exempt-pr-assignees](#exempt-pr-assignees) | Override [exempt-assignees](#exempt-assignees) for PRs only | |
|
| [exempt-all-pr-milestones](#exempt-all-pr-milestones) | Override [exempt-all-milestones](#exempt-all-milestones) for PRs only | |
|
||||||
| [exempt-all-assignees](#exempt-all-assignees) | Exempt all issues/PRs with assignees from stale | |
|
| [exempt-assignees](#exempt-assignees) | Assignees on issues/PRs exempted from stale | |
|
||||||
| [exempt-all-issue-assignees](#exempt-all-issue-assignees) | Override [exempt-all-assignees](#exempt-all-assignees) for issues only | |
|
| [exempt-issue-assignees](#exempt-issue-assignees) | Override [exempt-assignees](#exempt-assignees) for issues only | |
|
||||||
| [exempt-all-pr-assignees](#exempt-all-pr-assignees) | Override [exempt-all-assignees](#exempt-all-assignees) for PRs only | |
|
| [exempt-pr-assignees](#exempt-pr-assignees) | Override [exempt-assignees](#exempt-assignees) for PRs only | |
|
||||||
| [enable-statistics](#enable-statistics) | Display statistics in the logs | `true` |
|
| [exempt-all-assignees](#exempt-all-assignees) | Exempt all issues/PRs with assignees from stale | |
|
||||||
|
| [exempt-all-issue-assignees](#exempt-all-issue-assignees) | Override [exempt-all-assignees](#exempt-all-assignees) for issues only | |
|
||||||
|
| [exempt-all-pr-assignees](#exempt-all-pr-assignees) | Override [exempt-all-assignees](#exempt-all-assignees) for PRs only | |
|
||||||
|
| [enable-statistics](#enable-statistics) | Display statistics in the logs | `true` |
|
||||||
|
|
||||||
### List of output options
|
### List of output options
|
||||||
|
|
||||||
|
@ -293,22 +296,43 @@ Default value: `30`
|
||||||
|
|
||||||
#### remove-stale-when-updated
|
#### remove-stale-when-updated
|
||||||
|
|
||||||
Automatically remove the stale label when the issues or the pull requests are updated (based on [GitHub issue](https://docs.github.com/en/rest/reference/issues) field `updated_at`) or commented.
|
Automatically remove the stale label when the issues or the pull requests are updated (based on [GitHub issue](https://docs.github.com/en/rest/reference/issues) field `updated_at`).
|
||||||
|
|
||||||
Default value: `true`
|
Default value: `true`
|
||||||
|
|
||||||
#### remove-issue-stale-when-updated
|
#### remove-issue-stale-when-updated
|
||||||
|
|
||||||
Override [remove-stale-when-updated](#remove-stale-when-updated) but only to automatically remove the stale label when the issues are updated (based on [GitHub issue](https://docs.github.com/en/rest/reference/issues) field `updated_at`) or commented.
|
Override [remove-stale-when-updated](#remove-stale-when-updated) but only to automatically remove the stale label when the issues are updated (based on [GitHub issue](https://docs.github.com/en/rest/reference/issues) field `updated_at`).
|
||||||
|
|
||||||
Default value: unset
|
Default value: unset
|
||||||
|
|
||||||
#### remove-pr-stale-when-updated
|
#### remove-pr-stale-when-updated
|
||||||
|
|
||||||
Override [remove-stale-when-updated](#remove-stale-when-updated) but only to automatically remove the stale label when the pull requests are updated (based on [GitHub issue](https://docs.github.com/en/rest/reference/issues) field `updated_at`) or commented.
|
Override [remove-stale-when-updated](#remove-stale-when-updated) but only to automatically remove the stale label when the pull requests are updated (based on [GitHub issue](https://docs.github.com/en/rest/reference/issues) field `updated_at`).
|
||||||
|
|
||||||
Default value: unset
|
Default value: unset
|
||||||
|
|
||||||
|
#### remove-stale-when-commented
|
||||||
|
|
||||||
|
Automatically remove the stale label when the issues or the pull requests are commented.
|
||||||
|
|
||||||
|
Default value: `true`
|
||||||
|
Required Permission: `issues: write` and `pull-requests: write`
|
||||||
|
|
||||||
|
#### remove-issue-stale-when-commented
|
||||||
|
|
||||||
|
Override [remove-stale-when-commented](#remove-stale-when-commented) but only to automatically remove the stale label when the issues are commented.
|
||||||
|
|
||||||
|
Default value: unset
|
||||||
|
Required Permission: `issues: write` and `pull-requests: write`
|
||||||
|
|
||||||
|
#### remove-pr-stale-when-commented
|
||||||
|
|
||||||
|
Override [remove-stale-when-commented](#remove-stale-when-commented) but only to automatically remove the stale label when the pull requests are commented.
|
||||||
|
|
||||||
|
Default value: unset
|
||||||
|
Required Permission: `issues: write` and `pull-requests: write`
|
||||||
|
|
||||||
#### labels-to-add-when-unstale
|
#### labels-to-add-when-unstale
|
||||||
|
|
||||||
A comma delimited list of labels to add when a stale issue or pull request receives activity and has the [stale-issue-label](#stale-issue-label) or [stale-pr-label](#stale-pr-label) removed from it.
|
A comma delimited list of labels to add when a stale issue or pull request receives activity and has the [stale-issue-label](#stale-issue-label) or [stale-pr-label](#stale-pr-label) removed from it.
|
||||||
|
|
|
@ -29,6 +29,9 @@ export const DefaultProcessorOptions: IIssuesProcessorOptions = Object.freeze({
|
||||||
removeStaleWhenUpdated: false,
|
removeStaleWhenUpdated: false,
|
||||||
removeIssueStaleWhenUpdated: undefined,
|
removeIssueStaleWhenUpdated: undefined,
|
||||||
removePrStaleWhenUpdated: undefined,
|
removePrStaleWhenUpdated: undefined,
|
||||||
|
removeStaleWhenCommented: false,
|
||||||
|
removeIssueStaleWhenCommented: undefined,
|
||||||
|
removePrStaleWhenCommented: undefined,
|
||||||
ascending: false,
|
ascending: false,
|
||||||
deleteBranch: false,
|
deleteBranch: false,
|
||||||
startDate: '',
|
startDate: '',
|
||||||
|
|
|
@ -1220,7 +1220,7 @@ test('stale issues should not be closed if days is set to -1', async () => {
|
||||||
});
|
});
|
||||||
|
|
||||||
test('stale label should be removed if a comment was added to a stale issue', async () => {
|
test('stale label should be removed if a comment was added to a stale issue', async () => {
|
||||||
const opts = {...DefaultProcessorOptions, removeStaleWhenUpdated: true};
|
const opts = {...DefaultProcessorOptions, removeStaleWhenCommented: true};
|
||||||
const TestIssueList: Issue[] = [
|
const TestIssueList: Issue[] = [
|
||||||
generateIssue(
|
generateIssue(
|
||||||
opts,
|
opts,
|
||||||
|
@ -1259,7 +1259,7 @@ test('when the option "labelsToAddWhenUnstale" is set, the labels should be adde
|
||||||
expect.assertions(4);
|
expect.assertions(4);
|
||||||
const opts = {
|
const opts = {
|
||||||
...DefaultProcessorOptions,
|
...DefaultProcessorOptions,
|
||||||
removeStaleWhenUpdated: true,
|
removeStaleWhenCommented: true,
|
||||||
labelsToAddWhenUnstale: 'test'
|
labelsToAddWhenUnstale: 'test'
|
||||||
};
|
};
|
||||||
const TestIssueList: Issue[] = [
|
const TestIssueList: Issue[] = [
|
||||||
|
@ -1299,8 +1299,37 @@ test('when the option "labelsToAddWhenUnstale" is set, the labels should be adde
|
||||||
expect(processor.addedLabelIssues).toHaveLength(1);
|
expect(processor.addedLabelIssues).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
test('stale label should not be removed if a comment was added by the bot (and the issue should be closed)', async () => {
|
test('stale label should be removed if a stale issue was updated', async () => {
|
||||||
const opts = {...DefaultProcessorOptions, removeStaleWhenUpdated: true};
|
const opts = {...DefaultProcessorOptions, removeStaleWhenUpdated: true};
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(
|
||||||
|
opts,
|
||||||
|
1,
|
||||||
|
'An issue that should un-stale',
|
||||||
|
new Date().toDateString(),
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
false,
|
||||||
|
['Stale']
|
||||||
|
)
|
||||||
|
];
|
||||||
|
const processor = new IssuesProcessorMock(
|
||||||
|
opts,
|
||||||
|
async () => 'abot',
|
||||||
|
async p => (p === 1 ? TestIssueList : []),
|
||||||
|
async () => [],
|
||||||
|
async () => '2020-01-02T17:00:00Z'
|
||||||
|
);
|
||||||
|
|
||||||
|
// process our fake issue list
|
||||||
|
await processor.processIssues(1);
|
||||||
|
|
||||||
|
expect(processor.closedIssues).toHaveLength(0);
|
||||||
|
expect(processor.staleIssues).toHaveLength(0);
|
||||||
|
expect(processor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('stale label should not be removed if a comment was added by the bot (and the issue should be closed)', async () => {
|
||||||
|
const opts = {...DefaultProcessorOptions, removeStaleWhenCommented: true};
|
||||||
github.context.actor = 'abot';
|
github.context.actor = 'abot';
|
||||||
const TestIssueList: Issue[] = [
|
const TestIssueList: Issue[] = [
|
||||||
generateIssue(
|
generateIssue(
|
||||||
|
@ -1339,7 +1368,7 @@ test('stale label should not be removed if a comment was added by the bot (and t
|
||||||
test('stale label containing a space should be removed if a comment was added to a stale issue', async () => {
|
test('stale label containing a space should be removed if a comment was added to a stale issue', async () => {
|
||||||
const opts: IIssuesProcessorOptions = {
|
const opts: IIssuesProcessorOptions = {
|
||||||
...DefaultProcessorOptions,
|
...DefaultProcessorOptions,
|
||||||
removeStaleWhenUpdated: true,
|
removeStaleWhenCommented: true,
|
||||||
staleIssueLabel: 'stat: stale'
|
staleIssueLabel: 'stat: stale'
|
||||||
};
|
};
|
||||||
const TestIssueList: Issue[] = [
|
const TestIssueList: Issue[] = [
|
||||||
|
@ -2278,7 +2307,7 @@ test('processing an issue stale since less than the daysBeforeStale with a stale
|
||||||
daysBeforeStale: 30,
|
daysBeforeStale: 30,
|
||||||
daysBeforeClose: 7,
|
daysBeforeClose: 7,
|
||||||
closeIssueMessage: 'close message',
|
closeIssueMessage: 'close message',
|
||||||
removeStaleWhenUpdated: false
|
removeStaleWhenCommented: false
|
||||||
};
|
};
|
||||||
const now: Date = new Date();
|
const now: Date = new Date();
|
||||||
const updatedAt: Date = new Date(now.setDate(now.getDate() - 9));
|
const updatedAt: Date = new Date(now.setDate(now.getDate() - 9));
|
||||||
|
@ -2320,7 +2349,7 @@ test('processing an issue stale since less than the daysBeforeStale without a st
|
||||||
daysBeforeStale: 30,
|
daysBeforeStale: 30,
|
||||||
daysBeforeClose: 7,
|
daysBeforeClose: 7,
|
||||||
closeIssueMessage: 'close message',
|
closeIssueMessage: 'close message',
|
||||||
removeStaleWhenUpdated: false
|
removeStaleWhenCommented: false
|
||||||
};
|
};
|
||||||
const now: Date = new Date();
|
const now: Date = new Date();
|
||||||
const updatedAt: Date = new Date(now.setDate(now.getDate() - 9));
|
const updatedAt: Date = new Date(now.setDate(now.getDate() - 9));
|
||||||
|
|
|
@ -0,0 +1,556 @@
|
||||||
|
import {Issue} from '../src/classes/issue';
|
||||||
|
import {IIssue} from '../src/interfaces/issue';
|
||||||
|
import {IIssuesProcessorOptions} from '../src/interfaces/issues-processor-options';
|
||||||
|
import {ILabel} from '../src/interfaces/label';
|
||||||
|
import {IssuesProcessorMock} from './classes/issues-processor-mock';
|
||||||
|
import {DefaultProcessorOptions} from './constants/default-processor-options';
|
||||||
|
import {generateIssue} from './functions/generate-issue';
|
||||||
|
|
||||||
|
let issuesProcessorBuilder: IssuesProcessorBuilder;
|
||||||
|
let issuesProcessor: IssuesProcessorMock;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @description
|
||||||
|
* Assuming there is a comment on the issue
|
||||||
|
*/
|
||||||
|
describe('remove-stale-when-commented option', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder = new IssuesProcessorBuilder();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-stale-when-commented" is disabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.keepStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-stale-when-commented" is enabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.removeStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('remove-issue-stale-when-commented option', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder = new IssuesProcessorBuilder();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-stale-when-commented" is disabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.keepStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-issue-stale-when-commented" is unset', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.unsetIssueStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-issue-stale-when-commented" is disabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.keepIssueStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-issue-stale-when-commented" is enabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.removeIssueStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-stale-when-commented" is enabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.removeStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-issue-stale-when-commented" is unset', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.unsetIssueStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-issue-stale-when-commented" is disabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.keepIssueStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-issue-stale-when-commented" is enabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.removeIssueStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('remove-pr-stale-when-commented option', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder = new IssuesProcessorBuilder();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-stale-when-commented" is disabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.keepStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-pr-stale-when-commented" is unset', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.unsetPrStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-pr-stale-when-commented" is disabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.keepPrStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-pr-stale-when-commented" is enabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.removePrStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-stale-when-commented" is enabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.removeStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-pr-stale-when-commented" is unset', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.unsetPrStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-pr-stale-when-commented" is disabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.keepPrStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should not remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(0);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
describe('when the option "remove-pr-stale-when-commented" is enabled', (): void => {
|
||||||
|
beforeEach((): void => {
|
||||||
|
issuesProcessorBuilder.removePrStaleWhenCommented();
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the issue', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.staleIssues([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should remove the stale label on the pull request', async (): Promise<void> => {
|
||||||
|
expect.assertions(1);
|
||||||
|
issuesProcessor = issuesProcessorBuilder.stalePrs([{}]).build();
|
||||||
|
|
||||||
|
await issuesProcessor.processIssues();
|
||||||
|
|
||||||
|
expect(issuesProcessor.removedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
class IssuesProcessorBuilder {
|
||||||
|
private _options: IIssuesProcessorOptions = {
|
||||||
|
...DefaultProcessorOptions
|
||||||
|
};
|
||||||
|
private _issues: Issue[] = [];
|
||||||
|
|
||||||
|
keepStaleWhenCommented(): IssuesProcessorBuilder {
|
||||||
|
this._options.removeStaleWhenCommented = false;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeStaleWhenCommented(): IssuesProcessorBuilder {
|
||||||
|
this._options.removeStaleWhenCommented = true;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsetIssueStaleWhenCommented(): IssuesProcessorBuilder {
|
||||||
|
delete this._options.removeIssueStaleWhenCommented;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
keepIssueStaleWhenCommented(): IssuesProcessorBuilder {
|
||||||
|
this._options.removeIssueStaleWhenCommented = false;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
removeIssueStaleWhenCommented(): IssuesProcessorBuilder {
|
||||||
|
this._options.removeIssueStaleWhenCommented = true;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
unsetPrStaleWhenCommented(): IssuesProcessorBuilder {
|
||||||
|
delete this._options.removePrStaleWhenCommented;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
keepPrStaleWhenCommented(): IssuesProcessorBuilder {
|
||||||
|
this._options.removePrStaleWhenCommented = false;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
removePrStaleWhenCommented(): IssuesProcessorBuilder {
|
||||||
|
this._options.removePrStaleWhenCommented = true;
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
issuesOrPrs(issues: Partial<IIssue>[]): IssuesProcessorBuilder {
|
||||||
|
this._issues = issues.map(
|
||||||
|
(issue: Readonly<Partial<IIssue>>, index: Readonly<number>): Issue =>
|
||||||
|
generateIssue(
|
||||||
|
this._options,
|
||||||
|
index,
|
||||||
|
issue.title ?? 'dummy-title',
|
||||||
|
issue.updated_at ?? new Date().toDateString(),
|
||||||
|
issue.created_at ?? new Date().toDateString(),
|
||||||
|
!!issue.pull_request,
|
||||||
|
issue.labels ? issue.labels.map(label => label.name) : []
|
||||||
|
)
|
||||||
|
);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
issues(issues: Partial<IIssue>[]): IssuesProcessorBuilder {
|
||||||
|
this.issuesOrPrs(
|
||||||
|
issues.map((issue: Readonly<Partial<IIssue>>): Partial<IIssue> => {
|
||||||
|
return {
|
||||||
|
...issue,
|
||||||
|
pull_request: null
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
staleIssues(issues: Partial<IIssue>[]): IssuesProcessorBuilder {
|
||||||
|
this.issues(
|
||||||
|
issues.map((issue: Readonly<Partial<IIssue>>): Partial<IIssue> => {
|
||||||
|
return {
|
||||||
|
...issue,
|
||||||
|
updated_at: '2020-01-01T17:00:00Z',
|
||||||
|
created_at: '2020-01-01T17:00:00Z',
|
||||||
|
labels: issue.labels?.map((label: Readonly<ILabel>): ILabel => {
|
||||||
|
return {
|
||||||
|
...label,
|
||||||
|
name: 'Stale'
|
||||||
|
};
|
||||||
|
}) ?? [
|
||||||
|
{
|
||||||
|
name: 'Stale'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
prs(issues: Partial<IIssue>[]): IssuesProcessorBuilder {
|
||||||
|
this.issuesOrPrs(
|
||||||
|
issues.map((issue: Readonly<Partial<IIssue>>): Partial<IIssue> => {
|
||||||
|
return {
|
||||||
|
...issue,
|
||||||
|
pull_request: {key: 'value'}
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
stalePrs(issues: Partial<IIssue>[]): IssuesProcessorBuilder {
|
||||||
|
this.prs(
|
||||||
|
issues.map((issue: Readonly<Partial<IIssue>>): Partial<IIssue> => {
|
||||||
|
return {
|
||||||
|
...issue,
|
||||||
|
updated_at: '2020-01-01T17:00:00Z',
|
||||||
|
created_at: '2020-01-01T17:00:00Z',
|
||||||
|
labels: issue.labels?.map((label: Readonly<ILabel>): ILabel => {
|
||||||
|
return {
|
||||||
|
...label,
|
||||||
|
name: 'Stale'
|
||||||
|
};
|
||||||
|
}) ?? [
|
||||||
|
{
|
||||||
|
name: 'Stale'
|
||||||
|
}
|
||||||
|
]
|
||||||
|
};
|
||||||
|
})
|
||||||
|
);
|
||||||
|
|
||||||
|
return this;
|
||||||
|
}
|
||||||
|
|
||||||
|
build(): IssuesProcessorMock {
|
||||||
|
return new IssuesProcessorMock(
|
||||||
|
this._options,
|
||||||
|
async () => 'abot',
|
||||||
|
async p => (p === 1 ? this._issues : []),
|
||||||
|
async () => [
|
||||||
|
{
|
||||||
|
// Note this comment
|
||||||
|
user: {
|
||||||
|
login: 'notme',
|
||||||
|
type: 'User'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
|
async () => new Date().toDateString()
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
|
@ -11,7 +11,7 @@ let issuesProcessor: IssuesProcessorMock;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @description
|
* @description
|
||||||
* Assuming there is a comment on the issue
|
* Assuming there is an update on the issue
|
||||||
*/
|
*/
|
||||||
describe('remove-stale-when-updated option', (): void => {
|
describe('remove-stale-when-updated option', (): void => {
|
||||||
beforeEach((): void => {
|
beforeEach((): void => {
|
||||||
|
@ -480,8 +480,9 @@ class IssuesProcessorBuilder {
|
||||||
issues.map((issue: Readonly<Partial<IIssue>>): Partial<IIssue> => {
|
issues.map((issue: Readonly<Partial<IIssue>>): Partial<IIssue> => {
|
||||||
return {
|
return {
|
||||||
...issue,
|
...issue,
|
||||||
updated_at: '2020-01-01T17:00:00Z',
|
// Note this update
|
||||||
created_at: '2020-01-01T17:00:00Z',
|
updated_at: new Date().toDateString(),
|
||||||
|
created_at: new Date().toDateString(),
|
||||||
labels: issue.labels?.map((label: Readonly<ILabel>): ILabel => {
|
labels: issue.labels?.map((label: Readonly<ILabel>): ILabel => {
|
||||||
return {
|
return {
|
||||||
...label,
|
...label,
|
||||||
|
@ -517,8 +518,9 @@ class IssuesProcessorBuilder {
|
||||||
issues.map((issue: Readonly<Partial<IIssue>>): Partial<IIssue> => {
|
issues.map((issue: Readonly<Partial<IIssue>>): Partial<IIssue> => {
|
||||||
return {
|
return {
|
||||||
...issue,
|
...issue,
|
||||||
updated_at: '2020-01-01T17:00:00Z',
|
// Note this update
|
||||||
created_at: '2020-01-01T17:00:00Z',
|
updated_at: new Date().toDateString(),
|
||||||
|
created_at: new Date().toDateString(),
|
||||||
labels: issue.labels?.map((label: Readonly<ILabel>): ILabel => {
|
labels: issue.labels?.map((label: Readonly<ILabel>): ILabel => {
|
||||||
return {
|
return {
|
||||||
...label,
|
...label,
|
||||||
|
@ -541,14 +543,7 @@ class IssuesProcessorBuilder {
|
||||||
this._options,
|
this._options,
|
||||||
async () => 'abot',
|
async () => 'abot',
|
||||||
async p => (p === 1 ? this._issues : []),
|
async p => (p === 1 ? this._issues : []),
|
||||||
async () => [
|
async () => [],
|
||||||
{
|
|
||||||
user: {
|
|
||||||
login: 'notme',
|
|
||||||
type: 'User'
|
|
||||||
}
|
|
||||||
}
|
|
||||||
],
|
|
||||||
async () => new Date().toDateString()
|
async () => new Date().toDateString()
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
18
action.yml
18
action.yml
|
@ -113,15 +113,27 @@ inputs:
|
||||||
default: '30'
|
default: '30'
|
||||||
required: false
|
required: false
|
||||||
remove-stale-when-updated:
|
remove-stale-when-updated:
|
||||||
description: 'Remove stale labels from issues and pull requests when they are updated or commented on.'
|
description: 'Remove stale labels from issues and pull requests when they are updated.'
|
||||||
default: 'true'
|
default: 'true'
|
||||||
required: false
|
required: false
|
||||||
remove-issue-stale-when-updated:
|
remove-issue-stale-when-updated:
|
||||||
description: 'Remove stale labels from issues when they are updated or commented on. Override "remove-stale-when-updated" option regarding only the issues.'
|
description: 'Remove stale labels from issues when they are updated. Override "remove-stale-when-updated" option regarding only the issues.'
|
||||||
default: ''
|
default: ''
|
||||||
required: false
|
required: false
|
||||||
remove-pr-stale-when-updated:
|
remove-pr-stale-when-updated:
|
||||||
description: 'Remove stale labels from pull requests when they are updated or commented on. Override "remove-stale-when-updated" option regarding only the pull requests.'
|
description: 'Remove stale labels from pull requests when they are updated. Override "remove-stale-when-updated" option regarding only the pull requests.'
|
||||||
|
default: ''
|
||||||
|
required: false
|
||||||
|
remove-stale-when-commented:
|
||||||
|
description: 'Remove stale labels from issues and pull requests when they are commented on.'
|
||||||
|
default: 'true'
|
||||||
|
required: false
|
||||||
|
remove-issue-stale-when-commented:
|
||||||
|
description: 'Remove stale labels from issues when they are commented on. Override "remove-stale-when-commented" option regarding only the issues.'
|
||||||
|
default: ''
|
||||||
|
required: false
|
||||||
|
remove-pr-stale-when-commented:
|
||||||
|
description: 'Remove stale labels from pull requests when they are commented on. Override "remove-stale-when-commented" option regarding only the pull requests.'
|
||||||
default: ''
|
default: ''
|
||||||
required: false
|
required: false
|
||||||
debug-only:
|
debug-only:
|
||||||
|
|
|
@ -580,14 +580,28 @@ class IssuesProcessor {
|
||||||
const shouldRemoveStaleWhenUpdated = this._shouldRemoveStaleWhenUpdated(issue);
|
const shouldRemoveStaleWhenUpdated = this._shouldRemoveStaleWhenUpdated(issue);
|
||||||
issueLogger.info(`The option ${issueLogger.createOptionLink(this._getRemoveStaleWhenUpdatedUsedOptionName(issue))} is: ${logger_service_1.LoggerService.cyan(shouldRemoveStaleWhenUpdated)}`);
|
issueLogger.info(`The option ${issueLogger.createOptionLink(this._getRemoveStaleWhenUpdatedUsedOptionName(issue))} is: ${logger_service_1.LoggerService.cyan(shouldRemoveStaleWhenUpdated)}`);
|
||||||
if (shouldRemoveStaleWhenUpdated) {
|
if (shouldRemoveStaleWhenUpdated) {
|
||||||
issueLogger.info(`The stale label should not be removed`);
|
issueLogger.info(`The stale label should not be removed due to an update`);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
issueLogger.info(`The stale label should be removed if all conditions met`);
|
||||||
|
}
|
||||||
|
const shouldRemoveStaleWhenCommented = this._shouldRemoveStaleWhenCommented(issue);
|
||||||
|
issueLogger.info(`The option ${issueLogger.createOptionLink(this._getRemoveStaleWhenCommentedUsedOptionName(issue))} is: ${logger_service_1.LoggerService.cyan(shouldRemoveStaleWhenCommented)}`);
|
||||||
|
if (shouldRemoveStaleWhenCommented) {
|
||||||
|
issueLogger.info(`The stale label should not be removed due to a comment`);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
issueLogger.info(`The stale label should be removed if all conditions met`);
|
issueLogger.info(`The stale label should be removed if all conditions met`);
|
||||||
}
|
}
|
||||||
// Should we un-stale this issue?
|
// Should we un-stale this issue?
|
||||||
if (shouldRemoveStaleWhenUpdated && issueHasComments) {
|
if (shouldRemoveStaleWhenUpdated && issueHasUpdate) {
|
||||||
issueLogger.info(`Remove the stale label since the $$type has a comment and the workflow should remove the stale label when updated`);
|
issueLogger.info(`Remove the stale label since the $$type has an update and the workflow should remove the stale label when updated`);
|
||||||
|
yield this._removeStaleLabel(issue, staleLabel);
|
||||||
|
issueLogger.info(`Skipping the process since the $$type is now un-stale`);
|
||||||
|
return; // Nothing to do because it is no longer stale
|
||||||
|
}
|
||||||
|
else if (shouldRemoveStaleWhenCommented && issueHasComments) {
|
||||||
|
issueLogger.info(`Remove the stale label since the $$type has a comment and the workflow should remove the stale label when commented`);
|
||||||
yield this._removeStaleLabel(issue, staleLabel);
|
yield this._removeStaleLabel(issue, staleLabel);
|
||||||
// Are there labels to remove or add when an issue is no longer stale?
|
// Are there labels to remove or add when an issue is no longer stale?
|
||||||
yield this._removeLabelsWhenUnstale(issue, labelsToRemoveWhenUnstale);
|
yield this._removeLabelsWhenUnstale(issue, labelsToRemoveWhenUnstale);
|
||||||
|
@ -902,6 +916,18 @@ class IssuesProcessor {
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
_shouldRemoveStaleWhenCommented(issue) {
|
||||||
|
if (issue.isPullRequest) {
|
||||||
|
if (is_boolean_1.isBoolean(this.options.removePrStaleWhenCommented)) {
|
||||||
|
return this.options.removePrStaleWhenCommented;
|
||||||
|
}
|
||||||
|
return this.options.removeStaleWhenCommented;
|
||||||
|
}
|
||||||
|
if (is_boolean_1.isBoolean(this.options.removeIssueStaleWhenCommented)) {
|
||||||
|
return this.options.removeIssueStaleWhenCommented;
|
||||||
|
}
|
||||||
|
return this.options.removeStaleWhenCommented;
|
||||||
|
}
|
||||||
_removeStaleLabel(issue, staleLabel) {
|
_removeStaleLabel(issue, staleLabel) {
|
||||||
var _a;
|
var _a;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
@ -963,6 +989,18 @@ class IssuesProcessor {
|
||||||
}
|
}
|
||||||
return option_1.Option.RemoveStaleWhenUpdated;
|
return option_1.Option.RemoveStaleWhenUpdated;
|
||||||
}
|
}
|
||||||
|
_getRemoveStaleWhenCommentedUsedOptionName(issue) {
|
||||||
|
if (issue.isPullRequest) {
|
||||||
|
if (is_boolean_1.isBoolean(this.options.removePrStaleWhenCommented)) {
|
||||||
|
return option_1.Option.RemovePrStaleWhenCommented;
|
||||||
|
}
|
||||||
|
return option_1.Option.RemoveStaleWhenCommented;
|
||||||
|
}
|
||||||
|
if (is_boolean_1.isBoolean(this.options.removeIssueStaleWhenCommented)) {
|
||||||
|
return option_1.Option.RemoveIssueStaleWhenCommented;
|
||||||
|
}
|
||||||
|
return option_1.Option.RemoveStaleWhenCommented;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
exports.IssuesProcessor = IssuesProcessor;
|
exports.IssuesProcessor = IssuesProcessor;
|
||||||
|
|
||||||
|
@ -1723,6 +1761,9 @@ var Option;
|
||||||
Option["RemoveStaleWhenUpdated"] = "remove-stale-when-updated";
|
Option["RemoveStaleWhenUpdated"] = "remove-stale-when-updated";
|
||||||
Option["RemoveIssueStaleWhenUpdated"] = "remove-issue-stale-when-updated";
|
Option["RemoveIssueStaleWhenUpdated"] = "remove-issue-stale-when-updated";
|
||||||
Option["RemovePrStaleWhenUpdated"] = "remove-pr-stale-when-updated";
|
Option["RemovePrStaleWhenUpdated"] = "remove-pr-stale-when-updated";
|
||||||
|
Option["RemoveStaleWhenCommented"] = "remove-stale-when-commented";
|
||||||
|
Option["RemoveIssueStaleWhenCommented"] = "remove-issue-stale-when-commented";
|
||||||
|
Option["RemovePrStaleWhenCommented"] = "remove-pr-stale-when-commented";
|
||||||
Option["DebugOnly"] = "debug-only";
|
Option["DebugOnly"] = "debug-only";
|
||||||
Option["Ascending"] = "ascending";
|
Option["Ascending"] = "ascending";
|
||||||
Option["DeleteBranch"] = "delete-branch";
|
Option["DeleteBranch"] = "delete-branch";
|
||||||
|
@ -2007,6 +2048,9 @@ function _getAndValidateArgs() {
|
||||||
removeStaleWhenUpdated: !(core.getInput('remove-stale-when-updated') === 'false'),
|
removeStaleWhenUpdated: !(core.getInput('remove-stale-when-updated') === 'false'),
|
||||||
removeIssueStaleWhenUpdated: _toOptionalBoolean(core.getInput('remove-issue-stale-when-updated')),
|
removeIssueStaleWhenUpdated: _toOptionalBoolean(core.getInput('remove-issue-stale-when-updated')),
|
||||||
removePrStaleWhenUpdated: _toOptionalBoolean(core.getInput('remove-pr-stale-when-updated')),
|
removePrStaleWhenUpdated: _toOptionalBoolean(core.getInput('remove-pr-stale-when-updated')),
|
||||||
|
removeStaleWhenCommented: !(core.getInput('remove-stale-when-commented') === 'false'),
|
||||||
|
removeIssueStaleWhenCommented: _toOptionalBoolean(core.getInput('remove-issue-stale-when-commented')),
|
||||||
|
removePrStaleWhenCommented: _toOptionalBoolean(core.getInput('remove-pr-stale-when-commented')),
|
||||||
debugOnly: core.getInput('debug-only') === 'true',
|
debugOnly: core.getInput('debug-only') === 'true',
|
||||||
ascending: core.getInput('ascending') === 'true',
|
ascending: core.getInput('ascending') === 'true',
|
||||||
deleteBranch: core.getInput('delete-branch') === 'true',
|
deleteBranch: core.getInput('delete-branch') === 'true',
|
||||||
|
|
|
@ -37,6 +37,9 @@ describe('Issue', (): void => {
|
||||||
removeStaleWhenUpdated: false,
|
removeStaleWhenUpdated: false,
|
||||||
removeIssueStaleWhenUpdated: undefined,
|
removeIssueStaleWhenUpdated: undefined,
|
||||||
removePrStaleWhenUpdated: undefined,
|
removePrStaleWhenUpdated: undefined,
|
||||||
|
removeStaleWhenCommented: false,
|
||||||
|
removeIssueStaleWhenCommented: undefined,
|
||||||
|
removePrStaleWhenCommented: undefined,
|
||||||
repoToken: '',
|
repoToken: '',
|
||||||
staleIssueMessage: '',
|
staleIssueMessage: '',
|
||||||
stalePrMessage: '',
|
stalePrMessage: '',
|
||||||
|
|
|
@ -616,7 +616,28 @@ export class IssuesProcessor {
|
||||||
);
|
);
|
||||||
|
|
||||||
if (shouldRemoveStaleWhenUpdated) {
|
if (shouldRemoveStaleWhenUpdated) {
|
||||||
issueLogger.info(`The stale label should not be removed`);
|
issueLogger.info(
|
||||||
|
`The stale label should not be removed due to an update`
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
issueLogger.info(
|
||||||
|
`The stale label should be removed if all conditions met`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
const shouldRemoveStaleWhenCommented: boolean =
|
||||||
|
this._shouldRemoveStaleWhenCommented(issue);
|
||||||
|
|
||||||
|
issueLogger.info(
|
||||||
|
`The option ${issueLogger.createOptionLink(
|
||||||
|
this._getRemoveStaleWhenCommentedUsedOptionName(issue)
|
||||||
|
)} is: ${LoggerService.cyan(shouldRemoveStaleWhenCommented)}`
|
||||||
|
);
|
||||||
|
|
||||||
|
if (shouldRemoveStaleWhenCommented) {
|
||||||
|
issueLogger.info(
|
||||||
|
`The stale label should not be removed due to a comment`
|
||||||
|
);
|
||||||
} else {
|
} else {
|
||||||
issueLogger.info(
|
issueLogger.info(
|
||||||
`The stale label should be removed if all conditions met`
|
`The stale label should be removed if all conditions met`
|
||||||
|
@ -624,9 +645,18 @@ export class IssuesProcessor {
|
||||||
}
|
}
|
||||||
|
|
||||||
// Should we un-stale this issue?
|
// Should we un-stale this issue?
|
||||||
if (shouldRemoveStaleWhenUpdated && issueHasComments) {
|
if (shouldRemoveStaleWhenUpdated && issueHasUpdate) {
|
||||||
issueLogger.info(
|
issueLogger.info(
|
||||||
`Remove the stale label since the $$type has a comment and the workflow should remove the stale label when updated`
|
`Remove the stale label since the $$type has an update and the workflow should remove the stale label when updated`
|
||||||
|
);
|
||||||
|
await this._removeStaleLabel(issue, staleLabel);
|
||||||
|
|
||||||
|
issueLogger.info(`Skipping the process since the $$type is now un-stale`);
|
||||||
|
|
||||||
|
return; // Nothing to do because it is no longer stale
|
||||||
|
} else if (shouldRemoveStaleWhenCommented && issueHasComments) {
|
||||||
|
issueLogger.info(
|
||||||
|
`Remove the stale label since the $$type has a comment and the workflow should remove the stale label when commented`
|
||||||
);
|
);
|
||||||
await this._removeStaleLabel(issue, staleLabel);
|
await this._removeStaleLabel(issue, staleLabel);
|
||||||
|
|
||||||
|
@ -1046,6 +1076,22 @@ export class IssuesProcessor {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _shouldRemoveStaleWhenCommented(issue: Issue): boolean {
|
||||||
|
if (issue.isPullRequest) {
|
||||||
|
if (isBoolean(this.options.removePrStaleWhenCommented)) {
|
||||||
|
return this.options.removePrStaleWhenCommented;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.options.removeStaleWhenCommented;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBoolean(this.options.removeIssueStaleWhenCommented)) {
|
||||||
|
return this.options.removeIssueStaleWhenCommented;
|
||||||
|
}
|
||||||
|
|
||||||
|
return this.options.removeStaleWhenCommented;
|
||||||
|
}
|
||||||
|
|
||||||
private async _removeStaleLabel(
|
private async _removeStaleLabel(
|
||||||
issue: Issue,
|
issue: Issue,
|
||||||
staleLabel: Readonly<string>
|
staleLabel: Readonly<string>
|
||||||
|
@ -1157,4 +1203,25 @@ export class IssuesProcessor {
|
||||||
|
|
||||||
return Option.RemoveStaleWhenUpdated;
|
return Option.RemoveStaleWhenUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private _getRemoveStaleWhenCommentedUsedOptionName(
|
||||||
|
issue: Readonly<Issue>
|
||||||
|
):
|
||||||
|
| Option.RemovePrStaleWhenCommented
|
||||||
|
| Option.RemoveStaleWhenCommented
|
||||||
|
| Option.RemoveIssueStaleWhenCommented {
|
||||||
|
if (issue.isPullRequest) {
|
||||||
|
if (isBoolean(this.options.removePrStaleWhenCommented)) {
|
||||||
|
return Option.RemovePrStaleWhenCommented;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Option.RemoveStaleWhenCommented;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBoolean(this.options.removeIssueStaleWhenCommented)) {
|
||||||
|
return Option.RemoveIssueStaleWhenCommented;
|
||||||
|
}
|
||||||
|
|
||||||
|
return Option.RemoveStaleWhenCommented;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,9 @@ export enum Option {
|
||||||
RemoveStaleWhenUpdated = 'remove-stale-when-updated',
|
RemoveStaleWhenUpdated = 'remove-stale-when-updated',
|
||||||
RemoveIssueStaleWhenUpdated = 'remove-issue-stale-when-updated',
|
RemoveIssueStaleWhenUpdated = 'remove-issue-stale-when-updated',
|
||||||
RemovePrStaleWhenUpdated = 'remove-pr-stale-when-updated',
|
RemovePrStaleWhenUpdated = 'remove-pr-stale-when-updated',
|
||||||
|
RemoveStaleWhenCommented = 'remove-stale-when-commented',
|
||||||
|
RemoveIssueStaleWhenCommented = 'remove-issue-stale-when-commented',
|
||||||
|
RemovePrStaleWhenCommented = 'remove-pr-stale-when-commented',
|
||||||
DebugOnly = 'debug-only',
|
DebugOnly = 'debug-only',
|
||||||
Ascending = 'ascending',
|
Ascending = 'ascending',
|
||||||
DeleteBranch = 'delete-branch',
|
DeleteBranch = 'delete-branch',
|
||||||
|
|
|
@ -28,6 +28,9 @@ export interface IIssuesProcessorOptions {
|
||||||
removeStaleWhenUpdated: boolean;
|
removeStaleWhenUpdated: boolean;
|
||||||
removeIssueStaleWhenUpdated: boolean | undefined;
|
removeIssueStaleWhenUpdated: boolean | undefined;
|
||||||
removePrStaleWhenUpdated: boolean | undefined;
|
removePrStaleWhenUpdated: boolean | undefined;
|
||||||
|
removeStaleWhenCommented: boolean;
|
||||||
|
removeIssueStaleWhenCommented: boolean | undefined;
|
||||||
|
removePrStaleWhenCommented: boolean | undefined;
|
||||||
debugOnly: boolean;
|
debugOnly: boolean;
|
||||||
ascending: boolean;
|
ascending: boolean;
|
||||||
deleteBranch: boolean;
|
deleteBranch: boolean;
|
||||||
|
|
|
@ -62,6 +62,15 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
|
||||||
removePrStaleWhenUpdated: _toOptionalBoolean(
|
removePrStaleWhenUpdated: _toOptionalBoolean(
|
||||||
core.getInput('remove-pr-stale-when-updated')
|
core.getInput('remove-pr-stale-when-updated')
|
||||||
),
|
),
|
||||||
|
removeStaleWhenCommented: !(
|
||||||
|
core.getInput('remove-stale-when-commented') === 'false'
|
||||||
|
),
|
||||||
|
removeIssueStaleWhenCommented: _toOptionalBoolean(
|
||||||
|
core.getInput('remove-issue-stale-when-commented')
|
||||||
|
),
|
||||||
|
removePrStaleWhenCommented: _toOptionalBoolean(
|
||||||
|
core.getInput('remove-pr-stale-when-commented')
|
||||||
|
),
|
||||||
debugOnly: core.getInput('debug-only') === 'true',
|
debugOnly: core.getInput('debug-only') === 'true',
|
||||||
ascending: core.getInput('ascending') === 'true',
|
ascending: core.getInput('ascending') === 'true',
|
||||||
deleteBranch: core.getInput('delete-branch') === 'true',
|
deleteBranch: core.getInput('delete-branch') === 'true',
|
||||||
|
|
Loading…
Reference in New Issue