feat(assignees): add 6 new options to avoid stale for assignees (#327)

* feat(assignees): add new option to avoid stale for assignees

closes #271

* test: add more coverage

* docs: fix readme format issue

* docs: reorder and enhance typo

* docs(contributing): add more information about the npm scripts
This commit is contained in:
Geoffrey Testelin 2021-02-28 12:15:08 +01:00 committed by GitHub
parent 996798eb71
commit ec96ff65b0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
24 changed files with 2021 additions and 244 deletions

View File

@ -17,3 +17,29 @@ Run the tests :heavy_check_mark:
```bash
$ npm test
```
Run the tests and display only the first failing tests :heavy_check_mark:
```bash
$ npm test:only-errors
```
Run the tests with the watch mode :heavy_check_mark:
```bash
$ npm test:watch
```
Run the linter and fix (almost) every issue for you :heavy_check_mark:
```bash
$ npm lint:all:fix
```
### Before creating a PR
Build, lint, package and test everything.
```bash
$ npm all
```

View File

@ -23,12 +23,6 @@ Warns and then closes issues and PRs that have had no activity for a specified a
| `close-pr-label` | Label to apply on the closing PR. | Optional |
| `exempt-issue-labels` | Labels on an issue exempted from being marked as stale. | Optional |
| `exempt-pr-labels` | Labels on the PR exempted from being marked as stale. | Optional |
| `exempt-milestones` | Milestones on an issue or a PR exempted from being marked as stale. | Optional |
| `exempt-issue-milestones` | Milestones on an issue exempted from being marked as stale (override `exempt-milestones`). | Optional |
| `exempt-pr-milestones` | Milestones on the PR exempted from being marked as stale (override `exempt-milestones`). | Optional |
| `exempt-all-milestones` | Exempt all issues and PRs with milestones from being marked as stale. (priority over `exempt-milestones` rules) | Optional |
| `exempt-all-issue-milestones` | Exempt all issues with milestones from being marked as stale. (override `exempt-all-milestones`). | Optional |
| `exempt-all-pr-milestones` | Exempt all PRs with milestones from being marked as stale. (override `exempt-all-milestones`). | Optional |
| `only-labels` | Only labels checked for stale issue/PR. | Optional |
| `operations-per-run` | Maximum number of operations per run (GitHub API CRUD related). _Defaults to **30**_ | Optional |
| `remove-stale-when-updated` | Remove stale label from issue/PR on updates or comments. _Defaults to **true**_ | Optional |
@ -38,10 +32,22 @@ Warns and then closes issues and PRs that have had no activity for a specified a
| `skip-stale-pr-message` | Skip adding stale message on stale PR. _Defaults to **false**_ | Optional |
| `start-date` | The date used to skip the stale action on issue/PR created before it (ISO 8601 or RFC 2822). | Optional |
| `delete-branch` | Delete the git branch after closing a stale pull request. _Defaults to **false**_ | Optional |
| `exempt-milestones` | Milestones on an issue or a PR exempted from being marked as stale. | Optional |
| `exempt-issue-milestones` | Milestones on an issue exempted from being marked as stale (override `exempt-milestones`). | Optional |
| `exempt-pr-milestones` | Milestones on the PR exempted from being marked as stale (override `exempt-milestones`). | Optional |
| `exempt-all-milestones` | Exempt all issues and PRs with milestones from being marked as stale. (priority over `exempt-milestones` rules) | Optional |
| `exempt-all-issue-milestones` | Exempt all issues with milestones from being marked as stale. (override `exempt-all-milestones`). | Optional |
| `exempt-all-pr-milestones` | Exempt all PRs with milestones from being marked as stale. (override `exempt-all-milestones`). | Optional |
| `exempt-assignees` | Assignees on an issue or a PR exempted from being marked as stale. | Optional |
| `exempt-issue-assignees` | Assignees on an issue exempted from being marked as stale (override `exempt-assignees`). | Optional |
| `exempt-pr-assignees` | Assignees on the PR exempted from being marked as stale (override `exempt-assignees`). | Optional |
| `exempt-all-assignees` | Exempt all issues and PRs with assignees from being marked as stale. (priority over `exempt-assignees` rules) | Optional |
| `exempt-all-issue-assignees` | Exempt all issues with assignees from being marked as stale. (override `exempt-all-assignees`). | Optional |
| `exempt-all-pr-assignees` | Exempt all PRs with assignees from being marked as stale. (override `exempt-all-assignees`). | Optional |
### Usage
See [action.yml](./action.yml) For comprehensive list of options.
See also [action.yml](./action.yml) for a comprehensive list of all the options.
Basic:
@ -203,6 +209,41 @@ jobs:
exempt-all-pr-milestones: true
```
Avoid stale for specific assignees:
```yaml
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
exempt-issue-assignees: 'marco,polo'
exempt-pr-assignees: 'marco'
```
Avoid stale for all PR with assignees:
```yaml
name: 'Close stale issues and PRs'
on:
schedule:
- cron: '30 1 * * *'
jobs:
stale:
runs-on: ubuntu-latest
steps:
- uses: actions/stale@v3
with:
exempt-all-pr-assignees: true
```
### Debugging
To see the debug output from this action, you must set the secret `ACTIONS_STEP_DEBUG` to `true` in your repository.

413
__tests__/assignees.spec.ts Normal file
View File

@ -0,0 +1,413 @@
import {Issue} from '../src/classes/issue';
import {IssuesProcessor} from '../src/classes/issues-processor';
import {IIssuesProcessorOptions} from '../src/interfaces/issues-processor-options';
import {DefaultProcessorOptions} from './constants/default-processor-options';
import {generateIssue} from './functions/generate-issue';
interface ITestData {
id: number;
isPullRequest: boolean;
assignees: string[];
exemptAllAssignees: boolean;
exemptAllIssueAssignees: boolean | undefined;
exemptAllPrAssignees: boolean | undefined;
exemptAssignees: string;
exemptIssueAssignees: string;
exemptPrAssignees: string;
shouldStale: boolean;
description: string;
}
describe('assignees options', (): void => {
let opts: IIssuesProcessorOptions;
let testIssueList: Issue[];
let processor: IssuesProcessor;
const setTestIssueList = (
isPullRequest: boolean,
assignees: string[],
id: number
) => {
testIssueList = [
generateIssue(
opts,
id,
'My first issue',
'2020-01-01T17:00:00Z',
'2020-01-01T17:00:00Z',
isPullRequest,
undefined,
undefined,
undefined,
undefined,
assignees
)
];
};
const setProcessor = () => {
processor = new IssuesProcessor(
opts,
async () => 'abot',
async p => (p === 1 ? testIssueList : []),
async () => [],
async () => new Date().toDateString()
);
};
beforeEach((): void => {
opts = {...DefaultProcessorOptions};
});
describe.each`
id | isPullRequest | assignees | exemptAllAssignees | exemptAllIssueAssignees | exemptAllPrAssignees | exemptAssignees | exemptIssueAssignees | exemptPrAssignees | shouldStale | description
${100} | ${false} | ${[]} | ${false} | ${undefined} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the issue does not have an assignee'}
${101} | ${false} | ${[]} | ${true} | ${undefined} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the issue does not have an assignee and only exemptAllAssignees is enabled'}
${102} | ${false} | ${[]} | ${false} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the issue does not have an assignee and only exemptAllIssueAssignees is enabled'}
${103} | ${false} | ${[]} | ${false} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${true} | ${'when the issue does not have an assignee and only exemptAllPrAssignees is enabled'}
${104} | ${false} | ${[]} | ${true} | ${false} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the issue does not have an assignee and exemptAllAssignees is enabled and exemptAllIssueAssignees is disabled'}
${105} | ${false} | ${[]} | ${true} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the issue does not have an assignee and exemptAllAssignees is enabled and exemptAllIssueAssignees is enabled'}
${106} | ${false} | ${[]} | ${true} | ${undefined} | ${false} | ${''} | ${''} | ${''} | ${true} | ${'when the issue does not have an assignee and exemptAllAssignees is enabled and exemptAllPrAssignees is disabled'}
${107} | ${false} | ${[]} | ${true} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${true} | ${'when the issue does not have an assignee and exemptAllAssignees is enabled and exemptAllPrAssignees is enabled'}
${108} | ${false} | ${[]} | ${false} | ${false} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the issue does not have an assignee and exemptAllAssignees is disabled and exemptAllIssueAssignees is disabled'}
${109} | ${false} | ${[]} | ${false} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the issue does not have an assignee and exemptAllAssignees is disabled and exemptAllIssueAssignees is enabled'}
${200} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${''} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled and exemptAllPrAssignees is disabled'}
${201} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled and exemptAllPrAssignees is enabled'}
${202} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${''} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and only exemptAllAssignees is enabled'}
${203} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and only exemptAllIssueAssignees is enabled'}
${204} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and only exemptAllPrAssignees is enabled'}
${205} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is enabled and exemptAllIssueAssignees is disabled'}
${206} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled and exemptAllIssueAssignees is enabled'}
${207} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${''} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled and exemptAllPrAssignees is disabled'}
${208} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled and exemptAllPrAssignees is enabled'}
${209} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled and exemptAllIssueAssignees is disabled'}
${210} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled and exemptAllIssueAssignees is enabled'}
${211} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${''} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled and exemptAllPrAssignees is disabled'}
${212} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled and exemptAllPrAssignees is enabled'}
${213} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${''} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled and exemptAllPrAssignees is disabled'}
${300} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has a different assignee'}
${301} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees has a different assignee'}
${302} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled and exemptAssignees has a different assignee'}
${303} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllIssueAssignees is enabled and exemptAssignees has a different assignee'}
${304} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllPrAssignees is enabled and exemptAssignees has a different assignee'}
${305} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled and exemptAssignees has a different assignee'}
${306} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled and exemptAssignees has a different assignee'}
${307} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled and exemptAssignees has a different assignee'}
${308} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled and exemptAssignees has a different assignee'}
${309} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled and exemptAssignees has a different assignee'}
${310} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled and exemptAssignees has a different assignee'}
${311} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has a different assignee'}
${312} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees has a different assignee'}
${313} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has a different assignee'}
${400} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has the same assignee'}
${401} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees has the same assignee'}
${402} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled and exemptAssignees has the same assignee'}
${403} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllIssueAssignees is enabled and exemptAssignees has the same assignee'}
${404} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllPrAssignees is enabled and exemptAssignees has the same assignee'}
${405} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled and exemptAssignees has the same assignee'}
${406} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled and exemptAssignees has the same assignee'}
${407} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled and exemptAssignees has the same assignee'}
${408} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled and exemptAssignees has the same assignee'}
${409} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled and exemptAssignees has the same assignee'}
${410} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled and exemptAssignees has the same assignee'}
${411} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has the same assignee'}
${412} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees has the same assignee'}
${413} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has the same assignee'}
${500} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${501} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${502} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${503} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllIssueAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${504} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllPrAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${505} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${506} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${507} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${508} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${509} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${510} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${511} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${512} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${513} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${600} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${601} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${602} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${603} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${604} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${605} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${606} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${607} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${608} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${609} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${610} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${611} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${612} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${613} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${700} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${701} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${702} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${703} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllIssueAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${704} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the issue has an assignee and exemptAllPrAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${705} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${706} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${707} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${708} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${709} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${710} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${711} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${712} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${713} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${800} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'assignee'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${801} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'assignee'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${802} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${803} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${804} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'assignee'} | ${true} | ${'when the issue has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${805} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${806} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${807} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${808} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${809} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${810} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${811} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'assignee'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${812} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'assignee'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${813} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'assignee'} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${900} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${901} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${902} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${903} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${904} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${905} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${906} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${907} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${908} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${909} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${910} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${911} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${912} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${913} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${'bad'} | ${''} | ${true} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${1000} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1001} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1002} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1003} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1004} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1005} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1006} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1007} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1008} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1009} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1010} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1011} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1012} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1013} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${1100} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1101} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1102} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1103} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1104} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1105} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1106} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1107} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1108} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1109} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1110} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1111} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1112} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1113} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${1200} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1201} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1202} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1203} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1204} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1205} | ${false} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1206} | ${false} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1207} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1208} | ${false} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1209} | ${false} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1210} | ${false} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1211} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1212} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1213} | ${false} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the issue has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${1300} | ${true} | ${[]} | ${false} | ${undefined} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request does not have an assignee'}
${1301} | ${true} | ${[]} | ${true} | ${undefined} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request does not have an assignee and only exemptAllAssignees is enabled'}
${1302} | ${true} | ${[]} | ${false} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request does not have an assignee and only exemptAllIssueAssignees is enabled'}
${1303} | ${true} | ${[]} | ${false} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request does not have an assignee and only exemptAllPrAssignees is enabled'}
${1304} | ${true} | ${[]} | ${true} | ${false} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request does not have an assignee and exemptAllAssignees is enabled and exemptAllIssueAssignees is disabled'}
${1305} | ${true} | ${[]} | ${true} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request does not have an assignee and exemptAllAssignees is enabled and exemptAllIssueAssignees is enabled'}
${1306} | ${true} | ${[]} | ${true} | ${undefined} | ${false} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request does not have an assignee and exemptAllAssignees is enabled and exemptAllPrAssignees is disabled'}
${1307} | ${true} | ${[]} | ${true} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request does not have an assignee and exemptAllAssignees is enabled and exemptAllPrAssignees is enabled'}
${1308} | ${true} | ${[]} | ${false} | ${false} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request does not have an assignee and exemptAllAssignees is disabled and exemptAllIssueAssignees is disabled'}
${1309} | ${true} | ${[]} | ${false} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request does not have an assignee and exemptAllAssignees is disabled and exemptAllIssueAssignees is enabled'}
${1400} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled and exemptAllPrAssignees is disabled'}
${1401} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled and exemptAllPrAssignees is enabled'}
${1402} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${''} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and only exemptAllAssignees is enabled'}
${1403} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and only exemptAllIssueAssignees is enabled'}
${1404} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and only exemptAllPrAssignees is enabled'}
${1405} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${''} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled and exemptAllIssueAssignees is disabled'}
${1406} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled and exemptAllIssueAssignees is enabled'}
${1407} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is enabled and exemptAllPrAssignees is disabled'}
${1408} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled and exemptAllPrAssignees is enabled'}
${1409} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled and exemptAllIssueAssignees is disabled'}
${1410} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled and exemptAllIssueAssignees is enabled'}
${1411} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled and exemptAllPrAssignees is disabled'}
${1412} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${''} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled and exemptAllPrAssignees is enabled'}
${1413} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${''} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled and exemptAllPrAssignees is disabled'}
${1500} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has a different assignee'}
${1501} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees has a different assignee'}
${1502} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled and exemptAssignees has a different assignee'}
${1503} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllIssueAssignees is enabled and exemptAssignees has a different assignee'}
${1504} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllPrAssignees is enabled and exemptAssignees has a different assignee'}
${1505} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled and exemptAssignees has a different assignee'}
${1506} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled and exemptAssignees has a different assignee'}
${1507} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled and exemptAssignees has a different assignee'}
${1508} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'bad'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled and exemptAssignees has a different assignee'}
${1509} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled and exemptAssignees has a different assignee'}
${1510} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled and exemptAssignees has a different assignee'}
${1511} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has a different assignee'}
${1513} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has a different assignee'}
${1600} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has the same assignee'}
${1601} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees has the same assignee'}
${1602} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled and exemptAssignees has the same assignee'}
${1603} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllIssueAssignees is enabled and exemptAssignees has the same assignee'}
${1604} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllPrAssignees is enabled and exemptAssignees has the same assignee'}
${1605} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled and exemptAssignees has the same assignee'}
${1606} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled and exemptAssignees has the same assignee'}
${1607} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled and exemptAssignees has the same assignee'}
${1608} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled and exemptAssignees has the same assignee'}
${1609} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled and exemptAssignees has the same assignee'}
${1610} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled and exemptAssignees has the same assignee'}
${1611} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has the same assignee'}
${1612} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees has the same assignee'}
${1613} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees has the same assignee'}
${1701} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1702} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1703} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllIssueAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1704} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllPrAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1705} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1706} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1707} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1708} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'bad'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1709} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1710} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1711} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${'bad'} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptIssueAssignees has a different assignee'}
${1800} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1801} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1802} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1803} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1804} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1805} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'bad'} | ${'assignee'} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1806} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1807} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1808} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${'assignee'} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1809} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1810} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${'assignee'} | ${''} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptIssueAssignees has the same assignee'}
${1900} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1901} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1902} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the pull request has an assignee and exemptAllIssueAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1903} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllPrAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1904} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1905} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1906} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1907} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1908} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1909} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1910} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${1911} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'bad'} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled and exemptAssignees and exemptPrAssignees has a different assignee'}
${2000} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2001} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2002} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2003} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2004} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2005} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2006} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2007} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2008} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2009} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2010} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'bad'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has a different assignee and exemptPrAssignees has the same assignee'}
${2100} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2101} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2102} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2103} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2104} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2105} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2106} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2107} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2108} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2109} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2110} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${'bad'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has a different assignee'}
${2200} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2201} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2202} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2203} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2204} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2205} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2206} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2207} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2208} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2209} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2210} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2311} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2312} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2313} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${'assignee'} | ${''} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptIssueAssignees has the same assignee'}
${2300} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'bad'} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2301} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2302} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2303} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${true} | ${'when the pull request has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2304} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2305} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2306} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2307} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'bad'} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2308} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2309} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2310} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'bad'} | ${true} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2311} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'bad'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has a different assignee'}
${2400} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2401} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2402} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2403} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2404} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2405} | ${true} | ${['assignee']} | ${true} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2406} | ${true} | ${['assignee']} | ${true} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2407} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2408} | ${true} | ${['assignee']} | ${true} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is enabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2409} | ${true} | ${['assignee']} | ${false} | ${false} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2410} | ${true} | ${['assignee']} | ${false} | ${true} | ${undefined} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllIssueAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2411} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2412} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${true} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is enabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
${2413} | ${true} | ${['assignee']} | ${false} | ${undefined} | ${false} | ${'assignee'} | ${''} | ${'assignee'} | ${false} | ${'when the pull request has an assignee and exemptAllAssignees is disabled, exemptAllPrAssignees is disabled, exemptAssignees has the same assignee and exemptPrAssignees has the same assignee'}
`(
'$description',
({
id,
isPullRequest,
assignees,
exemptAllAssignees,
exemptAllIssueAssignees,
exemptAllPrAssignees,
exemptAssignees,
exemptIssueAssignees,
exemptPrAssignees,
shouldStale
}: ITestData): void => {
beforeEach((): void => {
opts.exemptAllAssignees = exemptAllAssignees;
opts.exemptAllIssueAssignees = exemptAllIssueAssignees;
opts.exemptAllPrAssignees = exemptAllPrAssignees;
opts.exemptAssignees = exemptAssignees;
opts.exemptIssueAssignees = exemptIssueAssignees;
opts.exemptPrAssignees = exemptPrAssignees;
setTestIssueList(isPullRequest, assignees, id);
setProcessor();
});
test(`should${
shouldStale ? '' : ' not'
} be marked as stale`, async () => {
expect.assertions(3);
await processor.processIssues(1);
expect(processor.staleIssues).toHaveLength(shouldStale ? 1 : 0);
expect(processor.closedIssues).toHaveLength(0);
expect(processor.removedLabelIssues).toHaveLength(0);
});
}
);
});

View File

@ -32,5 +32,11 @@ export const DefaultProcessorOptions: IIssuesProcessorOptions = Object.freeze({
exemptPrMilestones: '',
exemptAllMilestones: false,
exemptAllIssueMilestones: undefined,
exemptAllPrMilestones: undefined
exemptAllPrMilestones: undefined,
exemptAssignees: '',
exemptIssueAssignees: '',
exemptPrAssignees: '',
exemptAllAssignees: false,
exemptAllIssueAssignees: undefined,
exemptAllPrAssignees: undefined
});

View File

@ -0,0 +1,19 @@
import {IIssue} from '../../src/interfaces/issue';
export function generateIIssue(
partialIssue?: Readonly<Partial<IIssue>>
): IIssue {
return {
milestone: undefined,
assignees: [],
labels: [],
created_at: new Date().toISOString(),
updated_at: new Date().toISOString(),
number: Math.round(Math.random() * 5000),
pull_request: null,
title: 'dummy-title',
locked: false,
state: 'dummy-state',
...partialIssue
};
}

View File

@ -1,4 +1,5 @@
import {Issue} from '../../src/classes/issue';
import {IAssignee} from '../../src/interfaces/assignee';
import {IIssuesProcessorOptions} from '../../src/interfaces/issues-processor-options';
import {IsoDateString} from '../../src/types/iso-date-string';
@ -12,7 +13,8 @@ export function generateIssue(
labels: string[] = [],
isClosed = false,
isLocked = false,
milestone: string | undefined = undefined
milestone: string | undefined = undefined,
assignees: string[] = []
): Issue {
return new Issue(options, {
number: id,
@ -29,6 +31,13 @@ export function generateIssue(
? {
title: milestone
}
: undefined
: undefined,
assignees: assignees.map(
(assignee: Readonly<string>): IAssignee => {
return {
login: assignee
};
}
)
});
}

View File

@ -9,7 +9,6 @@ interface ITestData {
milestone: string;
name: string;
shouldStale: boolean;
exemptAllMilestones: boolean;
}
describe('milestones options', (): void => {

View File

@ -120,6 +120,30 @@ inputs:
description: 'The date used to skip the stale action on issue/pull request created before it (ISO 8601 or RFC 2822).'
default: ''
required: false
exempt-assignees:
description: 'The assignees which exempt an issue or a pull request from being marked as stale. Separate multiple assignees with commas (eg. "user1,user2")'
default: ''
required: false
exempt-issue-assignees:
description: 'The assignees which exempt an issue from being marked as stale. Separate multiple assignees with commas (eg. "user1,user2"). Override "exempt-assignees" option regarding only the issues.'
default: ''
required: false
exempt-pr-assignees:
description: 'The assignees which exempt a pull request from being marked as stale. Separate multiple assignees with commas (eg. "user1,user2"). Override "exempt-assignees" option regarding only the pull requests.'
default: ''
required: false
exempt-all-assignees:
description: 'Exempt all issues and pull requests with assignees from being marked as stale. Default to false.'
default: 'false'
required: false
exempt-all-issue-assignees:
description: 'Exempt all issues with assignees from being marked as stale. Override "exempt-all-assignees" option regarding only the issues.'
default: ''
required: false
exempt-all-pr-assignees:
description: 'Exempt all pull requests with assignees from being marked as stale. Override "exempt-all-assignees" option regarding only the pull requests.'
default: ''
required: false
runs:
using: 'node12'
main: 'dist/index.js'

273
dist/index.js vendored
View File

@ -2,6 +2,146 @@ module.exports =
/******/ (() => { // webpackBootstrap
/******/ var __webpack_modules__ = ({
/***/ 7236:
/***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.Assignees = void 0;
const lodash_deburr_1 = __importDefault(__nccwpck_require__(1601));
const words_to_list_1 = __nccwpck_require__(1883);
const issue_logger_1 = __nccwpck_require__(2984);
class Assignees {
constructor(options, issue) {
this._options = options;
this._issue = issue;
this._issueLogger = new issue_logger_1.IssueLogger(issue);
}
static _cleanAssignee(assignee) {
return lodash_deburr_1.default(assignee.toLowerCase());
}
shouldExemptAssignees() {
if (!this._issue.hasAssignees) {
this._issueLogger.info('This $$type has no assignee');
this._logSkip();
return false;
}
if (this._shouldExemptAllAssignees()) {
this._issueLogger.info('Skipping $$type because it has an exempt assignee');
return true;
}
const exemptAssignees = this._getExemptAssignees();
if (exemptAssignees.length === 0) {
this._issueLogger.info(`No option was specified to skip the stale process for this $$type`);
this._logSkip();
return false;
}
this._issueLogger.info(`Found ${exemptAssignees.length} assignee${exemptAssignees.length > 1 ? 's' : ''} on this $$type`);
const hasExemptAssignee = exemptAssignees.some((exemptAssignee) => this._hasAssignee(exemptAssignee));
if (!hasExemptAssignee) {
this._issueLogger.info('No assignee on this $$type can exempt the stale process');
this._logSkip();
}
else {
this._issueLogger.info('Skipping this $$type because it has an exempt assignee');
}
return hasExemptAssignee;
}
_getExemptAssignees() {
return this._issue.isPullRequest
? this._getExemptPullRequestAssignees()
: this._getExemptIssueAssignees();
}
_getExemptIssueAssignees() {
if (this._options.exemptIssueAssignees === '') {
this._issueLogger.info('The option "exemptIssueAssignees" is disabled. No specific assignee can skip the stale process for this $$type');
if (this._options.exemptAssignees === '') {
this._issueLogger.info('The option "exemptAssignees" is disabled. No specific assignee can skip the stale process for this $$type');
return [];
}
const exemptAssignees = words_to_list_1.wordsToList(this._options.exemptAssignees);
this._issueLogger.info(`The option "exemptAssignees" is set. ${exemptAssignees.length} assignee${exemptAssignees.length === 1 ? '' : 's'} can skip the stale process for this $$type`);
return exemptAssignees;
}
const exemptAssignees = words_to_list_1.wordsToList(this._options.exemptIssueAssignees);
this._issueLogger.info(`The option "exemptIssueAssignees" is set. ${exemptAssignees.length} assignee${exemptAssignees.length === 1 ? '' : 's'} can skip the stale process for this $$type`);
return exemptAssignees;
}
_getExemptPullRequestAssignees() {
if (this._options.exemptPrAssignees === '') {
this._issueLogger.info('The option "exemptPrAssignees" is disabled. No specific assignee can skip the stale process for this $$type');
if (this._options.exemptAssignees === '') {
this._issueLogger.info('The option "exemptAssignees" is disabled. No specific assignee can skip the stale process for this $$type');
return [];
}
const exemptAssignees = words_to_list_1.wordsToList(this._options.exemptAssignees);
this._issueLogger.info(`The option "exemptAssignees" is set. ${exemptAssignees.length} assignee${exemptAssignees.length === 1 ? '' : 's'} can skip the stale process for this $$type`);
return exemptAssignees;
}
const exemptAssignees = words_to_list_1.wordsToList(this._options.exemptPrAssignees);
this._issueLogger.info(`The option "exemptPrAssignees" is set. ${exemptAssignees.length} assignee${exemptAssignees.length === 1 ? '' : 's'} can skip the stale process for this $$type`);
return exemptAssignees;
}
_hasAssignee(assignee) {
const cleanAssignee = Assignees._cleanAssignee(assignee);
return this._issue.assignees.some((issueAssignee) => {
const isSameAssignee = cleanAssignee === Assignees._cleanAssignee(issueAssignee.login);
if (isSameAssignee) {
this._issueLogger.info(`@${issueAssignee.login} is assigned on this $$type and is an exempt assignee`);
}
return isSameAssignee;
});
}
_shouldExemptAllAssignees() {
return this._issue.isPullRequest
? this._shouldExemptAllPullRequestAssignees()
: this._shouldExemptAllIssueAssignees();
}
_shouldExemptAllIssueAssignees() {
if (this._options.exemptAllIssueAssignees === true) {
this._issueLogger.info('The option "exemptAllIssueAssignees" is enabled. Any assignee on this $$type will skip the stale process');
return true;
}
else if (this._options.exemptAllIssueAssignees === false) {
this._issueLogger.info('The option "exemptAllIssueAssignees" is disabled. Only some specific assignees on this $$type will skip the stale process');
return false;
}
this._logExemptAllAssigneesOption();
return this._options.exemptAllAssignees;
}
_shouldExemptAllPullRequestAssignees() {
if (this._options.exemptAllPrAssignees === true) {
this._issueLogger.info('The option "exemptAllPrAssignees" is enabled. Any assignee on this $$type will skip the stale process');
return true;
}
else if (this._options.exemptAllPrAssignees === false) {
this._issueLogger.info('The option "exemptAllPrAssignees" is disabled. Only some specific assignees on this $$type will skip the stale process');
return false;
}
this._logExemptAllAssigneesOption();
return this._options.exemptAllAssignees;
}
_logExemptAllAssigneesOption() {
if (this._options.exemptAllAssignees) {
this._issueLogger.info('The option "exemptAllAssignees" is enabled. Any assignee on this $$type will skip the stale process');
}
else {
this._issueLogger.info('The option "exemptAllAssignees" is disabled. Only some specific assignees on this $$type will skip the stale process');
}
}
_logSkip() {
this._issueLogger.info('Skip the assignees checks');
}
}
exports.Assignees = Assignees;
/***/ }),
/***/ 4783:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => {
@ -23,10 +163,18 @@ class Issue {
this.state = issue.state;
this.locked = issue.locked;
this.milestone = issue.milestone;
this.isPullRequest = is_pull_request_1.isPullRequest(this);
this.staleLabel = this._getStaleLabel();
this.assignees = issue.assignees;
this.isStale = is_labeled_1.isLabeled(this, this.staleLabel);
}
get isPullRequest() {
return is_pull_request_1.isPullRequest(this);
}
get staleLabel() {
return this._getStaleLabel();
}
get hasAssignees() {
return this.assignees.length > 0;
}
_getStaleLabel() {
return this.isPullRequest
? this._options.stalePrLabel
@ -63,6 +211,7 @@ const is_labeled_1 = __nccwpck_require__(6792);
const is_pull_request_1 = __nccwpck_require__(5400);
const should_mark_when_stale_1 = __nccwpck_require__(2461);
const words_to_list_1 = __nccwpck_require__(1883);
const assignees_1 = __nccwpck_require__(7236);
const issue_1 = __nccwpck_require__(4783);
const issue_logger_1 = __nccwpck_require__(2984);
const logger_1 = __nccwpck_require__(6212);
@ -115,7 +264,7 @@ class IssuesProcessor {
}
for (const issue of issues.values()) {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Found issue: issue #${issue.number} last updated ${issue.updated_at} (is pr? ${issue.isPullRequest})`);
issueLogger.info(`Found this $$type last updated ${issue.updated_at}`);
// calculate string based messages for this issue
const staleMessage = issue.isPullRequest
? this.options.stalePrMessage
@ -136,23 +285,18 @@ class IssuesProcessor {
const daysBeforeStale = issue.isPullRequest
? this._getDaysBeforePrStale()
: this._getDaysBeforeIssueStale();
if (issue.isPullRequest) {
issueLogger.info(`Days before pull request stale: ${daysBeforeStale}`);
}
else {
issueLogger.info(`Days before issue stale: ${daysBeforeStale}`);
}
issueLogger.info(`Days before $$type stale: ${daysBeforeStale}`);
const shouldMarkAsStale = should_mark_when_stale_1.shouldMarkWhenStale(daysBeforeStale);
if (!staleMessage && shouldMarkAsStale) {
issueLogger.info(`Skipping ${issueType} due to empty stale message`);
issueLogger.info(`Skipping $$type due to empty stale message`);
continue;
}
if (issue.state === 'closed') {
issueLogger.info(`Skipping ${issueType} because it is closed`);
issueLogger.info(`Skipping $$type because it is closed`);
continue; // don't process closed issues
}
if (issue.locked) {
issueLogger.info(`Skipping ${issueType} because it is locked`);
issueLogger.info(`Skipping $$type because it is locked`);
continue; // don't process locked issues
}
if (this.options.startDate) {
@ -164,17 +308,17 @@ class IssuesProcessor {
if (!is_valid_date_1.isValidDate(createdAt)) {
throw new Error(`Invalid issue field: "created_at". Expected a valid date`);
}
issueLogger.info(`Issue created the ${get_humanized_date_1.getHumanizedDate(createdAt)} (${issue.created_at})`);
issueLogger.info(`$$type created the ${get_humanized_date_1.getHumanizedDate(createdAt)} (${issue.created_at})`);
if (!is_date_more_recent_than_1.isDateMoreRecentThan(createdAt, startDate)) {
issueLogger.info(`Skipping ${issueType} because it was created before the specified start date`);
issueLogger.info(`Skipping $$type because it was created before the specified start date`);
continue; // don't process issues which were created before the start date
}
}
if (issue.isStale) {
issueLogger.info(`This issue has a stale label`);
issueLogger.info(`This $$type has a stale label`);
}
else {
issueLogger.info(`This issue hasn't a stale label`);
issueLogger.info(`This $$type hasn't a stale label`);
}
const exemptLabels = words_to_list_1.wordsToList(issue.isPullRequest
? this.options.exemptPrLabels
@ -184,19 +328,23 @@ class IssuesProcessor {
issueLogger.info(`An exempt label was added after the stale label.`);
yield this._removeStaleLabel(issue, staleLabel);
}
issueLogger.info(`Skipping ${issueType} because it has an exempt label`);
issueLogger.info(`Skipping $$type because it has an exempt label`);
continue; // don't process exempt issues
}
const milestones = new milestones_1.Milestones(this.options, issue);
if (milestones.shouldExemptMilestones()) {
issueLogger.info(`Skipping ${issueType} because it has an exempt milestone`);
issueLogger.info(`Skipping $$type because it has an exempted milestone`);
continue; // don't process exempt milestones
}
const assignees = new assignees_1.Assignees(this.options, issue);
if (assignees.shouldExemptAssignees()) {
continue; // don't process exempt assignees
}
// should this issue be marked stale?
const shouldBeStale = !IssuesProcessor._updatedSince(issue.updated_at, daysBeforeStale);
// determine if this issue needs to be marked stale first
if (!issue.isStale && shouldBeStale && shouldMarkAsStale) {
issueLogger.info(`Marking ${issueType} stale because it was last updated on ${issue.updated_at} and it does not have a stale label`);
issueLogger.info(`Marking $$type stale because it was last updated on ${issue.updated_at} and it does not have a stale label`);
yield this._markStale(issue, staleMessage, staleLabel, skipMessage);
issue.isStale = true; // this issue is now considered stale
}
@ -205,7 +353,7 @@ class IssuesProcessor {
}
// process the issue if it was marked stale
if (issue.isStale) {
issueLogger.info(`Found a stale ${issueType}`);
issueLogger.info(`Found a stale $$type`);
yield this._processStaleIssue(issue, issueType, staleLabel, actor, closeMessage, closeLabel);
}
}
@ -222,21 +370,16 @@ class IssuesProcessor {
return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue);
const markedStaleOn = (yield this._getLabelCreationDate(issue, staleLabel)) || issue.updated_at;
issueLogger.info(`Issue #${issue.number} marked stale on: ${markedStaleOn}`);
issueLogger.info(`$$type marked stale on: ${markedStaleOn}`);
const issueHasComments = yield this._hasCommentsSince(issue, markedStaleOn, actor);
issueLogger.info(`Issue #${issue.number} has been commented on: ${issueHasComments}`);
issueLogger.info(`$$type has been commented on: ${issueHasComments}`);
const isPr = is_pull_request_1.isPullRequest(issue);
const daysBeforeClose = isPr
? this._getDaysBeforePrClose()
: this._getDaysBeforeIssueClose();
if (isPr) {
issueLogger.info(`Days before pull request close: ${daysBeforeClose}`);
}
else {
issueLogger.info(`Days before issue close: ${daysBeforeClose}`);
}
issueLogger.info(`Days before $$type close: ${daysBeforeClose}`);
const issueHasUpdate = IssuesProcessor._updatedSince(issue.updated_at, daysBeforeClose);
issueLogger.info(`Issue #${issue.number} has been updated: ${issueHasUpdate}`);
issueLogger.info(`$$type has been updated: ${issueHasUpdate}`);
// should we un-stale this issue?
if (this.options.removeStaleWhenUpdated && issueHasComments) {
yield this._removeStaleLabel(issue, staleLabel);
@ -246,16 +389,16 @@ class IssuesProcessor {
return; // nothing to do because we aren't closing stale issues
}
if (!issueHasComments && !issueHasUpdate) {
issueLogger.info(`Closing ${issueType} because it was last updated on ${issue.updated_at}`);
issueLogger.info(`Closing $$type because it was last updated on ${issue.updated_at}`);
yield this._closeIssue(issue, closeMessage, closeLabel);
if (this.options.deleteBranch && issue.pull_request) {
issueLogger.info(`Deleting branch for #${issue.number} as delete-branch option was specified`);
issueLogger.info(`Deleting branch for as delete-branch option was specified`);
yield this._deleteBranch(issue);
this.deletedBranchIssues.push(issue);
}
}
else {
issueLogger.info(`Stale ${issueType} is not old enough to close yet (hasComments? ${issueHasComments}, hasUpdate? ${issueHasUpdate})`);
issueLogger.info(`Stale $$type is not old enough to close yet (hasComments? ${issueHasComments}, hasUpdate? ${issueHasUpdate})`);
}
});
}
@ -263,7 +406,7 @@ class IssuesProcessor {
_hasCommentsSince(issue, sinceDate, actor) {
return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Checking for comments on issue #${issue.number} since ${sinceDate}`);
issueLogger.info(`Checking for comments on $$type since ${sinceDate}`);
if (!sinceDate) {
return true;
}
@ -334,7 +477,7 @@ class IssuesProcessor {
_markStale(issue, staleMessage, staleLabel, skipMessage) {
return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Marking issue #${issue.number} as stale`);
issueLogger.info(`Marking $$type as stale`);
this.staleIssues.push(issue);
this._operationsLeft -= 2;
// if the issue is being marked stale, the updated date should be changed to right now
@ -374,7 +517,7 @@ class IssuesProcessor {
_closeIssue(issue, closeMessage, closeLabel) {
return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Closing issue #${issue.number} for being stale`);
issueLogger.info(`Closing $$type for being stale`);
this.closedIssues.push(issue);
this._operationsLeft -= 1;
if (this.options.debugOnly) {
@ -415,7 +558,7 @@ class IssuesProcessor {
});
}
catch (error) {
issueLogger.error(`Error updating an issue: ${error.message}`);
issueLogger.error(`Error updating this $$type: ${error.message}`);
}
});
}
@ -432,7 +575,7 @@ class IssuesProcessor {
return pullRequest.data;
}
catch (error) {
issueLogger.error(`Error getting pull request ${issue.number}: ${error.message}`);
issueLogger.error(`Error getting this $$type: ${error.message}`);
}
});
}
@ -440,17 +583,17 @@ class IssuesProcessor {
_deleteBranch(issue) {
return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Delete branch from closed issue #${issue.number} - ${issue.title}`);
issueLogger.info(`Delete branch from closed $$type - ${issue.title}`);
if (this.options.debugOnly) {
return;
}
const pullRequest = yield this._getPullRequest(issue);
if (!pullRequest) {
issueLogger.info(`Not deleting branch as pull request not found for issue ${issue.number}`);
issueLogger.info(`Not deleting branch as pull request not found for this $$type`);
return;
}
const branch = pullRequest.head.ref;
issueLogger.info(`Deleting branch ${branch} from closed issue #${issue.number}`);
issueLogger.info(`Deleting branch ${branch} from closed $$type`);
this._operationsLeft -= 1;
try {
yield this.client.git.deleteRef({
@ -460,7 +603,7 @@ class IssuesProcessor {
});
}
catch (error) {
issueLogger.error(`Error deleting branch ${branch} from issue #${issue.number}: ${error.message}`);
issueLogger.error(`Error deleting branch ${branch} from $$type: ${error.message}`);
}
});
}
@ -468,7 +611,7 @@ class IssuesProcessor {
_removeLabel(issue, label) {
return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Removing label "${label}" from issue #${issue.number}`);
issueLogger.info(`Removing label "${label}" from $$type`);
this.removedLabelIssues.push(issue);
this._operationsLeft -= 1;
// @todo remove the debug only to be able to test the code below
@ -493,7 +636,7 @@ class IssuesProcessor {
_getLabelCreationDate(issue, label) {
return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Checking for label on issue #${issue.number}`);
issueLogger.info(`Checking for label on $$type`);
this._operationsLeft -= 1;
const options = this.client.issues.listEvents.endpoint.merge({
owner: github_1.context.repo.owner,
@ -534,7 +677,7 @@ class IssuesProcessor {
_removeStaleLabel(issue, staleLabel) {
return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Issue #${issue.number} is no longer stale. Removing stale label.`);
issueLogger.info(`$$type is no longer stale. Removing stale label.`);
return this._removeLabel(issue, staleLabel);
});
}
@ -571,18 +714,39 @@ var __importStar = (this && this.__importStar) || function (mod) {
Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.IssueLogger = void 0;
const core = __importStar(__nccwpck_require__(2186));
/**
* @description
* Each log will prefix the message with the issue number
*
* @example
* warning('No stale') => "[#123] No stale"
*
* Each log method can have special tokens:
* - $$type => will replace this by either "pull request" or "issue" depending of the type of issue
*
* @example
* warning('The $$type will stale') => "The pull request will stale"
*/
class IssueLogger {
constructor(issue) {
this._issue = issue;
}
warning(message) {
core.warning(this._prefixWithIssueNumber(message));
core.warning(this._format(message));
}
info(message) {
core.info(this._prefixWithIssueNumber(message));
core.info(this._format(message));
}
error(message) {
core.error(this._prefixWithIssueNumber(message));
core.error(this._format(message));
}
_replaceTokens(message) {
return this._replaceTypeToken(message);
}
_replaceTypeToken(message) {
return message
.replace(/^\$\$type/, this._issue.isPullRequest ? 'Pull request' : 'Issue')
.replace(/\$\$type/g, this._issue.isPullRequest ? 'pull request' : 'issue');
}
_prefixWithIssueNumber(message) {
return `[#${this._getIssueNumber()}] ${message}`;
@ -590,6 +754,9 @@ class IssueLogger {
_getIssueNumber() {
return this._issue.number;
}
_format(message) {
return this._prefixWithIssueNumber(this._replaceTokens(message));
}
}
exports.IssueLogger = IssueLogger;
@ -656,8 +823,8 @@ class Milestones {
this._options = options;
this._issue = issue;
}
static _cleanMilestone(label) {
return lodash_deburr_1.default(label.toLowerCase());
static _cleanMilestone(milestone) {
return lodash_deburr_1.default(milestone.toLowerCase());
}
shouldExemptMilestones() {
if (this._shouldExemptAllMilestones()) {
@ -1002,7 +1169,13 @@ function _getAndValidateArgs() {
exemptPrMilestones: core.getInput('exempt-pr-milestones'),
exemptAllMilestones: core.getInput('exempt-all-milestones') === 'true',
exemptAllIssueMilestones: _toOptionalBoolean('exempt-all-issue-milestones'),
exemptAllPrMilestones: _toOptionalBoolean('exempt-all-pr-milestones')
exemptAllPrMilestones: _toOptionalBoolean('exempt-all-pr-milestones'),
exemptAssignees: core.getInput('exempt-assignees'),
exemptIssueAssignees: core.getInput('exempt-issue-assignees'),
exemptPrAssignees: core.getInput('exempt-pr-assignees'),
exemptAllAssignees: core.getInput('exempt-all-assignees') === 'true',
exemptAllIssueAssignees: _toOptionalBoolean('exempt-all-issue-assignees'),
exemptAllPrAssignees: _toOptionalBoolean('exempt-all-pr-assignees')
};
for (const numberInput of [
'days-before-stale',

61
package-lock.json generated
View File

@ -7140,6 +7140,67 @@
}
}
},
"jest-silent-reporter": {
"version": "0.4.0",
"resolved": "https://registry.npmjs.org/jest-silent-reporter/-/jest-silent-reporter-0.4.0.tgz",
"integrity": "sha512-X9pLv87dOba/Ou6E3MrT0HmszG56oZSykgyhIlcL9SErjikPObprxAz58831g4Ngl8TKwpU73pAfkPpjYaMSxg==",
"dev": true,
"requires": {
"chalk": "^4.0.0",
"jest-util": "^26.0.0"
},
"dependencies": {
"ansi-styles": {
"version": "4.3.0",
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-4.3.0.tgz",
"integrity": "sha512-zbB9rCJAT1rbjiVDb2hqKFHNYLxgtk8NURxZ3IZwD3F6NtxbXZQCnnSi1Lkx+IDohdPlFp222wVALIheZJQSEg==",
"dev": true,
"requires": {
"color-convert": "^2.0.1"
}
},
"chalk": {
"version": "4.1.0",
"resolved": "https://registry.npmjs.org/chalk/-/chalk-4.1.0.tgz",
"integrity": "sha512-qwx12AxXe2Q5xQ43Ac//I6v5aXTipYrSESdOgzrN+9XjgEpyjpKuvSGaN4qE93f7TQTlerQQ8S+EQ0EyDoVL1A==",
"dev": true,
"requires": {
"ansi-styles": "^4.1.0",
"supports-color": "^7.1.0"
}
},
"color-convert": {
"version": "2.0.1",
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-2.0.1.tgz",
"integrity": "sha512-RRECPsj7iu/xb5oKYcsFHSppFNnsj/52OVTRKb4zP5onXwVF3zVmmToNcOfGC+CRDpfK/U584fMg38ZHCaElKQ==",
"dev": true,
"requires": {
"color-name": "~1.1.4"
}
},
"color-name": {
"version": "1.1.4",
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.4.tgz",
"integrity": "sha512-dOy+3AuW3a2wNbZHIuMZpTcgjGuLU/uBL/ubcZF9OXbDo8ff4O8yVp5Bf0efS8uEoYo5q4Fx7dY9OgQGXgAsQA==",
"dev": true
},
"has-flag": {
"version": "4.0.0",
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-4.0.0.tgz",
"integrity": "sha512-EykJT/Q1KjTWctppgIAgfSO0tKVuZUjhgMr17kqTumMl6Afv3EISleU7qZUzoXDFTAHTDC4NOoG/ZxU3EvlMPQ==",
"dev": true
},
"supports-color": {
"version": "7.2.0",
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-7.2.0.tgz",
"integrity": "sha512-qpCAvRl9stuOHveKsn7HncJRvv501qIacKzQlO/+Lwxc9+0q2wLyv4Dfvt80/DPn2pqOBsJdDiogXGR9+OvwRw==",
"dev": true,
"requires": {
"has-flag": "^4.0.0"
}
}
}
},
"jest-snapshot": {
"version": "26.6.2",
"resolved": "https://registry.npmjs.org/jest-snapshot/-/jest-snapshot-26.6.2.tgz",

View File

@ -14,6 +14,8 @@
"lint:all:fix": "npm run format && npm run lint:fix",
"pack": "ncc build",
"test": "jest",
"test:only-errors": "jest --reporters jest-silent-reporter --silent",
"test:watch": "jest --watch --notify --expandf",
"all": "npm run build && npm run format && npm run lint && npm run pack && npm test"
},
"repository": {
@ -47,6 +49,7 @@
"eslint-plugin-jest": "^24.1.5",
"jest": "^26.6.3",
"jest-circus": "^26.6.3",
"jest-silent-reporter": "^0.4.0",
"js-yaml": "^4.0.0",
"prettier": "^2.2.1",
"ts-jest": "^26.5.1",

View File

@ -0,0 +1,594 @@
import {DefaultProcessorOptions} from '../../__tests__/constants/default-processor-options';
import {generateIIssue} from '../../__tests__/functions/generate-iissue';
import {IIssue} from '../interfaces/issue';
import {IIssuesProcessorOptions} from '../interfaces/issues-processor-options';
import {Issue} from './issue';
import {Assignees} from './assignees';
describe('Assignees', (): void => {
let assignees: Assignees;
let optionsInterface: IIssuesProcessorOptions;
let issue: Issue;
let issueInterface: IIssue;
beforeEach((): void => {
optionsInterface = {...DefaultProcessorOptions};
issueInterface = generateIIssue();
});
describe('shouldExemptAssignees()', (): void => {
describe('when the given issue is not a pull request', (): void => {
beforeEach((): void => {
issueInterface.pull_request = undefined;
});
describe('when the given options are not configured to exempt an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptAssignees = '';
});
describe('when the given options are not configured to exempt an issue with an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptIssueAssignees = '';
});
describe('when the given issue does not have an assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
});
describe('when the given options are configured to exempt an issue with an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptIssueAssignees =
'dummy-exempt-issue-assignee';
});
describe('when the given issue does not have an assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee different than the exempt issue assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee equaling the exempt issue assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-exempt-issue-assignee'
}
];
});
it('should return true', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(true);
});
});
});
});
describe('when the given options are configured to exempt an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptAssignees = 'dummy-exempt-assignee';
});
describe('when the given options are not configured to exempt an issue with an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptIssueAssignees = '';
});
describe('when the given issue does not have an assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee different than the exempt assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee equaling the exempt assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-exempt-assignee'
}
];
});
it('should return true', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(true);
});
});
});
describe('when the given options are configured to exempt an issue with an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptIssueAssignees =
'dummy-exempt-issue-assignee';
});
describe('when the given issue does not have an assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee different than the exempt issue assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee equaling the exempt issue assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-exempt-issue-assignee'
}
];
});
it('should return true', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(true);
});
});
describe('when the given issue does have an assignee different than the exempt assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee equaling the exempt assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-exempt-assignee'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
});
});
});
describe('when the given issue is a pull request', (): void => {
beforeEach((): void => {
issueInterface.pull_request = {};
});
describe('when the given options are not configured to exempt an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptAssignees = '';
});
describe('when the given options are not configured to exempt a pull request with an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptPrAssignees = '';
});
describe('when the given issue does not have an assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
});
describe('when the given options are configured to exempt a pull request with an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptPrAssignees = 'dummy-exempt-pr-assignee';
});
describe('when the given issue does not have an assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee different than the exempt pull request assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee equaling the exempt pull request assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-exempt-pr-assignee'
}
];
});
it('should return true', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(true);
});
});
});
});
describe('when the given options are configured to exempt an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptAssignees = 'dummy-exempt-assignee';
});
describe('when the given options are not configured to exempt a pull request with an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptPrAssignees = '';
});
describe('when the given issue does not have an assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee different than the exempt assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee equaling the exempt assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-exempt-assignee'
}
];
});
it('should return true', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(true);
});
});
});
describe('when the given options are configured to exempt a pull request with an assignee', (): void => {
beforeEach((): void => {
optionsInterface.exemptPrAssignees = 'dummy-exempt-pr-assignee';
});
describe('when the given issue does not have an assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee different than the exempt pull request assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee equaling the exempt pull request assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-exempt-pr-assignee'
}
];
});
it('should return true', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(true);
});
});
describe('when the given issue does have an assignee different than the exempt assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
describe('when the given issue does have an assignee equaling the exempt assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-exempt-assignee'
}
];
});
it('should return false', (): void => {
expect.assertions(1);
issue = new Issue(optionsInterface, issueInterface);
assignees = new Assignees(optionsInterface, issue);
const result = assignees.shouldExemptAssignees();
expect(result).toStrictEqual(false);
});
});
});
});
});
});
});

