diff --git a/README.md b/README.md
index 53ac224a..839afb10 100644
--- a/README.md
+++ b/README.md
@@ -8,50 +8,52 @@ Warns and then closes issues and PRs that have had no activity for a specified a
Every argument is optional.
-| Input | Description |
-| ----------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
-| `repo-token` | PAT(Personal Access Token) for authorizing repository.
_Defaults to **${{ github.token }}**_. |
-| `days-before-stale` | Idle number of days before marking an issue/PR as stale.
_Defaults to **60**_. |
-| `days-before-issue-stale` | Idle number of days before marking an issue as stale.
_Override `days-before-stale`_. |
-| `days-before-pr-stale` | Idle number of days before marking an PR as stale.
_Override `days-before-stale`_. |
-| `days-before-close` | Idle number of days before closing an stale issue/PR.
_Defaults to **7**_. |
-| `days-before-issue-close` | Idle number of days before closing an stale issue.
_Override `days-before-close`_. |
-| `days-before-pr-close` | Idle number of days before closing an stale PR.
_Override `days-before-close`_. |
-| `stale-issue-message` | Message to post on the stale issue. |
-| `stale-pr-message` | Message to post on the stale PR. |
-| `close-issue-message` | Message to post on the stale issue while closing it. |
-| `close-pr-message` | Message to post on the stale PR while closing it. |
-| `stale-issue-label` | Label to apply on the stale issue.
_Defaults to **Stale**_. |
-| `close-issue-label` | Label to apply on closing issue.
Automatically removed if no longer closed nor locked). |
-| `stale-pr-label` | Label to apply on the stale PR.
_Defaults to **Stale**_. |
-| `close-pr-label` | Label to apply on the closing PR.
Automatically removed if no longer closed nor locked). |
-| `exempt-issue-labels` | Labels on an issue exempted from being marked as stale. |
-| `exempt-pr-labels` | Labels on the PR exempted from being marked as stale. |
-| `only-labels` | Only issues and PRs with ALL these labels are checked.
Separate multiple labels with commas (eg. "question,answered"). |
-| `only-issue-labels` | Only issues with ALL these labels are checked.
Separate multiple labels with commas (eg. "question,answered").
_Override `only-labels`_. |
-| `only-pr-labels` | Only PRs with ALL these labels are checked.
Separate multiple labels with commas (eg. "question,answered").
_Override `only-labels`_. |
-| `any-of-labels` | Only issues and PRs with ANY of these labels are checked.
Separate multiple labels with commas (eg. "incomplete,waiting-feedback"). |
-| `operations-per-run` | Maximum number of operations per run.
GitHub API CRUD related.
_Defaults to **30**_. |
-| `remove-stale-when-updated` | Remove stale label from issue/PR on updates or comments.
_Defaults to **true**_. |
-| `debug-only` | Dry-run on action.
_Defaults to **false**_. |
-| `ascending` | Order to get issues/PR.
`true` is ascending, `false` is descending.
_Defaults to **false**_. |
-| `skip-stale-issue-message` | Skip adding stale message on stale issue.
_Defaults to **false**_. |
-| `skip-stale-pr-message` | Skip adding stale message on stale PR.
_Defaults to **false**_. |
-| `start-date` | The date used to skip the stale action on issue/PR created before it.
ISO 8601 or RFC 2822. |
-| `delete-branch` | Delete the git branch after closing a stale pull request.
_Defaults to **false**_. |
-| `exempt-milestones` | Milestones on an issue or a PR exempted from being marked as stale. |
-| `exempt-issue-milestones` | Milestones on an issue exempted from being marked as stale.
_Override `exempt-milestones`_. |
-| `exempt-pr-milestones` | Milestones on the PR exempted from being marked as stale.
_Override `exempt-milestones`_. |
-| `exempt-all-milestones` | Exempt all issues and PRs with milestones from being marked as stale.
_Priority over `exempt-milestones` rules_. |
-| `exempt-all-issue-milestones` | Exempt all issues with milestones from being marked as stale.
_Override `exempt-all-milestones`_. |
-| `exempt-all-pr-milestones` | Exempt all PRs with milestones from being marked as stale.
_Override `exempt-all-milestones`_. |
-| `exempt-assignees` | Assignees on an issue or a PR exempted from being marked as stale. |
-| `exempt-issue-assignees` | Assignees on an issue exempted from being marked as stale.
_Override `exempt-assignees`_. |
-| `exempt-pr-assignees` | Assignees on the PR exempted from being marked as stale.
_Override `exempt-assignees`_. |
-| `exempt-all-assignees` | Exempt all issues and PRs with assignees from being marked as stale.
_Priority over `exempt-assignees` rules_. |
-| `exempt-all-issue-assignees` | Exempt all issues with assignees from being marked as stale.
_Override `exempt-all-assignees`_. |
-| `exempt-all-pr-assignees` | Exempt all PRs with assignees from being marked as stale.
_Override `exempt-all-assignees`_. |
-| `enable-statistics` | Display some statistics at the end of the logs regarding the stale workflow.
Only when the logs are enabled.
_Defaults to **true**_. |
+| Input | Description |
+| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- |
+| `repo-token` | PAT(Personal Access Token) for authorizing repository.
_Defaults to **${{ github.token }}**_. |
+| `days-before-stale` | Idle number of days before marking an issue/PR as stale.
_Defaults to **60**_. |
+| `days-before-issue-stale` | Idle number of days before marking an issue as stale.
_Override `days-before-stale`_. |
+| `days-before-pr-stale` | Idle number of days before marking an PR as stale.
_Override `days-before-stale`_. |
+| `days-before-close` | Idle number of days before closing an stale issue/PR.
_Defaults to **7**_. |
+| `days-before-issue-close` | Idle number of days before closing an stale issue.
_Override `days-before-close`_. |
+| `days-before-pr-close` | Idle number of days before closing an stale PR.
_Override `days-before-close`_. |
+| `stale-issue-message` | Message to post on the stale issue. |
+| `stale-pr-message` | Message to post on the stale PR. |
+| `close-issue-message` | Message to post on the stale issue while closing it. |
+| `close-pr-message` | Message to post on the stale PR while closing it. |
+| `stale-issue-label` | Label to apply on the stale issue.
_Defaults to **Stale**_. |
+| `close-issue-label` | Label to apply on closing issue.
Automatically removed if no longer closed nor locked). |
+| `stale-pr-label` | Label to apply on the stale PR.
_Defaults to **Stale**_. |
+| `close-pr-label` | Label to apply on the closing PR.
Automatically removed if no longer closed nor locked). |
+| `exempt-issue-labels` | Labels on an issue exempted from being marked as stale. |
+| `exempt-pr-labels` | Labels on the PR exempted from being marked as stale. |
+| `only-labels` | Only issues and PRs with ALL these labels are checked.
Separate multiple labels with commas (eg. "question,answered"). |
+| `only-issue-labels` | Only issues with ALL these labels are checked.
Separate multiple labels with commas (eg. "question,answered").
_Override `only-labels`_. |
+| `only-pr-labels` | Only PRs with ALL these labels are checked.
Separate multiple labels with commas (eg. "question,answered").
_Override `only-labels`_. |
+| `any-of-labels` | Only issues and PRs with ANY of these labels are checked.
Separate multiple labels with commas (eg. "incomplete,waiting-feedback"). |
+| `any-of-issue-labels` | Only issues with ANY of these labels are checked.
Separate multiple labels with commas (eg. "incomplete,waiting-feedback").
_Override `any-of-labels`_. |
+| `any-of-pr-labels` | Only PRs with ANY of these labels are checked.
Separate multiple labels with commas (eg. "incomplete,waiting-feedback").
_Override `any-of-labels`_. |
+| `operations-per-run` | Maximum number of operations per run.
GitHub API CRUD related.
_Defaults to **30**_. |
+| `remove-stale-when-updated` | Remove stale label from issue/PR on updates or comments.
_Defaults to **true**_. |
+| `debug-only` | Dry-run on action.
_Defaults to **false**_. |
+| `ascending` | Order to get issues/PR.
`true` is ascending, `false` is descending.
_Defaults to **false**_. |
+| `skip-stale-issue-message` | Skip adding stale message on stale issue.
_Defaults to **false**_. |
+| `skip-stale-pr-message` | Skip adding stale message on stale PR.
_Defaults to **false**_. |
+| `start-date` | The date used to skip the stale action on issue/PR created before it.
ISO 8601 or RFC 2822. |
+| `delete-branch` | Delete the git branch after closing a stale pull request.
_Defaults to **false**_. |
+| `exempt-milestones` | Milestones on an issue or a PR exempted from being marked as stale. |
+| `exempt-issue-milestones` | Milestones on an issue exempted from being marked as stale.
_Override `exempt-milestones`_. |
+| `exempt-pr-milestones` | Milestones on the PR exempted from being marked as stale.
_Override `exempt-milestones`_. |
+| `exempt-all-milestones` | Exempt all issues and PRs with milestones from being marked as stale.
_Priority over `exempt-milestones` rules_. |
+| `exempt-all-issue-milestones` | Exempt all issues with milestones from being marked as stale.
_Override `exempt-all-milestones`_. |
+| `exempt-all-pr-milestones` | Exempt all PRs with milestones from being marked as stale.
_Override `exempt-all-milestones`_. |
+| `exempt-assignees` | Assignees on an issue or a PR exempted from being marked as stale. |
+| `exempt-issue-assignees` | Assignees on an issue exempted from being marked as stale.
_Override `exempt-assignees`_. |
+| `exempt-pr-assignees` | Assignees on the PR exempted from being marked as stale.
_Override `exempt-assignees`_. |
+| `exempt-all-assignees` | Exempt all issues and PRs with assignees from being marked as stale.
_Priority over `exempt-assignees` rules_. |
+| `exempt-all-issue-assignees` | Exempt all issues with assignees from being marked as stale.
_Override `exempt-all-assignees`_. |
+| `exempt-all-pr-assignees` | Exempt all PRs with assignees from being marked as stale.
_Override `exempt-all-assignees`_. |
+| `enable-statistics` | Display some statistics at the end of the logs regarding the stale workflow.
Only when the logs are enabled.
_Defaults to **true**_. |
### Detailed options
@@ -244,7 +246,7 @@ jobs:
- uses: actions/stale@v3
with:
any-of-labels: 'needs-more-info,needs-demo'
- # You can opt for 'only-labels' instead if your usecase requires all labels
+ # You can opt for 'only-labels' instead if your use-case requires all labels
# to be present in the issue/PR
```
diff --git a/__tests__/any-of-labels.spec.ts b/__tests__/any-of-labels.spec.ts
index f69d1eed..cfed44bd 100644
--- a/__tests__/any-of-labels.spec.ts
+++ b/__tests__/any-of-labels.spec.ts
@@ -1,77 +1,1083 @@
import {Issue} from '../src/classes/issue';
+import {IIssue} from '../src/interfaces/issue';
import {IIssuesProcessorOptions} from '../src/interfaces/issues-processor-options';
import {IssuesProcessorMock} from './classes/issues-processor-mock';
import {DefaultProcessorOptions} from './constants/default-processor-options';
import {generateIssue} from './functions/generate-issue';
-describe('any-of-labels option', () => {
- test('should do nothing when not set', async () => {
- const sut = new IssuesProcessorBuilder()
+let issuesProcessorBuilder: IssuesProcessorBuilder;
+let issuesProcessor: IssuesProcessorMock;
+
+describe('any-of-labels option', (): void => {
+ beforeEach((): void => {
+ issuesProcessorBuilder = new IssuesProcessorBuilder();
+ });
+
+ test('should stale when not set even if the issue has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
.emptyAnyOfLabels()
- .issues([{labels: [{name: 'some-label'}]}])
+ .issuesOrPrs([{labels: []}])
.build();
- await sut.processIssues();
+ await issuesProcessor.processIssues();
- expect(sut.staleIssues).toHaveLength(1);
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
});
- test('should skip it when none of the issue labels match', async () => {
- const sut = new IssuesProcessorBuilder()
- .anyOfLabels('skip-this-issue,and-this-one')
- .issues([{labels: [{name: 'some-label'}, {name: 'some-other-label'}]}])
+ test('should stale when not set even if the issue has a label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfLabels()
+ .issuesOrPrs([{labels: [{name: 'label'}]}])
.build();
- await sut.processIssues();
+ await issuesProcessor.processIssues();
- expect(sut.staleIssues).toHaveLength(0);
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
});
- test('should skip it when the issue has no labels', async () => {
- const sut = new IssuesProcessorBuilder()
- .anyOfLabels('skip-this-issue,and-this-one')
- .issues([{labels: []}])
+ test('should not stale when set and the issue has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfLabels('dummy-label')
+ .issuesOrPrs([{labels: []}])
.build();
- await sut.processIssues();
+ await issuesProcessor.processIssues();
- expect(sut.staleIssues).toHaveLength(0);
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
});
- test('should process it when one of the issue labels match', async () => {
- const sut = new IssuesProcessorBuilder()
- .anyOfLabels('skip-this-issue,and-this-one')
- .issues([{labels: [{name: 'some-label'}, {name: 'skip-this-issue'}]}])
+ test('should not stale when set and the issue has a different label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfLabels('dummy-label')
+ .issuesOrPrs([
+ {
+ labels: [
+ {
+ name: 'label'
+ }
+ ]
+ }
+ ])
.build();
- await sut.processIssues();
+ await issuesProcessor.processIssues();
- expect(sut.staleIssues).toHaveLength(1);
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
});
- test('should process it when all the issue labels match', async () => {
- const sut = new IssuesProcessorBuilder()
- .anyOfLabels('skip-this-issue,and-this-one')
- .issues([{labels: [{name: 'and-this-one'}, {name: 'skip-this-issue'}]}])
+ test('should not stale when set and the issue has different labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfLabels('dummy-label')
+ .issuesOrPrs([
+ {
+ labels: [
+ {
+ name: 'label-1'
+ },
+ {
+ name: 'label-2'
+ }
+ ]
+ }
+ ])
.build();
- await sut.processIssues();
+ await issuesProcessor.processIssues();
- expect(sut.staleIssues).toHaveLength(1);
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should stale when set and the issue has the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfLabels('dummy-label')
+ .issuesOrPrs([
+ {
+ labels: [
+ {
+ name: 'dummy-label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the issue has only one of the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfLabels('dummy-label-1,dummy-label-2')
+ .issuesOrPrs([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the issue has all the same labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfLabels('dummy-label-1,dummy-label-2')
+ .issuesOrPrs([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ },
+ {
+ name: 'dummy-label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+});
+
+describe('any-of-issue-labels option', (): void => {
+ beforeEach((): void => {
+ issuesProcessorBuilder = new IssuesProcessorBuilder();
+ });
+
+ describe('when the any-of-labels options is not set', (): void => {
+ beforeEach((): void => {
+ issuesProcessorBuilder.emptyAnyOfLabels();
+ });
+
+ test('should stale when not set even if the issue has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfIssueLabels()
+ .issues([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when not set even if the issue has a label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfIssueLabels()
+ .issues([{labels: [{name: 'dummy-label'}]}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should not stale when set and the issue has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the issue has a different label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the issue has different labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'label-1'
+ },
+ {
+ name: 'label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should stale when set and the issue has the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'dummy-label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the issue has only one of the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label-1,dummy-label-2')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the issue has all the same labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label-1,dummy-label-2')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ },
+ {
+ name: 'dummy-label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+ });
+
+ describe('when the any-of-labels options is set (same as any-of-issue-labels)', (): void => {
+ beforeEach((): void => {
+ issuesProcessorBuilder.anyOfLabels('dummy-label');
+ });
+
+ test('should not stale when not set even if the issue has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfIssueLabels()
+ .issues([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when not set even if the issue has a label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfIssueLabels()
+ .issues([{labels: [{name: 'label'}]}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the issue has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the issue has a different label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the issue has different labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'label-1'
+ },
+ {
+ name: 'label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should stale when set and the issue has the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'dummy-label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the issue has only one of the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label-1,dummy-label-2')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the issue has all the same labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label-1,dummy-label-2')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ },
+ {
+ name: 'dummy-label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+ });
+
+ describe('when the any-of-labels options is set (different than any-of-issue-labels)', (): void => {
+ beforeEach((): void => {
+ issuesProcessorBuilder.anyOfLabels('dummy-any-of-label');
+ });
+
+ test('should not stale when not set even if the issue has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfIssueLabels()
+ .issues([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when not set even if the issue has a label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfIssueLabels()
+ .issues([{labels: [{name: 'label'}]}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the issue has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the issue has a different label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the issue has different labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'label-1'
+ },
+ {
+ name: 'label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should stale when set and the issue has the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'dummy-label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the issue has only one of the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label-1,dummy-label-2')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the issue has all the same labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfIssueLabels('dummy-label-1,dummy-label-2')
+ .issues([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ },
+ {
+ name: 'dummy-label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+ });
+});
+
+describe('any-of-pr-labels option', (): void => {
+ beforeEach((): void => {
+ issuesProcessorBuilder = new IssuesProcessorBuilder();
+ });
+
+ describe('when the any-of-labels options is not set', (): void => {
+ beforeEach((): void => {
+ issuesProcessorBuilder.emptyAnyOfLabels();
+ });
+
+ test('should stale when not set even if the pr has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfPrLabels()
+ .prs([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when not set even if the pr has a label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfPrLabels()
+ .prs([{labels: [{name: 'dummy-label'}]}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should not stale when set and the pr has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the pr has a different label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the pr has different labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'label-1'
+ },
+ {
+ name: 'label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should stale when set and the pr has the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'dummy-label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the pr has only one of the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label-1,dummy-label-2')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the pr has all the same labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label-1,dummy-label-2')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ },
+ {
+ name: 'dummy-label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+ });
+
+ describe('when the any-of-labels options is set (same as any-of-pr-labels)', (): void => {
+ beforeEach((): void => {
+ issuesProcessorBuilder.anyOfLabels('dummy-label');
+ });
+
+ test('should not stale when not set even if the pr has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfPrLabels()
+ .prs([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when not set even if the pr has a label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfPrLabels()
+ .prs([{labels: [{name: 'label'}]}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the pr has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the pr has a different label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the pr has different labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'label-1'
+ },
+ {
+ name: 'label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should stale when set and the pr has the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'dummy-label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the pr has only one of the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label-1,dummy-label-2')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the pr has all the same labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label-1,dummy-label-2')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ },
+ {
+ name: 'dummy-label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+ });
+
+ describe('when the any-of-labels options is set (different than any-of-pr-labels)', (): void => {
+ beforeEach((): void => {
+ issuesProcessorBuilder.anyOfLabels('dummy-any-of-label');
+ });
+
+ test('should not stale when not set even if the pr has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfPrLabels()
+ .prs([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when not set even if the pr has a label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .emptyAnyOfPrLabels()
+ .prs([{labels: [{name: 'label'}]}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the pr has no label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([{labels: []}])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the pr has a different label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should not stale when set and the pr has different labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'label-1'
+ },
+ {
+ name: 'label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(0);
+ });
+
+ test('should stale when set and the pr has the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'dummy-label'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the pr has only one of the same label', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label-1,dummy-label-2')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
+
+ test('should stale when set and the pr has all the same labels', async (): Promise => {
+ expect.assertions(1);
+ issuesProcessor = issuesProcessorBuilder
+ .anyOfPrLabels('dummy-label-1,dummy-label-2')
+ .prs([
+ {
+ labels: [
+ {
+ name: 'dummy-label-1'
+ },
+ {
+ name: 'dummy-label-2'
+ }
+ ]
+ }
+ ])
+ .build();
+
+ await issuesProcessor.processIssues();
+
+ expect(issuesProcessor.staleIssues).toHaveLength(1);
+ });
});
});
class IssuesProcessorBuilder {
- private _options: IIssuesProcessorOptions;
- private _issues: Issue[];
-
- constructor() {
- this._options = {...DefaultProcessorOptions};
- this._issues = [];
- }
+ private _options: IIssuesProcessorOptions = {
+ ...DefaultProcessorOptions,
+ daysBeforeStale: 0
+ };
+ private _issues: Issue[] = [];
anyOfLabels(labels: string): IssuesProcessorBuilder {
this._options.anyOfLabels = labels;
+
+ return this;
+ }
+
+ anyOfIssueLabels(labels: string): IssuesProcessorBuilder {
+ this._options.anyOfIssueLabels = labels;
+
+ return this;
+ }
+
+ anyOfPrLabels(labels: string): IssuesProcessorBuilder {
+ this._options.anyOfPrLabels = labels;
+
return this;
}
@@ -79,19 +1085,58 @@ class IssuesProcessorBuilder {
return this.anyOfLabels('');
}
- issues(issues: Partial[]): IssuesProcessorBuilder {
+ emptyAnyOfIssueLabels(): IssuesProcessorBuilder {
+ return this.anyOfIssueLabels('');
+ }
+
+ emptyAnyOfPrLabels(): IssuesProcessorBuilder {
+ return this.anyOfPrLabels('');
+ }
+
+ issuesOrPrs(issues: Partial[]): IssuesProcessorBuilder {
this._issues = issues.map(
- (issue, index): Issue =>
+ (issue: Readonly>, index: Readonly): Issue =>
generateIssue(
this._options,
index,
- issue.title || 'Issue title',
- issue.updated_at || '2000-01-01T00:00:00Z', // we only care about stale/expired issues here
- issue.created_at || '2000-01-01T00:00:00Z',
- issue.isPullRequest || false,
+ 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[]): IssuesProcessorBuilder {
+ this.issuesOrPrs(
+ issues.map(
+ (issue: Readonly>): Partial => {
+ return {
+ ...issue,
+ pull_request: null
+ };
+ }
+ )
+ );
+
+ return this;
+ }
+
+ prs(issues: Partial[]): IssuesProcessorBuilder {
+ this.issuesOrPrs(
+ issues.map(
+ (issue: Readonly>): Partial => {
+ return {
+ ...issue,
+ pull_request: {key: 'value'}
+ };
+ }
+ )
+ );
+
return this;
}
diff --git a/__tests__/constants/default-processor-options.ts b/__tests__/constants/default-processor-options.ts
index e89a80f6..035e4ac1 100644
--- a/__tests__/constants/default-processor-options.ts
+++ b/__tests__/constants/default-processor-options.ts
@@ -22,6 +22,8 @@ export const DefaultProcessorOptions: IIssuesProcessorOptions = Object.freeze({
onlyIssueLabels: '',
onlyPrLabels: '',
anyOfLabels: '',
+ anyOfIssueLabels: '',
+ anyOfPrLabels: '',
operationsPerRun: 100,
debugOnly: true,
removeStaleWhenUpdated: false,
diff --git a/action.yml b/action.yml
index 0b3f202e..43f92678 100644
--- a/action.yml
+++ b/action.yml
@@ -92,6 +92,14 @@ inputs:
description: 'Only issues or pull requests with at least one of these labels are checked if stale. Defaults to `` (disabled) and can be a comma-separated list of labels.'
default: ''
required: false
+ any-of-issue-labels:
+ description: 'Only issues with at least one of these labels are checked if stale. Defaults to `` (disabled) and can be a comma-separated list of labels. Override "any-of-labels" option regarding only the issues.'
+ default: ''
+ required: false
+ any-of-pr-labels:
+ description: 'Only pull requests with at least one of these labels are checked if stale. Defaults to `` (disabled) and can be a comma-separated list of labels. Override "any-of-labels" option regarding only the pull requests.'
+ default: ''
+ required: false
only-issue-labels:
description: 'Only issues with all of these labels are checked if stale. Defaults to `[]` (disabled) and can be a comma-separated list of labels. Override "only-labels" option regarding only the issues.'
default: ''
diff --git a/dist/index.js b/dist/index.js
index baeb586e..965191e9 100644
--- a/dist/index.js
+++ b/dist/index.js
@@ -312,15 +312,17 @@ class IssuesProcessor {
return is_labeled_1.isLabeled(issue, label);
});
if (!hasAllWhitelistedLabels) {
- issueLogger.info(`Skipping this $$type because it doesn't have all the required labels`);
+ issueLogger.info(chalk_1.default.white('└──'), `Skipping this $$type because it doesn't have all the required labels`);
continue; // Don't process issues without all of the required labels
}
else {
- issueLogger.info(`All the required labels are present on this $$type. Continuing the process`);
+ issueLogger.info(chalk_1.default.white('├──'), `All the required labels are present on this $$type`);
+ issueLogger.info(chalk_1.default.white('└──'), `Continuing the process for this $$type`);
}
}
else {
- issueLogger.info(`The option "onlyLabels" was not specified. Continuing the process for this $$type`);
+ issueLogger.info(`The option "onlyLabels" was not specified`);
+ issueLogger.info(chalk_1.default.white('└──'), `Continuing the process for this $$type`);
}
issueLogger.info(`Days before $$type stale: ${daysBeforeStale}`);
const shouldMarkAsStale = should_mark_when_stale_1.shouldMarkWhenStale(daysBeforeStale);
@@ -370,11 +372,24 @@ class IssuesProcessor {
issueLogger.info(`Skipping $$type because it has an exempt label`);
continue; // don't process exempt issues
}
- const anyOfLabels = words_to_list_1.wordsToList(this.options.anyOfLabels);
- if (anyOfLabels.length &&
- !anyOfLabels.some((label) => is_labeled_1.isLabeled(issue, label))) {
- issueLogger.info(`Skipping $$type because it does not have any of the required labels`);
- continue; // don't process issues without any of the required labels
+ const anyOfLabels = words_to_list_1.wordsToList(this._getAnyOfLabels(issue));
+ if (anyOfLabels.length > 0) {
+ issueLogger.info(`The option "anyOfLabels" was specified to only processed the issues and pull requests with one of those labels (${anyOfLabels.length})`);
+ const hasOneOfWhitelistedLabels = anyOfLabels.some((label) => {
+ return is_labeled_1.isLabeled(issue, label);
+ });
+ if (!hasOneOfWhitelistedLabels) {
+ issueLogger.info(chalk_1.default.white('└──'), `Skipping this $$type because it doesn't have one of the required labels`);
+ continue; // Don't process issues without any of the required labels
+ }
+ else {
+ issueLogger.info(chalk_1.default.white('├──'), `One of the required labels is present on this $$type`);
+ issueLogger.info(chalk_1.default.white('└──'), `Continuing the process for this $$type`);
+ }
+ }
+ else {
+ issueLogger.info(`The option "anyOfLabels" was not specified`);
+ issueLogger.info(chalk_1.default.white('└──'), `Continuing the process for this $$type`);
}
const milestones = new milestones_1.Milestones(this.options, issue);
if (milestones.shouldExemptMilestones()) {
@@ -759,6 +774,19 @@ class IssuesProcessor {
}
return this.options.onlyLabels;
}
+ _getAnyOfLabels(issue) {
+ if (issue.isPullRequest) {
+ if (this.options.anyOfPrLabels !== '') {
+ return this.options.anyOfPrLabels;
+ }
+ }
+ else {
+ if (this.options.anyOfIssueLabels !== '') {
+ return this.options.anyOfIssueLabels;
+ }
+ }
+ return this.options.anyOfLabels;
+ }
_removeStaleLabel(issue, staleLabel) {
var _a;
return __awaiter(this, void 0, void 0, function* () {
@@ -1758,6 +1786,8 @@ function _getAndValidateArgs() {
onlyIssueLabels: core.getInput('only-issue-labels'),
onlyPrLabels: core.getInput('only-pr-labels'),
anyOfLabels: core.getInput('any-of-labels'),
+ anyOfIssueLabels: core.getInput('any-of-issue-labels'),
+ anyOfPrLabels: core.getInput('any-of-pr-labels'),
operationsPerRun: parseInt(core.getInput('operations-per-run', { required: true })),
removeStaleWhenUpdated: !(core.getInput('remove-stale-when-updated') === 'false'),
debugOnly: core.getInput('debug-only') === 'true',
diff --git a/src/classes/issue.spec.ts b/src/classes/issue.spec.ts
index 8e7afff6..6d10ae9e 100644
--- a/src/classes/issue.spec.ts
+++ b/src/classes/issue.spec.ts
@@ -31,6 +31,8 @@ describe('Issue', (): void => {
onlyIssueLabels: '',
onlyPrLabels: '',
anyOfLabels: '',
+ anyOfIssueLabels: '',
+ anyOfPrLabels: '',
operationsPerRun: 0,
removeStaleWhenUpdated: false,
repoToken: '',
diff --git a/src/classes/issues-processor.ts b/src/classes/issues-processor.ts
index 43ee5219..2662b0f8 100644
--- a/src/classes/issues-processor.ts
+++ b/src/classes/issues-processor.ts
@@ -132,17 +132,25 @@ export class IssuesProcessor {
if (!hasAllWhitelistedLabels) {
issueLogger.info(
+ chalk.white('└──'),
`Skipping this $$type because it doesn't have all the required labels`
);
continue; // Don't process issues without all of the required labels
} else {
issueLogger.info(
- `All the required labels are present on this $$type. Continuing the process`
+ chalk.white('├──'),
+ `All the required labels are present on this $$type`
+ );
+ issueLogger.info(
+ chalk.white('└──'),
+ `Continuing the process for this $$type`
);
}
} else {
+ issueLogger.info(`The option "onlyLabels" was not specified`);
issueLogger.info(
- `The option "onlyLabels" was not specified. Continuing the process for this $$type`
+ chalk.white('└──'),
+ `Continuing the process for this $$type`
);
}
@@ -229,18 +237,41 @@ export class IssuesProcessor {
continue; // don't process exempt issues
}
- const anyOfLabels: string[] = wordsToList(this.options.anyOfLabels);
+ const anyOfLabels: string[] = wordsToList(this._getAnyOfLabels(issue));
- if (
- anyOfLabels.length &&
- !anyOfLabels.some((label: Readonly): boolean =>
- isLabeled(issue, label)
- )
- ) {
+ if (anyOfLabels.length > 0) {
issueLogger.info(
- `Skipping $$type because it does not have any of the required labels`
+ `The option "anyOfLabels" was specified to only processed the issues and pull requests with one of those labels (${anyOfLabels.length})`
+ );
+
+ const hasOneOfWhitelistedLabels: boolean = anyOfLabels.some(
+ (label: Readonly): boolean => {
+ return isLabeled(issue, label);
+ }
+ );
+
+ if (!hasOneOfWhitelistedLabels) {
+ issueLogger.info(
+ chalk.white('└──'),
+ `Skipping this $$type because it doesn't have one of the required labels`
+ );
+ continue; // Don't process issues without any of the required labels
+ } else {
+ issueLogger.info(
+ chalk.white('├──'),
+ `One of the required labels is present on this $$type`
+ );
+ issueLogger.info(
+ chalk.white('└──'),
+ `Continuing the process for this $$type`
+ );
+ }
+ } else {
+ issueLogger.info(`The option "anyOfLabels" was not specified`);
+ issueLogger.info(
+ chalk.white('└──'),
+ `Continuing the process for this $$type`
);
- continue; // don't process issues without any of the required labels
}
const milestones: Milestones = new Milestones(this.options, issue);
@@ -736,6 +767,20 @@ export class IssuesProcessor {
return this.options.onlyLabels;
}
+ private _getAnyOfLabels(issue: Issue): string {
+ if (issue.isPullRequest) {
+ if (this.options.anyOfPrLabels !== '') {
+ return this.options.anyOfPrLabels;
+ }
+ } else {
+ if (this.options.anyOfIssueLabels !== '') {
+ return this.options.anyOfIssueLabels;
+ }
+ }
+
+ return this.options.anyOfLabels;
+ }
+
private async _removeStaleLabel(
issue: Issue,
staleLabel: Readonly
diff --git a/src/interfaces/issues-processor-options.ts b/src/interfaces/issues-processor-options.ts
index 3c62d95b..0c981f86 100644
--- a/src/interfaces/issues-processor-options.ts
+++ b/src/interfaces/issues-processor-options.ts
@@ -22,6 +22,8 @@ export interface IIssuesProcessorOptions {
onlyIssueLabels: string;
onlyPrLabels: string;
anyOfLabels: string;
+ anyOfIssueLabels: string;
+ anyOfPrLabels: string;
operationsPerRun: number;
removeStaleWhenUpdated: boolean;
debugOnly: boolean;
diff --git a/src/main.ts b/src/main.ts
index 5aa0bc48..0cdf69e3 100644
--- a/src/main.ts
+++ b/src/main.ts
@@ -41,6 +41,8 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
onlyIssueLabels: core.getInput('only-issue-labels'),
onlyPrLabels: core.getInput('only-pr-labels'),
anyOfLabels: core.getInput('any-of-labels'),
+ anyOfIssueLabels: core.getInput('any-of-issue-labels'),
+ anyOfPrLabels: core.getInput('any-of-pr-labels'),
operationsPerRun: parseInt(
core.getInput('operations-per-run', {required: true})
),