feat: add new filtering and labeling options, update input parameter names

BREAKING CHANGE: input parameter names have changed
This commit is contained in:
dessant
2021-09-27 20:38:48 +03:00
parent a0c7da3065
commit 26fd836f96
4 changed files with 502 additions and 180 deletions

231
README.md
View File

@@ -16,7 +16,7 @@ please consider contributing with
## Usage
Create a `lock.yml` workflow file in the `.github/workflows` directory,
Create the `lock.yml` workflow file in the `.github/workflows` directory,
use one of the [example workflows](#examples) to get started.
### Inputs
@@ -28,44 +28,118 @@ The action can be configured using [input parameters](https://docs.github.com/en
- GitHub access token, value must be `${{ github.token }}` or an encrypted
secret that contains a [personal access token](#using-a-personal-access-token)
- Optional, defaults to `${{ github.token }}`
- **`issue-lock-inactive-days`**
- **`issue-inactive-days`**
- Number of days of inactivity before a closed issue is locked
- Optional, defaults to `365`
- **`issue-exclude-created-before`**
- Do not lock issues created before a given timestamp,
- **`exclude-issue-created-before`**
- Do not lock issues created before a given date,
value must follow ISO 8601, ignored
when `exclude-issue-created-between` is set
- Optional, defaults to `''`
- **`exclude-issue-created-after`**
- Do not lock issues created after a given date,
value must follow ISO 8601, ignored
when `exclude-issue-created-between` is set
- Optional, defaults to `''`
- **`exclude-issue-created-between`**
- Do not lock issues created in a given time interval,
value must follow ISO 8601
- Optional, defaults to `''`
- **`issue-exclude-labels`**
- Do not lock issues with these labels, value must be
- **`exclude-issue-closed-before`**
- Do not lock issues closed before a given date,
value must follow ISO 8601, ignored
when `exclude-issue-closed-between` is set
- Optional, defaults to `''`
- **`exclude-issue-closed-after`**
- Do not lock issues closed after a given date,
value must follow ISO 8601, ignored
when `exclude-issue-closed-between` is set
- Optional, defaults to `''`
- **`exclude-issue-closed-between`**
- Do not lock issues closed in a given time interval,
value must follow ISO 8601
- Optional, defaults to `''`
- **`include-any-issue-labels`**
- Only lock issues with any of these labels, value must be
a comma separated list of labels or `''`, ignored
when `include-all-issue-labels` is set
- Optional, defaults to `''`
- **`include-all-issue-labels`**
- Only lock issues with all these labels, value must be
a comma separated list of labels or `''`
- Optional, defaults to `''`
- **`issue-lock-labels`**
- **`exclude-any-issue-labels`**
- Do not lock issues with any of these labels, value must be
a comma separated list of labels or `''`
- Optional, defaults to `''`
- **`add-issue-labels`**
- Labels to add before locking an issue, value must be
a comma separated list of labels or `''`
- Optional, defaults to `''`
- **`issue-lock-comment`**
- **`remove-issue-labels`**
- Labels to remove before locking an issue, value must be
a comma separated list of labels or `''`
- Optional, defaults to `''`
- **`issue-comment`**
- Comment to post before locking an issue
- Optional, defaults to `''`
- **`issue-lock-reason`**
- Reason for locking an issue, value must be one
of `resolved`, `off-topic`, `too heated`, `spam` or `''`
- Optional, defaults to `resolved`
- **`pr-lock-inactive-days`**
- **`pr-inactive-days`**
- Number of days of inactivity before a closed pull request is locked
- Optional, defaults to `365`
- **`pr-exclude-created-before`**
- Do not lock pull requests created before a given timestamp,
- **`exclude-pr-created-before`**
- Do not lock pull requests created before a given date,
value must follow ISO 8601, ignored
when `exclude-pr-created-between` is set
- Optional, defaults to `''`
- **`exclude-pr-created-after`**
- Do not lock pull requests created after a given date,
value must follow ISO 8601, ignored
when `exclude-pr-created-between` is set
- Optional, defaults to `''`
- **`exclude-pr-created-between`**
- Do not lock pull requests created in a given time interval,
value must follow ISO 8601
- Optional, defaults to `''`
- **`pr-exclude-labels`**
- Do not lock pull requests with these labels, value must
be a comma separated list of labels or `''`
- **`exclude-pr-closed-before`**
- Do not lock pull requests closed before a given date,
value must follow ISO 8601, ignored
when `exclude-pr-closed-between` is set
- Optional, defaults to `''`
- **`pr-lock-labels`**
- **`exclude-pr-closed-after`**
- Do not lock pull requests closed after a given date,
value must follow ISO 8601, ignored
when `exclude-pr-closed-between` is set
- Optional, defaults to `''`
- **`exclude-pr-closed-between`**
- Do not lock pull requests closed in a given time interval,
value must follow ISO 8601
- Optional, defaults to `''`
- **`include-any-pr-labels`**
- Only lock pull requests with any of these labels, value must be
a comma separated list of labels or `''`, ignored
when `include-all-pr-labels` is set
- Optional, defaults to `''`
- **`include-all-pr-labels`**
- Only lock pull requests with all these labels, value must be
a comma separated list of labels or `''`
- Optional, defaults to `''`
- **`exclude-any-pr-labels`**
- Do not lock pull requests with any of these labels, value must be
a comma separated list of labels or `''`
- Optional, defaults to `''`
- **`add-pr-labels`**
- Labels to add before locking a pull request, value must be
a comma separated list of labels or `''`
- Optional, defaults to `''`
- **`pr-lock-comment`**
- **`remove-pr-labels`**
- Labels to remove before locking a pull request, value must be
a comma separated list of labels or `''`
- Optional, defaults to `''`
- **`pr-comment`**
- Comment to post before locking a pull request
- Optional, defaults to `''`
- **`pr-lock-reason`**
@@ -76,6 +150,9 @@ The action can be configured using [input parameters](https://docs.github.com/en
- Limit locking to only issues or pull requests, value must be
one of `issues`, `prs` or `''`
- Optional, defaults to `''`
- **`log-output`**
- Log output parameters, value must be either `true` or `false`
- Optional, defaults to `false`
### Outputs
@@ -92,7 +169,8 @@ The action can be configured using [input parameters](https://docs.github.com/en
## Examples
The following workflow will search once an hour for closed issues
and pull requests that can be locked.
and pull requests that have not had any activity
in the past year and can be locked.
<!-- prettier-ignore -->
```yaml
@@ -114,7 +192,7 @@ jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2
- uses: dessant/lock-threads@v3
```
Edit the workflow after the initial backlog of issues and pull requests
@@ -153,25 +231,42 @@ jobs:
action:
runs-on: ubuntu-latest
steps:
- uses: dessant/lock-threads@v2
- uses: dessant/lock-threads@v3
with:
github-token: ${{ github.token }}
issue-lock-inactive-days: '365'
issue-exclude-created-before: ''
issue-exclude-labels: ''
issue-lock-labels: ''
issue-lock-comment: ''
issue-inactive-days: '365'
exclude-issue-created-before: ''
exclude-issue-created-after: ''
exclude-issue-created-between: ''
exclude-issue-closed-before: ''
exclude-issue-closed-after: ''
exclude-issue-closed-between: ''
include-any-issue-labels: ''
include-all-issue-labels: ''
exclude-any-issue-labels: ''
add-issue-labels: ''
remove-issue-labels: ''
issue-comment: ''
issue-lock-reason: 'resolved'
pr-lock-inactive-days: '365'
pr-exclude-created-before: ''
pr-exclude-labels: ''
pr-lock-labels: ''
pr-lock-comment: ''
pr-inactive-days: '365'
exclude-pr-created-before: ''
exclude-pr-created-after: ''
exclude-pr-created-between: ''
exclude-pr-closed-before: ''
exclude-pr-closed-after: ''
exclude-pr-closed-between: ''
include-any-pr-labels: ''
include-all-pr-labels: ''
exclude-any-pr-labels: ''
add-pr-labels: ''
remove-pr-labels: ''
pr-comment: ''
pr-lock-reason: 'resolved'
process-only: ''
log-output: false
```
### Excluding issues and pull requests
### Filtering issues and pull requests
This step will lock only issues, and exclude issues created before 2018,
or those with the `upstream` or `help-wanted` labels applied.
@@ -179,10 +274,10 @@ or those with the `upstream` or `help-wanted` labels applied.
<!-- prettier-ignore -->
```yaml
steps:
- uses: dessant/lock-threads@v2
- uses: dessant/lock-threads@v3
with:
issue-exclude-created-before: '2018-01-01T00:00:00Z'
issue-exclude-labels: 'upstream, help-wanted'
exclude-issue-created-before: '2018-01-01T00:00:00Z'
exclude-any-issue-labels: 'upstream, help-wanted'
process-only: 'issues'
```
@@ -192,12 +287,51 @@ with the `wip` label applied.
<!-- prettier-ignore -->
```yaml
steps:
- uses: dessant/lock-threads@v2
- uses: dessant/lock-threads@v3
with:
pr-exclude-labels: 'wip'
exclude-any-pr-labels: 'wip'
process-only: 'prs'
```
This step will lock only issues, and exclude issues closed before 2018,
or those created in 2018 and 2019.
<!-- prettier-ignore -->
```yaml
steps:
- uses: dessant/lock-threads@v3
with:
exclude-issue-created-between: '2018-01-01T00:00:00Z/2019-12-31T23:59:59.999Z'
exclude-issue-closed-before: '2018-01-01T00:00:00Z'
process-only: 'issues'
```
This step will lock issues that have the `incomplete` _or_ `invalid`
labels applied, and pull requests that have the `qa: done` _and_ `published`
labels applied.
<!-- prettier-ignore -->
```yaml
steps:
- uses: dessant/lock-threads@v3
with:
include-any-issue-labels: 'incomplete, invalid'
include-all-pr-labels: 'qa: done, published'
```
This step will lock issues that have not had any activity in the past 180 days.
<!-- prettier-ignore -->
```yaml
steps:
- uses: dessant/lock-threads@v3
with:
issue-inactive-days: '180'
process-only: 'issues'
```
### Commenting and labeling
This step will post a comment on issues and pull requests before locking them,
@@ -206,19 +340,32 @@ and apply the `outdated` label to issues.
<!-- prettier-ignore -->
```yaml
steps:
- uses: dessant/lock-threads@v2
- uses: dessant/lock-threads@v3
with:
issue-lock-labels: 'outdated'
issue-lock-comment: >
add-issue-labels: 'outdated'
issue-comment: >
This issue has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new issue for related bugs.
pr-lock-comment: >
pr-comment: >
This pull request has been automatically locked since there
has not been any recent activity after it was closed.
Please open a new issue for related bugs.
```
This step will apply the `qa: done` and `archived` labels,
and remove the `qa: primary` and `needs: user feedback` labels
before locking issues.
<!-- prettier-ignore -->
```yaml
steps:
- uses: dessant/lock-threads@v3
with:
add-issue-labels: 'qa: done, archived'
remove-issue-labels: 'qa: primary, needs: user feedback'
```
### Using a personal access token
The action uses an installation access token by default to interact with GitHub.
@@ -234,7 +381,7 @@ using the `github-token` input parameter.
<!-- prettier-ignore -->
```yaml
steps:
- uses: dessant/lock-threads@v2
- uses: dessant/lock-threads@v3
with:
github-token: ${{ secrets.PERSONAL_ACCESS_TOKEN }}
```
@@ -248,9 +395,9 @@ applying or removing milestones, or pushing commits.
An easy way to check and see which issues or pull requests will initially
be locked is to add the `updated` search qualifier to either the issue
or pull request page filter for your repository:
or pull request search field for your repository:
`is:closed is:unlocked updated:<2018-12-20`.
Adjust the date to be 365 days ago (or whatever you set for `*-lock-inactive-days`)
Adjust the date to be 365 days ago (or whatever you set for `*-inactive-days`)
to see which issues or pull requests will be locked.
## Why are only some issues and pull requests processed?

View File

@@ -5,37 +5,85 @@ inputs:
github-token:
description: 'GitHub access token'
default: '${{ github.token }}'
issue-lock-inactive-days:
issue-inactive-days:
description: 'Number of days of inactivity before a closed issue is locked'
default: '365'
issue-exclude-created-before:
description: 'Do not lock issues created before a given timestamp, value must follow ISO 8601'
exclude-issue-created-before:
description: 'Do not lock issues created before a given date, value must follow ISO 8601'
default: ''
issue-exclude-labels:
description: 'Do not lock issues with these labels, value must be a comma separated list of labels'
exclude-issue-created-after:
description: 'Do not lock issues created after a given date, value must follow ISO 8601'
default: ''
issue-lock-labels:
exclude-issue-created-between:
description: 'Do not lock issues created in a given time interval, value must follow ISO 8601'
default: ''
exclude-issue-closed-before:
description: 'Do not lock issues closed before a given date, value must follow ISO 8601'
default: ''
exclude-issue-closed-after:
description: 'Do not lock issues closed after a given date, value must follow ISO 8601'
default: ''
exclude-issue-closed-between:
description: 'Do not lock issues closed in a given time interval, value must follow ISO 8601'
default: ''
include-any-issue-labels:
description: 'Only lock issues with any of these labels, value must be a comma separated list of labels'
default: ''
include-all-issue-labels:
description: 'Only lock issues with all these labels, value must be a comma separated list of labels'
default: ''
exclude-any-issue-labels:
description: 'Do not lock issues with any of these labels, value must be a comma separated list of labels'
default: ''
add-issue-labels:
description: 'Labels to add before locking an issue, value must be a comma separated list of labels'
default: ''
issue-lock-comment:
remove-issue-labels:
description: 'Labels to remove before locking an issue, value must be a comma separated list of labels'
default: ''
issue-comment:
description: 'Comment to post before locking an issue'
default: ''
issue-lock-reason:
description: 'Reason for locking an issue, value must be one of `resolved`, `off-topic`, `too heated` or `spam`'
default: 'resolved'
pr-lock-inactive-days:
pr-inactive-days:
description: 'Number of days of inactivity before a closed pull request is locked'
default: '365'
pr-exclude-created-before:
description: 'Do not lock pull requests created before a given timestamp, value must follow ISO 8601'
exclude-pr-created-before:
description: 'Do not lock pull requests created before a given date, value must follow ISO 8601'
default: ''
pr-exclude-labels:
description: 'Do not lock pull requests with these labels, value must be a comma separated list of labels'
exclude-pr-created-after:
description: 'Do not lock pull requests created after a given date, value must follow ISO 8601'
default: ''
pr-lock-labels:
exclude-pr-created-between:
description: 'Do not lock pull requests created in a given time interval, value must follow ISO 8601'
default: ''
exclude-pr-closed-before:
description: 'Do not lock pull requests closed before a given date, value must follow ISO 8601'
default: ''
exclude-pr-closed-after:
description: 'Do not lock pull requests closed after a given date, value must follow ISO 8601'
default: ''
exclude-pr-closed-between:
description: 'Do not lock pull requests closed in a given time interval, value must follow ISO 8601'
default: ''
include-any-pr-labels:
description: 'Only lock pull requests with any of these labels, value must be a comma separated list of labels'
default: ''
include-all-pr-labels:
description: 'Only lock pull requests with all these labels, value must be a comma separated list of labels'
default: ''
exclude-any-pr-labels:
description: 'Do not lock pull requests with any of these labels, value must be a comma separated list of labels'
default: ''
add-pr-labels:
description: 'Labels to add before locking a pull request, value must be a comma separated list of labels'
default: ''
pr-lock-comment:
remove-pr-labels:
description: 'Labels to remove before locking a pull request, value must be a comma separated list of labels'
default: ''
pr-comment:
description: 'Comment to post before locking a pull request'
default: ''
pr-lock-reason:
@@ -44,6 +92,9 @@ inputs:
process-only:
description: 'Limit locking to only issues or pull requests, value must be one of `issues` or `prs`'
default: ''
log-output:
description: 'Log output parameters, value must be either `true` or `false`'
default: false
outputs:
issues:
description: 'Issues that have been locked, value is a JSON string'

View File

@@ -23,19 +23,31 @@ class App {
async lockThreads() {
const type = this.config['process-only'];
const threadTypes = type ? [type] : ['issue', 'pr'];
const logOutput = this.config['log-output'];
const threadTypes = type ? [type] : ['issue', 'pr'];
for (const item of threadTypes) {
const threads = await this.lock(item);
core.debug(`Setting output (${item}s)`);
core.setOutput(`${item}s`, threads.length ? JSON.stringify(threads) : '');
if (threads.length) {
core.setOutput(`${item}s`, JSON.stringify(threads));
if (logOutput) {
core.info(`Output (${item}s):`);
core.info(JSON.stringify(threads, null, 2));
}
} else {
core.setOutput(`${item}s`, '');
}
}
}
async lock(type) {
const repo = github.context.repo;
const lockLabels = this.config[`${type}-lock-labels`];
const lockComment = this.config[`${type}-lock-comment`];
const addLabels = this.config[`add-${type}-labels`];
const removeLabels = this.config[`remove-${type}-labels`];
const comment = this.config[`${type}-comment`];
const lockReason = this.config[`${type}-lock-reason`];
const threads = [];
@@ -44,12 +56,12 @@ class App {
for (const result of results) {
const issue = {...repo, issue_number: result.number};
if (lockComment) {
if (comment) {
core.debug(`Commenting (${type}: ${issue.issue_number})`);
try {
await this.client.rest.issues.createComment({
...issue,
body: lockComment
body: comment
});
} catch (err) {
if (!/cannot be modified.*discussion/i.test(err.message)) {
@@ -58,12 +70,39 @@ class App {
}
}
if (lockLabels) {
core.debug(`Labeling (${type}: ${issue.issue_number})`);
await this.client.rest.issues.addLabels({
...issue,
labels: lockLabels
});
if (addLabels || removeLabels) {
const {data: issueData} = await this.client.rest.issues.get({...issue});
if (addLabels) {
const currentLabels = issueData.labels.map(label => label.name);
const newLabels = addLabels.filter(
label => !currentLabels.includes(label)
);
if (newLabels.length) {
core.debug(`Labeling (${type}: ${issue.issue_number})`);
await this.client.rest.issues.addLabels({
...issue,
labels: newLabels
});
}
}
if (removeLabels) {
const currentLabels = issueData.labels.map(label => label.name);
const matchingLabels = currentLabels.filter(label =>
removeLabels.includes(label)
);
if (matchingLabels.length) {
core.debug(`Unlabeling (${type}: ${issue.issue_number})`);
for (const label of matchingLabels) {
await this.client.rest.issues.removeLabel({
...issue,
name: label
});
}
}
}
}
core.debug(`Locking (${type}: ${issue.issue_number})`);
@@ -89,22 +128,41 @@ class App {
async search(type) {
const {owner, repo} = github.context.repo;
const timestamp = this.getUpdatedTimestamp(
this.config[`${type}-lock-inactive-days`]
const updatedTime = this.getUpdatedTimestamp(
this.config[`${type}-inactive-days`]
);
let query = `repo:${owner}/${repo} updated:<${timestamp} is:closed is:unlocked`;
let query = `repo:${owner}/${repo} updated:<${updatedTime} is:closed is:unlocked`;
const excludeLabels = this.config[`${type}-exclude-labels`];
if (excludeLabels) {
const queryPart = excludeLabels
.map(label => `-label:"${label}"`)
.join(' ');
query += ` ${queryPart}`;
const includeAnyLabels = this.config[`include-any-${type}-labels`];
const includeAllLabels = this.config[`include-all-${type}-labels`];
if (includeAllLabels) {
query += ` ${includeAllLabels
.map(label => `label:"${label}"`)
.join(' ')}`;
} else if (includeAnyLabels) {
query += ` label:${includeAnyLabels.join(',')}`;
}
const excludeCreatedBefore = this.config[`${type}-exclude-created-before`];
if (excludeCreatedBefore) {
query += ` created:>${this.getISOTimestamp(excludeCreatedBefore)}`;
const excludeAnyLabels = this.config[`exclude-any-${type}-labels`];
if (excludeAnyLabels) {
query += ` -label:${excludeAnyLabels.join(',')}`;
}
const excludeCreatedQuery = this.getFilterByDateQuery({
type,
qualifier: 'created'
});
if (excludeCreatedQuery) {
query += ` ${excludeCreatedQuery}`;
}
const excludeClosedQuery = this.getFilterByDateQuery({
type,
qualifier: 'closed'
});
if (excludeClosedQuery) {
query += ` ${excludeClosedQuery}`;
}
if (type === 'issue') {
@@ -127,6 +185,26 @@ class App {
return results.filter(issue => !issue.locked);
}
getFilterByDateQuery({type, qualifier = 'created'} = {}) {
const beforeDate = this.config[`exclude-${type}-${qualifier}-before`];
const afterDate = this.config[`exclude-${type}-${qualifier}-after`];
const betweenDates = this.config[`exclude-${type}-${qualifier}-between`];
if (betweenDates) {
return `-${qualifier}:${betweenDates
.map(date => this.getISOTimestamp(date))
.join('..')}`;
} else if (beforeDate && afterDate) {
return `${qualifier}:${this.getISOTimestamp(
beforeDate
)}..${this.getISOTimestamp(afterDate)}`;
} else if (beforeDate) {
return `${qualifier}:>${this.getISOTimestamp(beforeDate)}`;
} else if (afterDate) {
return `${qualifier}:<${this.getISOTimestamp(afterDate)}`;
}
}
getUpdatedTimestamp(days) {
const ttl = days * 24 * 60 * 60 * 1000;
const date = new Date(new Date() - ttl);

View File

@@ -1,134 +1,180 @@
const Joi = require('joi');
const extendedJoi = Joi.extend({
type: 'stringList',
base: Joi.array(),
coerce: {
from: 'string',
method(value) {
value = value.trim();
if (value) {
value = value
.split(',')
.map(item => item.trim())
.filter(Boolean);
}
const extendedJoi = Joi.extend(joi => {
return {
type: 'stringList',
base: joi.array(),
coerce: {
from: 'string',
method(value, helpers) {
value = value.trim();
if (value) {
value = value
.split(',')
.map(item => item.trim())
.filter(Boolean);
}
return {value};
}
}
}).extend({
type: 'processOnly',
base: Joi.string(),
coerce: {
from: 'string',
method(value) {
value = value.trim();
if (['issues', 'prs'].includes(value)) {
value = value.slice(0, -1);
return {value};
}
return {value};
}
}
});
};
})
.extend(joi => {
return {
type: 'timeInterval',
base: joi.array(),
messages: {
'timeInterval.asc':
'{{#label}} the start date must be earlier than the end date'
},
coerce: {
from: 'string',
method(value, helpers) {
value = value.trim();
if (value) {
value = value
.split('/')
.map(item => item.trim())
.filter(Boolean);
}
return {value};
}
},
rules: {
asc: {
validate(value, helpers, args, options) {
if (value[0] < value[1]) {
return value;
}
return helpers.error('timeInterval.asc');
}
}
}
};
})
.extend(joi => {
return {
type: 'processOnly',
base: joi.string(),
coerce: {
from: 'string',
method(value, helpers) {
value = value.trim();
if (['issues', 'prs'].includes(value)) {
value = value.slice(0, -1);
}
return {value};
}
}
};
});
const joiDate = Joi.alternatives().try(
Joi.date()
// .iso()
.min('1970-01-01T00:00:00Z')
.max('2970-12-31T23:59:59Z'),
Joi.string().trim().valid('')
);
const joiTimeInterval = Joi.alternatives().try(
extendedJoi
.timeInterval()
.items(
Joi.date().iso().min('1970-01-01T00:00:00Z').max('2970-12-31T23:59:59Z')
)
.length(2)
.asc(),
Joi.string().trim().valid('')
);
const joiLabels = Joi.alternatives().try(
extendedJoi
.stringList()
.items(Joi.string().trim().max(50))
.min(1)
.max(30)
.unique(),
Joi.string().trim().valid('')
);
const schema = Joi.object({
'github-token': Joi.string().trim().max(100),
'issue-lock-inactive-days': Joi.number()
'issue-inactive-days': Joi.number()
.min(0)
.max(3650)
.precision(9)
.default(365),
'issue-exclude-created-before': Joi.alternatives()
.try(
Joi.date()
// .iso()
.min('1970-01-01T00:00:00Z')
.max('2970-12-31T23:59:59Z'),
Joi.string().trim().valid('')
)
.default(''),
'exclude-issue-created-before': joiDate.default(''),
'issue-exclude-labels': Joi.alternatives()
.try(
extendedJoi
.stringList()
.items(Joi.string().trim().max(50))
.min(1)
.max(30)
.unique(),
Joi.string().trim().valid('')
)
.default(''),
'exclude-issue-created-after': joiDate.default(''),
'issue-lock-labels': Joi.alternatives()
.try(
extendedJoi
.stringList()
.items(Joi.string().trim().max(50))
.min(1)
.max(30)
.unique(),
Joi.string().trim().valid('')
)
.default(''),
'exclude-issue-created-between': joiTimeInterval.default(''),
'issue-lock-comment': Joi.string().trim().max(10000).allow('').default(''),
'exclude-issue-closed-before': joiDate.default(''),
'exclude-issue-closed-after': joiDate.default(''),
'exclude-issue-closed-between': joiTimeInterval.default(''),
'include-any-issue-labels': joiLabels.default(''),
'include-all-issue-labels': joiLabels.default(''),
'exclude-any-issue-labels': joiLabels.default(''),
'add-issue-labels': joiLabels.default(''),
'remove-issue-labels': joiLabels.default(''),
'issue-comment': Joi.string().trim().max(10000).allow('').default(''),
'issue-lock-reason': Joi.string()
.valid('resolved', 'off-topic', 'too heated', 'spam', '')
.default('resolved'),
'pr-lock-inactive-days': Joi.number()
.min(0)
.max(3650)
.precision(9)
.default(365),
'pr-inactive-days': Joi.number().min(0).max(3650).precision(9).default(365),
'pr-exclude-created-before': Joi.alternatives()
.try(
Joi.date()
// .iso()
.min('1970-01-01T00:00:00Z')
.max('2970-12-31T23:59:59Z'),
Joi.string().trim().valid('')
)
.default(''),
'exclude-pr-created-before': joiDate.default(''),
'pr-exclude-labels': Joi.alternatives()
.try(
extendedJoi
.stringList()
.items(Joi.string().trim().max(50))
.min(1)
.max(30)
.unique(),
Joi.string().trim().valid('')
)
.default(''),
'exclude-pr-created-after': joiDate.default(''),
'pr-lock-labels': Joi.alternatives()
.try(
extendedJoi
.stringList()
.items(Joi.string().trim().max(50))
.min(1)
.max(30)
.unique(),
Joi.string().trim().valid('')
)
.default(''),
'exclude-pr-created-between': joiTimeInterval.default(''),
'pr-lock-comment': Joi.string().trim().max(10000).allow('').default(''),
'exclude-pr-closed-before': joiDate.default(''),
'exclude-pr-closed-after': joiDate.default(''),
'exclude-pr-closed-between': joiTimeInterval.default(''),
'include-any-pr-labels': joiLabels.default(''),
'include-all-pr-labels': joiLabels.default(''),
'exclude-any-pr-labels': joiLabels.default(''),
'add-pr-labels': joiLabels.default(''),
'remove-pr-labels': joiLabels.default(''),
'pr-comment': Joi.string().trim().max(10000).allow('').default(''),
'pr-lock-reason': Joi.string()
.valid('resolved', 'off-topic', 'too heated', 'spam', '')
.default('resolved'),
'process-only': extendedJoi.processOnly().valid('issue', 'pr', '').default('')
'process-only': extendedJoi
.processOnly()
.valid('issue', 'pr', '')
.default(''),
'log-output': Joi.boolean().default(false)
});
module.exports = schema;