251
src/classes/assignees.ts Normal file
View File

@ -0,0 +1,251 @@
import deburr from 'lodash.deburr';
import {wordsToList} from '../functions/words-to-list';
import {IAssignee} from '../interfaces/assignee';
import {IIssuesProcessorOptions} from '../interfaces/issues-processor-options';
import {Issue} from './issue';
import {IssueLogger} from './loggers/issue-logger';
type CleanAssignee = string;
export class Assignees {
private static _cleanAssignee(assignee: Readonly<string>): CleanAssignee {
return deburr(assignee.toLowerCase());
}
private readonly _options: IIssuesProcessorOptions;
private readonly _issue: Issue;
private readonly _issueLogger: IssueLogger;
constructor(options: Readonly<IIssuesProcessorOptions>, issue: Issue) {
this._options = options;
this._issue = issue;
this._issueLogger = new IssueLogger(issue);
}
shouldExemptAssignees(): boolean {
if (!this._issue.hasAssignees) {
this._issueLogger.info('This $$type has no assignee');
this._logSkip();
return false;
}
if (this._shouldExemptAllAssignees()) {
this._issueLogger.info(
'Skipping $$type because it has an exempt assignee'
);
return true;
}
const exemptAssignees: string[] = this._getExemptAssignees();
if (exemptAssignees.length === 0) {
this._issueLogger.info(
`No option was specified to skip the stale process for this $$type`
);
this._logSkip();
return false;
}
this._issueLogger.info(
`Found ${exemptAssignees.length} assignee${
exemptAssignees.length > 1 ? 's' : ''
} on this $$type`
);
const hasExemptAssignee: boolean = exemptAssignees.some(
(exemptAssignee: Readonly<string>): boolean =>
this._hasAssignee(exemptAssignee)
);
if (!hasExemptAssignee) {
this._issueLogger.info(
'No assignee on this $$type can exempt the stale process'
);
this._logSkip();
} else {
this._issueLogger.info(
'Skipping this $$type because it has an exempt assignee'
);
}
return hasExemptAssignee;
}
private _getExemptAssignees(): string[] {
return this._issue.isPullRequest
? this._getExemptPullRequestAssignees()
: this._getExemptIssueAssignees();
}
private _getExemptIssueAssignees(): string[] {
if (this._options.exemptIssueAssignees === '') {
this._issueLogger.info(
'The option "exemptIssueAssignees" is disabled. No specific assignee can skip the stale process for this $$type'
);
if (this._options.exemptAssignees === '') {
this._issueLogger.info(
'The option "exemptAssignees" is disabled. No specific assignee can skip the stale process for this $$type'
);
return [];
}
const exemptAssignees: string[] = wordsToList(
this._options.exemptAssignees
);
this._issueLogger.info(
`The option "exemptAssignees" is set. ${
exemptAssignees.length
} assignee${
exemptAssignees.length === 1 ? '' : 's'
} can skip the stale process for this $$type`
);
return exemptAssignees;
}
const exemptAssignees: string[] = wordsToList(
this._options.exemptIssueAssignees
);
this._issueLogger.info(
`The option "exemptIssueAssignees" is set. ${
exemptAssignees.length
} assignee${
exemptAssignees.length === 1 ? '' : 's'
} can skip the stale process for this $$type`
);
return exemptAssignees;
}
private _getExemptPullRequestAssignees(): string[] {
if (this._options.exemptPrAssignees === '') {
this._issueLogger.info(
'The option "exemptPrAssignees" is disabled. No specific assignee can skip the stale process for this $$type'
);
if (this._options.exemptAssignees === '') {
this._issueLogger.info(
'The option "exemptAssignees" is disabled. No specific assignee can skip the stale process for this $$type'
);
return [];
}
const exemptAssignees: string[] = wordsToList(
this._options.exemptAssignees
);
this._issueLogger.info(
`The option "exemptAssignees" is set. ${
exemptAssignees.length
} assignee${
exemptAssignees.length === 1 ? '' : 's'
} can skip the stale process for this $$type`
);
return exemptAssignees;
}
const exemptAssignees: string[] = wordsToList(
this._options.exemptPrAssignees
);
this._issueLogger.info(
`The option "exemptPrAssignees" is set. ${
exemptAssignees.length
} assignee${
exemptAssignees.length === 1 ? '' : 's'
} can skip the stale process for this $$type`
);
return exemptAssignees;
}
private _hasAssignee(assignee: Readonly<string>): boolean {
const cleanAssignee: CleanAssignee = Assignees._cleanAssignee(assignee);
return this._issue.assignees.some(
(issueAssignee: Readonly<IAssignee>): boolean => {
const isSameAssignee: boolean =
cleanAssignee === Assignees._cleanAssignee(issueAssignee.login);
if (isSameAssignee) {
this._issueLogger.info(
`@${issueAssignee.login} is assigned on this $$type and is an exempt assignee`
);
}
return isSameAssignee;
}
);
}
private _shouldExemptAllAssignees(): boolean {
return this._issue.isPullRequest
? this._shouldExemptAllPullRequestAssignees()
: this._shouldExemptAllIssueAssignees();
}
private _shouldExemptAllIssueAssignees(): boolean {
if (this._options.exemptAllIssueAssignees === true) {
this._issueLogger.info(
'The option "exemptAllIssueAssignees" is enabled. Any assignee on this $$type will skip the stale process'
);
return true;
} else if (this._options.exemptAllIssueAssignees === false) {
this._issueLogger.info(
'The option "exemptAllIssueAssignees" is disabled. Only some specific assignees on this $$type will skip the stale process'
);
return false;
}
this._logExemptAllAssigneesOption();
return this._options.exemptAllAssignees;
}
private _shouldExemptAllPullRequestAssignees(): boolean {
if (this._options.exemptAllPrAssignees === true) {
this._issueLogger.info(
'The option "exemptAllPrAssignees" is enabled. Any assignee on this $$type will skip the stale process'
);
return true;
} else if (this._options.exemptAllPrAssignees === false) {
this._issueLogger.info(
'The option "exemptAllPrAssignees" is disabled. Only some specific assignees on this $$type will skip the stale process'
);
return false;
}
this._logExemptAllAssigneesOption();
return this._options.exemptAllAssignees;
}
private _logExemptAllAssigneesOption(): void {
if (this._options.exemptAllAssignees) {
this._issueLogger.info(
'The option "exemptAllAssignees" is enabled. Any assignee on this $$type will skip the stale process'
);
} else {
this._issueLogger.info(
'The option "exemptAllAssignees" is disabled. Only some specific assignees on this $$type will skip the stale process'
);
}
}
private _logSkip(): void {
this._issueLogger.info('Skip the assignees checks');
}
}

View File

@ -1,3 +1,4 @@
import {IAssignee} from '../interfaces/assignee';
import {IIssue} from '../interfaces/issue';
import {IIssuesProcessorOptions} from '../interfaces/issues-processor-options';
import {ILabel} from '../interfaces/label';
@ -25,10 +26,7 @@ describe('Issue', (): void => {
debugOnly: false,
deleteBranch: false,
exemptIssueLabels: '',
exemptIssueMilestones: '',
exemptMilestones: '',
exemptPrLabels: '',
exemptPrMilestones: '',
onlyLabels: '',
operationsPerRun: 0,
removeStaleWhenUpdated: false,
@ -40,9 +38,18 @@ describe('Issue', (): void => {
startDate: undefined,
stalePrLabel: 'dummy-stale-pr-label',
staleIssueLabel: 'dummy-stale-issue-label',
exemptMilestones: '',
exemptIssueMilestones: '',
exemptPrMilestones: '',
exemptAllMilestones: false,
exemptAllIssueMilestones: undefined,
exemptAllPrMilestones: undefined
exemptAllPrMilestones: undefined,
exemptAssignees: '',
exemptIssueAssignees: '',
exemptPrAssignees: '',
exemptAllAssignees: false,
exemptAllIssueAssignees: undefined,
exemptAllPrAssignees: undefined
};
issueInterface = {
title: 'dummy-title',
@ -59,7 +66,12 @@ describe('Issue', (): void => {
locked: false,
milestone: {
title: 'dummy-milestone'
}
},
assignees: [
{
login: 'dummy-login'
}
]
};
issue = new Issue(optionsInterface, issueInterface);
});
@ -125,56 +137,14 @@ describe('Issue', (): void => {
} as IMilestone);
});
describe('when the given issue pull_request is not set', (): void => {
beforeEach((): void => {
issueInterface.pull_request = undefined;
issue = new Issue(optionsInterface, issueInterface);
});
it('should set the assignees with the given issue assignees', (): void => {
expect.assertions(1);
it('should set the isPullRequest to false', (): void => {
expect.assertions(1);
expect(issue.isPullRequest).toStrictEqual(false);
});
});
describe('when the given issue pull_request is set', (): void => {
beforeEach((): void => {
issueInterface.pull_request = {};
issue = new Issue(optionsInterface, issueInterface);
});
it('should set the isPullRequest to true', (): void => {
expect.assertions(1);
expect(issue.isPullRequest).toStrictEqual(true);
});
});
describe('when the given issue is not a pull request', (): void => {
beforeEach((): void => {
issueInterface.pull_request = undefined;
issue = new Issue(optionsInterface, issueInterface);
});
it('should set the staleLabel with the given option staleIssueLabel', (): void => {
expect.assertions(1);
expect(issue.staleLabel).toStrictEqual('dummy-stale-issue-label');
});
});
describe('when the given issue is a pull request', (): void => {
beforeEach((): void => {
issueInterface.pull_request = {};
issue = new Issue(optionsInterface, issueInterface);
});
it('should set the staleLabel with the given option stalePrLabel', (): void => {
expect.assertions(1);
expect(issue.staleLabel).toStrictEqual('dummy-stale-pr-label');
});
expect(issue.assignees).toStrictEqual([
{
login: 'dummy-login'
} as IAssignee
]);
});
describe('when the given issue does not contains the stale label', (): void => {
@ -209,4 +179,104 @@ describe('Issue', (): void => {
});
});
});
describe('get isPullRequest', (): void => {
describe('when the issue pull_request is not set', (): void => {
beforeEach((): void => {
issueInterface.pull_request = undefined;
issue = new Issue(optionsInterface, issueInterface);
});
it('should return false', (): void => {
expect.assertions(1);
const result = issue.isPullRequest;
expect(result).toStrictEqual(false);
});
});
describe('when the issue pull_request is set', (): void => {
beforeEach((): void => {
issueInterface.pull_request = {};
issue = new Issue(optionsInterface, issueInterface);
});
it('should return true', (): void => {
expect.assertions(1);
const result = issue.isPullRequest;
expect(result).toStrictEqual(true);
});
});
});
describe('get staleLabel', (): void => {
describe('when the issue is not a pull request', (): void => {
beforeEach((): void => {
issueInterface.pull_request = undefined;
issue = new Issue(optionsInterface, issueInterface);
});
it('should return the issue stale label', (): void => {
expect.assertions(1);
const result = issue.staleLabel;
expect(result).toStrictEqual('dummy-stale-issue-label');
});
});
describe('when the given issue is a pull request', (): void => {
beforeEach((): void => {
issueInterface.pull_request = {};
issue = new Issue(optionsInterface, issueInterface);
});
it('should return the pull request stale label', (): void => {
expect.assertions(1);
const result = issue.staleLabel;
expect(result).toStrictEqual('dummy-stale-pr-label');
});
});
});
describe('get hasAssignees', (): void => {
describe('when the issue has no assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [];
issue = new Issue(optionsInterface, issueInterface);
});
it('should return false', (): void => {
expect.assertions(1);
const result = issue.hasAssignees;
expect(result).toStrictEqual(false);
});
});
describe('when the issue has at least one assignee', (): void => {
beforeEach((): void => {
issueInterface.assignees = [
{
login: 'dummy-login'
}
];
issue = new Issue(optionsInterface, issueInterface);
});
it('should return true', (): void => {
expect.assertions(1);
const result = issue.hasAssignees;
expect(result).toStrictEqual(true);
});
});
});
});

View File

@ -1,5 +1,6 @@
import {isLabeled} from '../functions/is-labeled';
import {isPullRequest} from '../functions/is-pull-request';
import {IAssignee} from '../interfaces/assignee';
import {IIssue} from '../interfaces/issue';
import {IIssuesProcessorOptions} from '../interfaces/issues-processor-options';
import {ILabel} from '../interfaces/label';
@ -17,8 +18,7 @@ export class Issue implements IIssue {
readonly state: string;
readonly locked: boolean;
readonly milestone: IMilestone | undefined;
readonly isPullRequest: boolean;
readonly staleLabel: string;
readonly assignees: IAssignee[];
isStale: boolean;
constructor(
@ -35,12 +35,23 @@ export class Issue implements IIssue {
this.state = issue.state;
this.locked = issue.locked;
this.milestone = issue.milestone;
this.assignees = issue.assignees;
this.isPullRequest = isPullRequest(this);
this.staleLabel = this._getStaleLabel();
this.isStale = isLabeled(this, this.staleLabel);
}
get isPullRequest(): boolean {
return isPullRequest(this);
}
get staleLabel(): string {
return this._getStaleLabel();
}
get hasAssignees(): boolean {
return this.assignees.length > 0;
}
private _getStaleLabel(): string {
return this.isPullRequest
? this._options.stalePrLabel

View File

@ -15,6 +15,7 @@ import {IIssue} from '../interfaces/issue';
import {IIssueEvent} from '../interfaces/issue-event';
import {IIssuesProcessorOptions} from '../interfaces/issues-processor-options';
import {IPullRequest} from '../interfaces/pull-request';
import {Assignees} from './assignees';
import {Issue} from './issue';
import {IssueLogger} from './loggers/issue-logger';
import {Logger} from './loggers/logger';
@ -97,9 +98,7 @@ export class IssuesProcessor {
for (const issue of issues.values()) {
const issueLogger: IssueLogger = new IssueLogger(issue);
issueLogger.info(
`Found issue: issue #${issue.number} last updated ${issue.updated_at} (is pr? ${issue.isPullRequest})`
);
issueLogger.info(`Found this $$type last updated ${issue.updated_at}`);
// calculate string based messages for this issue
const staleMessage: string = issue.isPullRequest
@ -122,26 +121,22 @@ export class IssuesProcessor {
? this._getDaysBeforePrStale()
: this._getDaysBeforeIssueStale();
if (issue.isPullRequest) {
issueLogger.info(`Days before pull request stale: ${daysBeforeStale}`);
} else {
issueLogger.info(`Days before issue stale: ${daysBeforeStale}`);
}
issueLogger.info(`Days before $$type stale: ${daysBeforeStale}`);
const shouldMarkAsStale: boolean = shouldMarkWhenStale(daysBeforeStale);
if (!staleMessage && shouldMarkAsStale) {
issueLogger.info(`Skipping ${issueType} due to empty stale message`);
issueLogger.info(`Skipping $$type due to empty stale message`);
continue;
}
if (issue.state === 'closed') {
issueLogger.info(`Skipping ${issueType} because it is closed`);
issueLogger.info(`Skipping $$type because it is closed`);
continue; // don't process closed issues
}
if (issue.locked) {
issueLogger.info(`Skipping ${issueType} because it is locked`);
issueLogger.info(`Skipping $$type because it is locked`);
continue; // don't process locked issues
}
@ -164,14 +159,14 @@ export class IssuesProcessor {
}
issueLogger.info(
`Issue created the ${getHumanizedDate(createdAt)} (${
`$$type created the ${getHumanizedDate(createdAt)} (${
issue.created_at
})`
);
if (!isDateMoreRecentThan(createdAt, startDate)) {
issueLogger.info(
`Skipping ${issueType} because it was created before the specified start date`
`Skipping $$type because it was created before the specified start date`
);
continue; // don't process issues which were created before the start date
@ -179,9 +174,9 @@ export class IssuesProcessor {
}
if (issue.isStale) {
issueLogger.info(`This issue has a stale label`);
issueLogger.info(`This $$type has a stale label`);
} else {
issueLogger.info(`This issue hasn't a stale label`);
issueLogger.info(`This $$type hasn't a stale label`);
}
const exemptLabels: string[] = wordsToList(
@ -200,9 +195,7 @@ export class IssuesProcessor {
await this._removeStaleLabel(issue, staleLabel);
}
issueLogger.info(
`Skipping ${issueType} because it has an exempt label`
);
issueLogger.info(`Skipping $$type because it has an exempt label`);
continue; // don't process exempt issues
}
@ -210,11 +203,17 @@ export class IssuesProcessor {
if (milestones.shouldExemptMilestones()) {
issueLogger.info(
`Skipping ${issueType} because it has an exempt milestone`
`Skipping $$type because it has an exempted milestone`
);
continue; // don't process exempt milestones
}
const assignees: Assignees = new Assignees(this.options, issue);
if (assignees.shouldExemptAssignees()) {
continue; // don't process exempt assignees
}
// should this issue be marked stale?
const shouldBeStale = !IssuesProcessor._updatedSince(
issue.updated_at,
@ -224,7 +223,7 @@ export class IssuesProcessor {
// determine if this issue needs to be marked stale first
if (!issue.isStale && shouldBeStale && shouldMarkAsStale) {
issueLogger.info(
`Marking ${issueType} stale because it was last updated on ${issue.updated_at} and it does not have a stale label`
`Marking $$type stale because it was last updated on ${issue.updated_at} and it does not have a stale label`
);
await this._markStale(issue, staleMessage, staleLabel, skipMessage);
issue.isStale = true; // this issue is now considered stale
@ -236,7 +235,7 @@ export class IssuesProcessor {
// process the issue if it was marked stale
if (issue.isStale) {
issueLogger.info(`Found a stale ${issueType}`);
issueLogger.info(`Found a stale $$type`);
await this._processStaleIssue(
issue,
issueType,
@ -271,37 +270,27 @@ export class IssuesProcessor {
const issueLogger: IssueLogger = new IssueLogger(issue);
const markedStaleOn: string =
(await this._getLabelCreationDate(issue, staleLabel)) || issue.updated_at;
issueLogger.info(
`Issue #${issue.number} marked stale on: ${markedStaleOn}`
);
issueLogger.info(`$$type marked stale on: ${markedStaleOn}`);
const issueHasComments: boolean = await this._hasCommentsSince(
issue,
markedStaleOn,
actor
);
issueLogger.info(
`Issue #${issue.number} has been commented on: ${issueHasComments}`
);
issueLogger.info(`$$type has been commented on: ${issueHasComments}`);
const isPr: boolean = isPullRequest(issue);
const daysBeforeClose: number = isPr
? this._getDaysBeforePrClose()
: this._getDaysBeforeIssueClose();
if (isPr) {
issueLogger.info(`Days before pull request close: ${daysBeforeClose}`);
} else {
issueLogger.info(`Days before issue close: ${daysBeforeClose}`);
}
issueLogger.info(`Days before $$type close: ${daysBeforeClose}`);
const issueHasUpdate: boolean = IssuesProcessor._updatedSince(
issue.updated_at,
daysBeforeClose
);
issueLogger.info(
`Issue #${issue.number} has been updated: ${issueHasUpdate}`
);
issueLogger.info(`$$type has been updated: ${issueHasUpdate}`);
// should we un-stale this issue?
if (this.options.removeStaleWhenUpdated && issueHasComments) {
@ -315,20 +304,20 @@ export class IssuesProcessor {
if (!issueHasComments && !issueHasUpdate) {
issueLogger.info(
`Closing ${issueType} because it was last updated on ${issue.updated_at}`
`Closing $$type because it was last updated on ${issue.updated_at}`
);
await this._closeIssue(issue, closeMessage, closeLabel);
if (this.options.deleteBranch && issue.pull_request) {
issueLogger.info(
`Deleting branch for #${issue.number} as delete-branch option was specified`
`Deleting branch for as delete-branch option was specified`
);
await this._deleteBranch(issue);
this.deletedBranchIssues.push(issue);
}
} else {
issueLogger.info(
`Stale ${issueType} is not old enough to close yet (hasComments? ${issueHasComments}, hasUpdate? ${issueHasUpdate})`
`Stale $$type is not old enough to close yet (hasComments? ${issueHasComments}, hasUpdate? ${issueHasUpdate})`
);
}
}
@ -341,9 +330,7 @@ export class IssuesProcessor {
): Promise<boolean> {
const issueLogger: IssueLogger = new IssueLogger(issue);
issueLogger.info(
`Checking for comments on issue #${issue.number} since ${sinceDate}`
);
issueLogger.info(`Checking for comments on $$type since ${sinceDate}`);
if (!sinceDate) {
return true;
@ -433,7 +420,7 @@ export class IssuesProcessor {
): Promise<void> {
const issueLogger: IssueLogger = new IssueLogger(issue);
issueLogger.info(`Marking issue #${issue.number} as stale`);
issueLogger.info(`Marking $$type as stale`);
this.staleIssues.push(issue);
@ -481,7 +468,7 @@ export class IssuesProcessor {
): Promise<void> {
const issueLogger: IssueLogger = new IssueLogger(issue);
issueLogger.info(`Closing issue #${issue.number} for being stale`);
issueLogger.info(`Closing $$type for being stale`);
this.closedIssues.push(issue);
@ -525,7 +512,7 @@ export class IssuesProcessor {
state: 'closed'
});
} catch (error) {
issueLogger.error(`Error updating an issue: ${error.message}`);
issueLogger.error(`Error updating this $$type: ${error.message}`);
}
}
@ -544,9 +531,7 @@ export class IssuesProcessor {
return pullRequest.data;
} catch (error) {
issueLogger.error(
`Error getting pull request ${issue.number}: ${error.message}`
);
issueLogger.error(`Error getting this $$type: ${error.message}`);
}
}
@ -554,9 +539,7 @@ export class IssuesProcessor {
private async _deleteBranch(issue: Issue): Promise<void> {
const issueLogger: IssueLogger = new IssueLogger(issue);
issueLogger.info(
`Delete branch from closed issue #${issue.number} - ${issue.title}`
);
issueLogger.info(`Delete branch from closed $$type - ${issue.title}`);
if (this.options.debugOnly) {
return;
@ -566,15 +549,13 @@ export class IssuesProcessor {
if (!pullRequest) {
issueLogger.info(
`Not deleting branch as pull request not found for issue ${issue.number}`
`Not deleting branch as pull request not found for this $$type`
);
return;
}
const branch = pullRequest.head.ref;
issueLogger.info(
`Deleting branch ${branch} from closed issue #${issue.number}`
);
issueLogger.info(`Deleting branch ${branch} from closed $$type`);
this._operationsLeft -= 1;
@ -586,7 +567,7 @@ export class IssuesProcessor {
});
} catch (error) {
issueLogger.error(
`Error deleting branch ${branch} from issue #${issue.number}: ${error.message}`
`Error deleting branch ${branch} from $$type: ${error.message}`
);
}
}
@ -595,7 +576,7 @@ export class IssuesProcessor {
private async _removeLabel(issue: Issue, label: string): Promise<void> {
const issueLogger: IssueLogger = new IssueLogger(issue);
issueLogger.info(`Removing label "${label}" from issue #${issue.number}`);
issueLogger.info(`Removing label "${label}" from $$type`);
this.removedLabelIssues.push(issue);
@ -626,7 +607,7 @@ export class IssuesProcessor {
): Promise<string | undefined> {
const issueLogger: IssueLogger = new IssueLogger(issue);
issueLogger.info(`Checking for label on issue #${issue.number}`);
issueLogger.info(`Checking for label on $$type`);
this._operationsLeft -= 1;
@ -682,9 +663,7 @@ export class IssuesProcessor {
): Promise<void> {
const issueLogger: IssueLogger = new IssueLogger(issue);
issueLogger.info(
`Issue #${issue.number} is no longer stale. Removing stale label.`
);
issueLogger.info(`$$type is no longer stale. Removing stale label.`);
return this._removeLabel(issue, staleLabel);
}

View File

@ -1,3 +1,5 @@
import {DefaultProcessorOptions} from '../../../__tests__/constants/default-processor-options';
import {generateIIssue} from '../../../__tests__/functions/generate-iissue';
import {Issue} from '../issue';
import {IssueLogger} from './issue-logger';
import * as core from '@actions/core';
@ -5,21 +7,20 @@ import * as core from '@actions/core';
describe('IssueLogger', (): void => {
let issue: Issue;
let issueLogger: IssueLogger;
let message: string;
beforeEach((): void => {
issue = {
number: 8
} as Issue;
issueLogger = new IssueLogger(issue);
});
let coreWarningSpy: jest.SpyInstance;
describe('warning()', (): void => {
let message: string;
let coreWarningSpy: jest.SpyInstance;
beforeEach((): void => {
message = 'dummy-message';
issue = new Issue(
DefaultProcessorOptions,
generateIIssue({
number: 8
})
);
issueLogger = new IssueLogger(issue);
coreWarningSpy = jest.spyOn(core, 'warning').mockImplementation();
});
@ -35,12 +36,17 @@ describe('IssueLogger', (): void => {
});
describe('info()', (): void => {
let message: string;
let coreInfoSpy: jest.SpyInstance;
beforeEach((): void => {
message = 'dummy-message';
issue = new Issue(
DefaultProcessorOptions,
generateIIssue({
number: 8
})
);
issueLogger = new IssueLogger(issue);
coreInfoSpy = jest.spyOn(core, 'info').mockImplementation();
});
@ -56,12 +62,17 @@ describe('IssueLogger', (): void => {
});
describe('error()', (): void => {
let message: string;
let coreErrorSpy: jest.SpyInstance;
beforeEach((): void => {
message = 'dummy-message';
issue = new Issue(
DefaultProcessorOptions,
generateIIssue({
number: 8
})
);
issueLogger = new IssueLogger(issue);
coreErrorSpy = jest.spyOn(core, 'error').mockImplementation();
});
@ -75,4 +86,82 @@ describe('IssueLogger', (): void => {
expect(coreErrorSpy).toHaveBeenCalledWith('[#8] dummy-message');
});
});
it('should prefix the message with the issue number', (): void => {
expect.assertions(2);
message = 'dummy-message';
issue = new Issue(
DefaultProcessorOptions,
generateIIssue({
number: 123
})
);
issueLogger = new IssueLogger(issue);
coreWarningSpy = jest.spyOn(core, 'warning').mockImplementation();
issueLogger.warning(message);
expect(coreWarningSpy).toHaveBeenCalledTimes(1);
expect(coreWarningSpy).toHaveBeenCalledWith('[#123] dummy-message');
});
it.each`
pull_request | replacement
${{key: 'value'}} | ${'pull request'}
${{}} | ${'pull request'}
${null} | ${'issue'}
${undefined} | ${'issue'}
`(
'should replace the special tokens "$$type" with the corresponding type',
({pull_request, replacement}): void => {
expect.assertions(2);
message = 'The $$type will stale! $$type will soon be closed!';
issue = new Issue(
DefaultProcessorOptions,
generateIIssue({
number: 8,
pull_request
})
);
issueLogger = new IssueLogger(issue);
coreWarningSpy = jest.spyOn(core, 'warning').mockImplementation();
issueLogger.warning(message);
expect(coreWarningSpy).toHaveBeenCalledTimes(1);
expect(coreWarningSpy).toHaveBeenCalledWith(
`[#8] The ${replacement} will stale! ${replacement} will soon be closed!`
);
}
);
it.each`
pull_request | replacement
${{key: 'value'}} | ${'Pull request'}
${{}} | ${'Pull request'}
${null} | ${'Issue'}
${undefined} | ${'Issue'}
`(
'should replace the special token "$$type" with the corresponding type with first letter as uppercase',
({pull_request, replacement}): void => {
expect.assertions(2);
message = '$$type will stale';
issue = new Issue(
DefaultProcessorOptions,
generateIIssue({
number: 8,
pull_request
})
);
issueLogger = new IssueLogger(issue);
coreWarningSpy = jest.spyOn(core, 'warning').mockImplementation();
issueLogger.warning(message);
expect(coreWarningSpy).toHaveBeenCalledTimes(1);
expect(coreWarningSpy).toHaveBeenCalledWith(
`[#8] ${replacement} will stale`
);
}
);
});

View File

@ -2,6 +2,19 @@ import * as core from '@actions/core';
import {Issue} from '../issue';
import {Logger} from './logger';
/**
* @description
* Each log will prefix the message with the issue number
*
* @example
* warning('No stale') => "[#123] No stale"
*
* Each log method can have special tokens:
* - $$type => will replace this by either "pull request" or "issue" depending of the type of issue
*
* @example
* warning('The $$type will stale') => "The pull request will stale"
*/
export class IssueLogger implements Logger {
private readonly _issue: Issue;
@ -10,15 +23,31 @@ export class IssueLogger implements Logger {
}
warning(message: Readonly<string>): void {
core.warning(this._prefixWithIssueNumber(message));
core.warning(this._format(message));
}
info(message: Readonly<string>): void {
core.info(this._prefixWithIssueNumber(message));
core.info(this._format(message));
}
error(message: Readonly<string>): void {
core.error(this._prefixWithIssueNumber(message));
core.error(this._format(message));
}
private _replaceTokens(message: Readonly<string>): string {
return this._replaceTypeToken(message);
}
private _replaceTypeToken(message: Readonly<string>): string {
return message
.replace(
/^\$\$type/,
this._issue.isPullRequest ? 'Pull request' : 'Issue'
)
.replace(
/\$\$type/g,
this._issue.isPullRequest ? 'pull request' : 'issue'
);
}
private _prefixWithIssueNumber(message: Readonly<string>): string {
@ -28,4 +57,8 @@ export class IssueLogger implements Logger {
private _getIssueNumber(): number {
return this._issue.number;
}
private _format(message: Readonly<string>): string {
return this._prefixWithIssueNumber(this._replaceTokens(message));
}
}

View File

@ -1,3 +1,5 @@
import {DefaultProcessorOptions} from '../../__tests__/constants/default-processor-options';
import {generateIIssue} from '../../__tests__/functions/generate-iissue';
import {IIssue} from '../interfaces/issue';
import {IIssuesProcessorOptions} from '../interfaces/issues-processor-options';
import {Issue} from './issue';
@ -10,51 +12,8 @@ describe('Milestones', (): void => {
let issueInterface: IIssue;
beforeEach((): void => {
optionsInterface = {
ascending: false,
closeIssueLabel: '',
closeIssueMessage: '',
closePrLabel: '',
closePrMessage: '',
daysBeforeClose: 0,
daysBeforeIssueClose: 0,
daysBeforeIssueStale: 0,
daysBeforePrClose: 0,
daysBeforePrStale: 0,
daysBeforeStale: 0,
debugOnly: false,
deleteBranch: false,
exemptIssueLabels: '',
exemptPrLabels: '',
onlyLabels: '',
operationsPerRun: 0,
removeStaleWhenUpdated: false,
repoToken: '',
skipStaleIssueMessage: false,
skipStalePrMessage: false,
staleIssueLabel: '',
staleIssueMessage: '',
stalePrLabel: '',
stalePrMessage: '',
startDate: undefined,
exemptIssueMilestones: '',
exemptPrMilestones: '',
exemptMilestones: '',
exemptAllMilestones: false,
exemptAllIssueMilestones: undefined,
exemptAllPrMilestones: undefined
};
issueInterface = {
created_at: '',
locked: false,
milestone: undefined,
number: 0,
pull_request: undefined,
state: '',
title: '',
updated_at: '',
labels: []
};
optionsInterface = {...DefaultProcessorOptions};
issueInterface = generateIIssue();
});
describe('shouldExemptMilestones()', (): void => {

View File

@ -6,8 +6,8 @@ import {Issue} from './issue';
type CleanMilestone = string;
export class Milestones {
private static _cleanMilestone(label: Readonly<string>): CleanMilestone {
return deburr(label.toLowerCase());
private static _cleanMilestone(milestone: Readonly<string>): CleanMilestone {
return deburr(milestone.toLowerCase());
}
private readonly _options: IIssuesProcessorOptions;

View File

@ -0,0 +1,3 @@
export interface IAssignee {
login: string;
}

View File

@ -1,4 +1,5 @@
import {IsoDateString} from '../types/iso-date-string';
import {IAssignee} from './assignee';
import {ILabel} from './label';
import {IMilestone} from './milestone';
@ -12,4 +13,5 @@ export interface IIssue {
state: string;
locked: boolean;
milestone: IMilestone | undefined;
assignees: IAssignee[];
}

View File

@ -33,4 +33,10 @@ export interface IIssuesProcessorOptions {
exemptAllMilestones: boolean;
exemptAllIssueMilestones: boolean | undefined;
exemptAllPrMilestones: boolean | undefined;
exemptAssignees: string;
exemptIssueAssignees: string;
exemptPrAssignees: string;
exemptAllAssignees: boolean;
exemptAllIssueAssignees: boolean | undefined;
exemptAllPrAssignees: boolean | undefined;
}

View File

@ -59,7 +59,13 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
exemptPrMilestones: core.getInput('exempt-pr-milestones'),
exemptAllMilestones: core.getInput('exempt-all-milestones') === 'true',
exemptAllIssueMilestones: _toOptionalBoolean('exempt-all-issue-milestones'),
exemptAllPrMilestones: _toOptionalBoolean('exempt-all-pr-milestones')
exemptAllPrMilestones: _toOptionalBoolean('exempt-all-pr-milestones'),
exemptAssignees: core.getInput('exempt-assignees'),
exemptIssueAssignees: core.getInput('exempt-issue-assignees'),
exemptPrAssignees: core.getInput('exempt-pr-assignees'),
exemptAllAssignees: core.getInput('exempt-all-assignees') === 'true',
exemptAllIssueAssignees: _toOptionalBoolean('exempt-all-issue-assignees'),
exemptAllPrAssignees: _toOptionalBoolean('exempt-all-pr-assignees')
};
for (const numberInput of [