Compare commits

..

7 Commits

Author SHA1 Message Date
Luke Tomlinson
489c8a69b9 More debugging 2021-06-29 11:50:32 -04:00
Luke Tomlinson
31eafc7219 Debug events 2021-06-29 11:44:24 -04:00
Luke Tomlinson
75a803e008 Filter comments based on content, not author 2021-06-24 16:50:23 -04:00
Luke Tomlinson
cce770077c Print comments 2021-06-24 15:28:15 -04:00
Luke Tomlinson
b95063d0a1 Print more user info 2021-06-24 15:23:23 -04:00
Luke Tomlinson
7370047184 Print actor 2021-06-24 14:09:38 -04:00
Luke Tomlinson
a7d1a14092 Testing 2021-06-24 14:00:41 -04:00
14 changed files with 266 additions and 129 deletions

View File

@@ -1,24 +0,0 @@
# Changelog
Starting in version 4.0.0 we will maintain a changelog
## [4.0.0](https://github.com/actions/stale/compare/v3.0.19...v4.0.0) (2021-07-14)
### Features
* **options:** simplify config by removing skip stale message options ([#457](https://github.com/actions/stale/issues/457)) ([6ec637d](https://github.com/actions/stale/commit/6ec637d238067ab8cc96c9289dcdac280bbd3f4a)), closes [#405](https://github.com/actions/stale/issues/405) [#455](https://github.com/actions/stale/issues/455)
* **output:** print output parameters ([#458](https://github.com/actions/stale/issues/458)) ([3e6d35b](https://github.com/actions/stale/commit/3e6d35b685f0b2fa1a69be893fa07d3d85e05ee0))
### Bug Fixes
* **dry-run:** forbid mutations in dry-run ([#500](https://github.com/actions/stale/issues/500)) ([f1017f3](https://github.com/actions/stale/commit/f1017f33dd159ea51366375120c3e6981d7c3097)), closes [#499](https://github.com/actions/stale/issues/499)
* **logs:** coloured logs ([#465](https://github.com/actions/stale/issues/465)) ([5fbbfba](https://github.com/actions/stale/commit/5fbbfba142860ea6512549e96e36e3540c314132))
* **operations:** fail fast the current batch to respect the operations limit ([#474](https://github.com/actions/stale/issues/474)) ([5f6f311](https://github.com/actions/stale/commit/5f6f311ca6aa75babadfc7bac6edf5d85fa3f35d)), closes [#466](https://github.com/actions/stale/issues/466)
* **label comparison**: make label comparison case insensitive [#517](https://github.com/actions/stale/pull/517), closes [#516](https://github.com/actions/stale/pull/516)
* **filtering comments by actor could have strange behavior**: "stale" comments are now detected based on if the message is the stale message not _who_ made the comment([#519](https://github.com/actions/stale/pull/519)), fixes [#441](https://github.com/actions/stale/pull/441), [#509](https://github.com/actions/stale/pull/509), [#518](https://github.com/actions/stale/pull/518)
### Breaking Changes
* The options `skip-stale-issue-message` and `skip-stale-pr-message` were removed. Instead, setting the options `stale-issue-message` and `stale-pr-message` will be enough to let the stale workflow add a comment. If the options are unset, a comment will not be added which was the equivalent of setting `skip-stale-issue-message` to `false`.
* The `operations-per-run` option will be more effective. After migrating, you could face a failed-fast process workflow if you let the default value (30) or set it to a small number. In that case, you will see a warning at the end of the logs (if enabled) indicating that the workflow was stopped sooner to avoid consuming too much API calls. In most cases, you can just increase this limit to make sure to process everything in a single run.

View File

@@ -11,17 +11,24 @@ The default configuration will:
## Recommended permissions ## Recommended permissions
For the execution of this action, it must be able to fetch all issues and pull requests from your repository. For the execution of this action, it must be able to fetch all issues and pull requests from your repository.
In addition, based on the provided configuration, the action could require more permission(s) (e.g.: add label, remove label, comment, close, etc.).
This can be achieved with the following [configuration in the action](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#permissions) if the permissions are restricted: This can be achieved with the following [configuration in the action](https://docs.github.com/en/actions/reference/workflow-syntax-for-github-actions#permissions) if the permissions are restricted:
```yaml
permissions:
issues: read
pull-requests: read
```
In addition, based on the provided configuration, the action could require more permission(s) (e.g.: add label, remove label, comment, close, etc.).
You can find more information about the required permissions under the corresponding options that you wish to use.
However, if don't want to bother, you can use these permissions:
```yaml ```yaml
permissions: permissions:
issues: write issues: write
pull-requests: write pull-requests: write
``` ```
You can find more information about the required permissions under the corresponding options that you wish to use.
## All options ## All options
### List of input options ### List of input options

View File

@@ -1139,6 +1139,7 @@ class IssuesProcessorBuilder {
build(): IssuesProcessorMock { build(): IssuesProcessorMock {
return new IssuesProcessorMock( return new IssuesProcessorMock(
this._options, this._options,
async () => 'abot',
async p => (p === 1 ? this._issues : []), async p => (p === 1 ? this._issues : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()

View File

@@ -48,6 +48,7 @@ describe('assignees options', (): void => {
const setProcessor = () => { const setProcessor = () => {
processor = new IssuesProcessorMock( processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? testIssueList : []), async p => (p === 1 ? testIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()

View File

@@ -6,6 +6,7 @@ import {IIssuesProcessorOptions} from '../../src/interfaces/issues-processor-opt
export class IssuesProcessorMock extends IssuesProcessor { export class IssuesProcessorMock extends IssuesProcessor {
constructor( constructor(
options: IIssuesProcessorOptions, options: IIssuesProcessorOptions,
getActor?: () => Promise<string>,
getIssues?: (page: number) => Promise<Issue[]>, getIssues?: (page: number) => Promise<Issue[]>,
listIssueComments?: ( listIssueComments?: (
issueNumber: number, issueNumber: number,
@@ -18,6 +19,10 @@ export class IssuesProcessorMock extends IssuesProcessor {
) { ) {
super(options); super(options);
if (getActor) {
this.getActor = getActor;
}
if (getIssues) { if (getIssues) {
this.getIssues = getIssues; this.getIssues = getIssues;
} }

View File

@@ -16,6 +16,7 @@ test('processing an issue with no label will make it stale and close it, if it i
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -47,6 +48,7 @@ test('processing an issue with no label and a start date as ECMAScript epoch in
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -78,6 +80,7 @@ test('processing an issue with no label and a start date as ECMAScript epoch in
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -109,6 +112,7 @@ test('processing an issue with no label and a start date as ECMAScript epoch in
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -140,6 +144,7 @@ test('processing an issue with no label and a start date as ECMAScript epoch in
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -171,6 +176,7 @@ test('processing an issue with no label and a start date as ISO 8601 being befor
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -202,6 +208,7 @@ test('processing an issue with no label and a start date as ISO 8601 being after
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -233,6 +240,7 @@ test('processing an issue with no label and a start date as RFC 2822 being befor
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -264,6 +272,7 @@ test('processing an issue with no label and a start date as RFC 2822 being after
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -287,6 +296,7 @@ test('processing an issue with no label will make it stale and close it, if it i
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -311,6 +321,7 @@ test('processing an issue with no label will make it stale and not close it, if
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -333,6 +344,7 @@ test('processing an issue with no label will make it stale and not close it if d
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -356,6 +368,7 @@ test('processing an issue with no label will make it stale and not close it if d
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -379,6 +392,7 @@ test('processing an issue with no label will not make it stale if days-before-st
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -403,6 +417,7 @@ test('processing an issue with no label will not make it stale if days-before-st
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -430,6 +445,7 @@ test('processing an issue with no label will make it stale but not close it', as
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
DefaultProcessorOptions, DefaultProcessorOptions,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -460,6 +476,7 @@ test('processing a stale issue will close it', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -490,6 +507,7 @@ test('processing a stale issue containing a space in the label will close it', a
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -520,6 +538,7 @@ test('processing a stale issue containing a slash in the label will close it', a
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -551,6 +570,7 @@ test('processing a stale issue will close it when days-before-issue-stale overri
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -581,6 +601,7 @@ test('processing a stale PR will close it', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -612,6 +633,7 @@ test('processing a stale PR will close it when days-before-pr-stale override day
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -643,6 +665,7 @@ test('processing a stale issue will close it even if configured not to mark as s
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -675,6 +698,7 @@ test('processing a stale issue will close it even if configured not to mark as s
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -706,6 +730,7 @@ test('processing a stale PR will close it even if configured not to mark as stal
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -738,6 +763,7 @@ test('processing a stale PR will close it even if configured not to mark as stal
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -765,6 +791,7 @@ test('closed issues will not be marked stale', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
DefaultProcessorOptions, DefaultProcessorOptions,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [] async () => []
); );
@@ -791,6 +818,7 @@ test('stale closed issues will not be closed', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
DefaultProcessorOptions, DefaultProcessorOptions,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -818,6 +846,7 @@ test('closed prs will not be marked stale', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
DefaultProcessorOptions, DefaultProcessorOptions,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -845,6 +874,7 @@ test('stale closed prs will not be closed', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
DefaultProcessorOptions, DefaultProcessorOptions,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -871,8 +901,10 @@ test('locked issues will not be marked stale', async () => {
true true
) )
]; ];
const processor = new IssuesProcessorMock(DefaultProcessorOptions, async p => const processor = new IssuesProcessorMock(
p === 1 ? TestIssueList : [] DefaultProcessorOptions,
async () => 'abot',
async p => (p === 1 ? TestIssueList : [])
); );
// process our fake issue list // process our fake issue list
@@ -898,6 +930,7 @@ test('stale locked issues will not be closed', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
DefaultProcessorOptions, DefaultProcessorOptions,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -924,8 +957,10 @@ test('locked prs will not be marked stale', async () => {
true true
) )
]; ];
const processor = new IssuesProcessorMock(DefaultProcessorOptions, async p => const processor = new IssuesProcessorMock(
p === 1 ? TestIssueList : [] DefaultProcessorOptions,
async () => 'abot',
async p => (p === 1 ? TestIssueList : [])
); );
// process our fake issue list // process our fake issue list
@@ -951,6 +986,7 @@ test('stale locked prs will not be closed', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
DefaultProcessorOptions, DefaultProcessorOptions,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -980,6 +1016,7 @@ test('exempt issue labels will not be marked stale', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1009,6 +1046,7 @@ test('exempt issue labels will not be marked stale (multi issue label with space
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1037,6 +1075,7 @@ test('exempt issue labels will not be marked stale (multi issue label)', async (
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1083,6 +1122,7 @@ test('exempt pr labels will not be marked stale', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1111,14 +1151,14 @@ test('exempt issue labels will not be marked stale and will remove the existing
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [ async () => [
{ {
user: { user: {
login: 'notme', login: 'notme',
type: 'User' type: 'User'
}, }
body: 'Body'
} }
], // return a fake comment to indicate there was an update ], // return a fake comment to indicate there was an update
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1166,6 +1206,7 @@ test('stale issues should not be closed if days is set to -1', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1193,14 +1234,14 @@ test('stale label should be removed if a comment was added to a stale issue', as
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [ async () => [
{ {
user: { user: {
login: 'notme', login: 'notme',
type: 'User' type: 'User'
}, }
body: 'Body'
} }
], // return a fake comment to indicate there was an update ], // return a fake comment to indicate there was an update
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1234,14 +1275,14 @@ test('when the option "labelsToAddWhenUnstale" is set, the labels should be adde
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [ async () => [
{ {
user: { user: {
login: 'notme', login: 'notme',
type: 'User' type: 'User'
}, }
body: 'Body'
} }
], // return a fake comment to indicate there was an update ], // return a fake comment to indicate there was an update
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1274,14 +1315,14 @@ test('stale label should not be removed if a comment was added by the bot (and t
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [ async () => [
{ {
user: { user: {
login: 'abot', login: 'abot',
type: 'User' type: 'User'
}, }
body: 'This issue is stale'
} }
], // return a fake comment to indicate there was an update by the bot ], // return a fake comment to indicate there was an update by the bot
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1314,8 +1355,9 @@ test('stale label containing a space should be removed if a comment was added to
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [{user: {login: 'notme', type: 'User'}, body: 'Body'}], // return a fake comment to indicate there was an update async () => [{user: {login: 'notme', type: 'User'}}], // return a fake comment to indicate there was an update
async () => new Date().toDateString() async () => new Date().toDateString()
); );
@@ -1345,6 +1387,7 @@ test('stale issues should not be closed until after the closed number of days',
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1377,6 +1420,7 @@ test('stale issues should be closed if the closed nubmer of days (additive) is a
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1408,6 +1452,7 @@ test('stale issues should not be closed until after the closed number of days (l
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1440,6 +1485,7 @@ test('skips stale message on issues when stale-issue-message is empty', async ()
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1484,6 +1530,7 @@ test('send stale message on issues when stale-issue-message is not empty', async
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1528,6 +1575,7 @@ test('skips stale message on prs when stale-pr-message is empty', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1572,6 +1620,7 @@ test('send stale message on prs when stale-pr-message is not empty', async () =>
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1613,6 +1662,7 @@ test('git branch is deleted when option is enabled', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1642,6 +1692,7 @@ test('git branch is not deleted when issue is not pull request', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1673,6 +1724,7 @@ test('an issue without a milestone will be marked as stale', async () => {
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
DefaultProcessorOptions, DefaultProcessorOptions,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1706,6 +1758,7 @@ test('an issue without an exempted milestone will be marked as stale', async ()
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1739,6 +1792,7 @@ test('an issue with an exempted milestone will not be marked as stale', async ()
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1772,6 +1826,7 @@ test('an issue with an exempted milestone will not be marked as stale (multi mil
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1805,6 +1860,7 @@ test('an issue with an exempted milestone will not be marked as stale (multi mil
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1839,6 +1895,7 @@ test('an issue with an exempted milestone but without an exempted issue mileston
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1873,6 +1930,7 @@ test('an issue with an exempted milestone but with another exempted issue milest
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1907,6 +1965,7 @@ test('an issue with an exempted milestone and with an exempted issue milestone w
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1934,6 +1993,7 @@ test('processing an issue opened since 2 days and with the option "daysBeforeIss
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1960,6 +2020,7 @@ test('processing an issue opened since 2 days and with the option "daysBeforeIss
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -1986,6 +2047,7 @@ test('processing an issue opened since 2 days and with the option "daysBeforeIss
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -2019,6 +2081,7 @@ test('processing a pull request opened since 2 days and with the option "daysBef
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -2052,6 +2115,7 @@ test('processing a pull request opened since 2 days and with the option "daysBef
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -2085,6 +2149,7 @@ test('processing a pull request opened since 2 days and with the option "daysBef
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -2121,6 +2186,7 @@ test('processing a previously closed issue with a close label will remove the cl
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -2156,6 +2222,7 @@ test('processing a closed issue with a close label will not remove the close lab
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -2191,6 +2258,7 @@ test('processing a locked issue with a close label will not remove the close lab
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()
@@ -2230,6 +2298,7 @@ test('processing an issue stale since less than the daysBeforeStale with a stale
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async (): Promise<IComment[]> => Promise.resolve([]), async (): Promise<IComment[]> => Promise.resolve([]),
async () => labelCreatedAt.toDateString() async () => labelCreatedAt.toDateString()
@@ -2270,6 +2339,7 @@ test('processing an issue stale since less than the daysBeforeStale without a st
]; ];
const processor = new IssuesProcessorMock( const processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? TestIssueList : []), async p => (p === 1 ? TestIssueList : []),
async (): Promise<IComment[]> => Promise.resolve([]), async (): Promise<IComment[]> => Promise.resolve([]),
async () => new Date().toDateString() async () => new Date().toDateString()

View File

@@ -39,6 +39,7 @@ describe('milestones options', (): void => {
const setProcessor = () => { const setProcessor = () => {
processor = new IssuesProcessorMock( processor = new IssuesProcessorMock(
opts, opts,
async () => 'abot',
async p => (p === 1 ? testIssueList : []), async p => (p === 1 ? testIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()

View File

@@ -1139,6 +1139,7 @@ class IssuesProcessorBuilder {
build(): IssuesProcessorMock { build(): IssuesProcessorMock {
return new IssuesProcessorMock( return new IssuesProcessorMock(
this._options, this._options,
async () => 'abot',
async p => (p === 1 ? this._issues : []), async p => (p === 1 ? this._issues : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()

View File

@@ -205,6 +205,7 @@ class SUT {
private async _setProcessor(): Promise<number> { private async _setProcessor(): Promise<number> {
this.processor = new IssuesProcessorMock( this.processor = new IssuesProcessorMock(
this._opts, this._opts,
async () => 'abot',
async p => (p === 1 ? this._testIssueList : []), async p => (p === 1 ? this._testIssueList : []),
async () => [], async () => [],
async () => new Date().toDateString() async () => new Date().toDateString()

View File

@@ -539,14 +539,14 @@ class IssuesProcessorBuilder {
build(): IssuesProcessorMock { build(): IssuesProcessorMock {
return new IssuesProcessorMock( return new IssuesProcessorMock(
this._options, this._options,
async () => 'abot',
async p => (p === 1 ? this._issues : []), async p => (p === 1 ? this._issues : []),
async () => [ async () => [
{ {
user: { user: {
login: 'notme', login: 'notme',
type: 'User' type: 'User'
}, }
body: 'body'
} }
], ],
async () => new Date().toDateString() async () => new Date().toDateString()

188
dist/index.js vendored
View File

@@ -233,7 +233,6 @@ const is_date_more_recent_than_1 = __nccwpck_require__(1473);
const is_valid_date_1 = __nccwpck_require__(891); const is_valid_date_1 = __nccwpck_require__(891);
const is_boolean_1 = __nccwpck_require__(8236); const is_boolean_1 = __nccwpck_require__(8236);
const is_labeled_1 = __nccwpck_require__(6792); const is_labeled_1 = __nccwpck_require__(6792);
const clean_label_1 = __nccwpck_require__(7752);
const should_mark_when_stale_1 = __nccwpck_require__(2461); const should_mark_when_stale_1 = __nccwpck_require__(2461);
const words_to_list_1 = __nccwpck_require__(1883); const words_to_list_1 = __nccwpck_require__(1883);
const assignees_1 = __nccwpck_require__(7236); const assignees_1 = __nccwpck_require__(7236);
@@ -268,7 +267,7 @@ class IssuesProcessor {
} }
} }
static _updatedSince(timestamp, num_days) { static _updatedSince(timestamp, num_days) {
const daysInMillis = 1000 * 60 * 60 * 24 * num_days; const daysInMillis = 1000 * 60 * num_days; //temporarily number of minutes
const millisSinceLastUpdated = new Date().getTime() - new Date(timestamp).getTime(); const millisSinceLastUpdated = new Date().getTime() - new Date(timestamp).getTime();
return millisSinceLastUpdated <= daysInMillis; return millisSinceLastUpdated <= daysInMillis;
} }
@@ -292,6 +291,7 @@ class IssuesProcessor {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
// get the next batch of issues // get the next batch of issues
const issues = yield this.getIssues(page); const issues = yield this.getIssues(page);
const actor = yield this.getActor();
if (issues.length <= 0) { if (issues.length <= 0) {
this._logger.info(logger_service_1.LoggerService.green(`No more issues found to process. Exiting...`)); this._logger.info(logger_service_1.LoggerService.green(`No more issues found to process. Exiting...`));
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.setOperationsCount(this.operations.getConsumedOperationsCount()).logStats(); (_a = this._statistics) === null || _a === void 0 ? void 0 : _a.setOperationsCount(this.operations.getConsumedOperationsCount()).logStats();
@@ -309,7 +309,7 @@ class IssuesProcessor {
} }
const issueLogger = new issue_logger_1.IssueLogger(issue); const issueLogger = new issue_logger_1.IssueLogger(issue);
yield issueLogger.grouping(`$$type #${issue.number}`, () => __awaiter(this, void 0, void 0, function* () { yield issueLogger.grouping(`$$type #${issue.number}`, () => __awaiter(this, void 0, void 0, function* () {
yield this.processIssue(issue, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale); yield this.processIssue(issue, actor, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale);
})); }));
} }
if (!this.operations.hasRemainingOperations()) { if (!this.operations.hasRemainingOperations()) {
@@ -323,7 +323,7 @@ class IssuesProcessor {
return this.processIssues(page + 1); return this.processIssues(page + 1);
}); });
} }
processIssue(issue, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale) { processIssue(issue, actor, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale) {
var _a; var _a;
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementProcessedItemsCount(issue); (_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementProcessedItemsCount(issue);
@@ -472,7 +472,7 @@ class IssuesProcessor {
// Process the issue if it was marked stale // Process the issue if it was marked stale
if (issue.isStale) { if (issue.isStale) {
issueLogger.info(`This $$type is already stale`); issueLogger.info(`This $$type is already stale`);
yield this._processStaleIssue(issue, staleLabel, staleMessage, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale, closeMessage, closeLabel); yield this._processStaleIssue(issue, staleLabel, actor, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale, closeMessage, closeLabel);
} }
IssuesProcessor._endIssueProcessing(issue); IssuesProcessor._endIssueProcessing(issue);
}); });
@@ -499,6 +499,20 @@ class IssuesProcessor {
} }
}); });
} }
// get the actor from the GitHub token or context
getActor() {
return __awaiter(this, void 0, void 0, function* () {
let actor;
try {
this.operations.consumeOperation();
actor = yield this.client.users.getAuthenticated();
}
catch (error) {
return github_1.context.actor;
}
return actor.data.login;
});
}
// grab issues from github in batches of 100 // grab issues from github in batches of 100
getIssues(page) { getIssues(page) {
var _a; var _a;
@@ -541,7 +555,8 @@ class IssuesProcessor {
}); });
const events = yield this.client.paginate(options); const events = yield this.client.paginate(options);
const reversedEvents = events.reverse(); const reversedEvents = events.reverse();
const staleLabeledEvent = reversedEvents.find(event => event.event === 'labeled' && clean_label_1.cleanLabel(event.label.name) === clean_label_1.cleanLabel(label)); issueLogger.info(`Reversed Events: ${JSON.stringify(reversedEvents)}`);
const staleLabeledEvent = reversedEvents.find(event => event.event === 'labeled' && event.label.name === label);
if (!staleLabeledEvent) { if (!staleLabeledEvent) {
// Must be old rather than labeled // Must be old rather than labeled
return undefined; return undefined;
@@ -550,12 +565,12 @@ class IssuesProcessor {
}); });
} }
// handle all of the stale issue logic when we find a stale issue // handle all of the stale issue logic when we find a stale issue
_processStaleIssue(issue, staleLabel, staleMessage, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale, closeMessage, closeLabel) { _processStaleIssue(issue, staleLabel, actor, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale, closeMessage, closeLabel) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue); const issueLogger = new issue_logger_1.IssueLogger(issue);
const markedStaleOn = (yield this.getLabelCreationDate(issue, staleLabel)) || issue.updated_at; const markedStaleOn = (yield this.getLabelCreationDate(issue, staleLabel)) || issue.updated_at;
issueLogger.info(`$$type marked stale on: ${logger_service_1.LoggerService.cyan(markedStaleOn)}`); issueLogger.info(`$$type marked stale on: ${logger_service_1.LoggerService.cyan(markedStaleOn)}`);
const issueHasComments = yield this._hasCommentsSince(issue, markedStaleOn, staleMessage); const issueHasComments = yield this._hasCommentsSince(issue, markedStaleOn, actor);
issueLogger.info(`$$type has been commented on: ${logger_service_1.LoggerService.cyan(issueHasComments)}`); issueLogger.info(`$$type has been commented on: ${logger_service_1.LoggerService.cyan(issueHasComments)}`);
const daysBeforeClose = issue.isPullRequest const daysBeforeClose = issue.isPullRequest
? this._getDaysBeforePrClose() ? this._getDaysBeforePrClose()
@@ -600,7 +615,7 @@ class IssuesProcessor {
}); });
} }
// checks to see if a given issue is still stale (has had activity on it) // checks to see if a given issue is still stale (has had activity on it)
_hasCommentsSince(issue, sinceDate, staleMessage) { _hasCommentsSince(issue, sinceDate, actor) {
return __awaiter(this, void 0, void 0, function* () { return __awaiter(this, void 0, void 0, function* () {
const issueLogger = new issue_logger_1.IssueLogger(issue); const issueLogger = new issue_logger_1.IssueLogger(issue);
issueLogger.info(`Checking for comments on $$type since: ${logger_service_1.LoggerService.cyan(sinceDate)}`); issueLogger.info(`Checking for comments on $$type since: ${logger_service_1.LoggerService.cyan(sinceDate)}`);
@@ -609,9 +624,10 @@ class IssuesProcessor {
} }
// find any comments since the date // find any comments since the date
const comments = yield this.listIssueComments(issue.number, sinceDate); const comments = yield this.listIssueComments(issue.number, sinceDate);
const filteredComments = comments.filter(comment => comment.user.type === 'User' && core.debug(`The actor is: ${actor}`);
comment.body.toLowerCase() !== staleMessage.toLowerCase()); core.debug(`The comments are ${JSON.stringify(comments)}`);
issueLogger.info(`Comments that are not the stale comment or another bot: ${logger_service_1.LoggerService.cyan(filteredComments.length)}`); const filteredComments = comments.filter(comment => comment.user.type === 'User' && comment.body !== IssuesProcessor._getStaleMessageUsedOptionName(issue));
issueLogger.info(`Comments not made by actor or another bot: ${logger_service_1.LoggerService.cyan(filteredComments.length)}`);
// if there are any user comments returned // if there are any user comments returned
return filteredComments.length > 0; return filteredComments.length > 0;
}); });
@@ -1732,33 +1748,6 @@ var Option;
})(Option = exports.Option || (exports.Option = {})); })(Option = exports.Option || (exports.Option = {}));
/***/ }),
/***/ 7752:
/***/ (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.cleanLabel = void 0;
const lodash_deburr_1 = __importDefault(__nccwpck_require__(1601));
/**
* @description
* Clean a label by lowercasing it and deburring it for consistency
*
* @param {string} label A raw GitHub label
*
* @return {string} A lowercased, deburred version of the passed in label
*/
function cleanLabel(label) {
return lodash_deburr_1.default(label.toLowerCase());
}
exports.cleanLabel = cleanLabel;
/***/ }), /***/ }),
/***/ 965: /***/ 965:
@@ -1845,13 +1834,16 @@ exports.isBoolean = isBoolean;
/***/ }), /***/ }),
/***/ 6792: /***/ 6792:
/***/ ((__unused_webpack_module, exports, __nccwpck_require__) => { /***/ (function(__unused_webpack_module, exports, __nccwpck_require__) {
"use strict"; "use strict";
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", ({ value: true })); Object.defineProperty(exports, "__esModule", ({ value: true }));
exports.isLabeled = void 0; exports.isLabeled = void 0;
const clean_label_1 = __nccwpck_require__(7752); const lodash_deburr_1 = __importDefault(__nccwpck_require__(1601));
/** /**
* @description * @description
* Check if the given label is listed as a label of the given issue * Check if the given label is listed as a label of the given issue
@@ -1863,10 +1855,13 @@ const clean_label_1 = __nccwpck_require__(7752);
*/ */
function isLabeled(issue, label) { function isLabeled(issue, label) {
return !!issue.labels.find((issueLabel) => { return !!issue.labels.find((issueLabel) => {
return clean_label_1.cleanLabel(label) === clean_label_1.cleanLabel(issueLabel.name); return cleanLabel(label) === cleanLabel(issueLabel.name);
}); });
} }
exports.isLabeled = isLabeled; exports.isLabeled = isLabeled;
function cleanLabel(label) {
return lodash_deburr_1.default(label.toLowerCase());
}
/***/ }), /***/ }),
@@ -5800,14 +5795,17 @@ ansiEscapes.iTerm = {
/***/ }), /***/ }),
/***/ 2068: /***/ 2068:
/***/ ((module, __unused_webpack_exports, __nccwpck_require__) => { /***/ ((__unused_webpack___webpack_module__, __webpack_exports__, __nccwpck_require__) => {
"use strict"; "use strict";
/* module decorator */ module = __nccwpck_require__.nmd(module); __nccwpck_require__.r(__webpack_exports__);
/* harmony export */ __nccwpck_require__.d(__webpack_exports__, {
/* harmony export */ "default": () => __WEBPACK_DEFAULT_EXPORT__
/* harmony export */ });
const ANSI_BACKGROUND_OFFSET = 10; const ANSI_BACKGROUND_OFFSET = 10;
const wrapAnsi16 = (offset = 0) => code => `\u001B[${code + offset}m`;
const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`; const wrapAnsi256 = (offset = 0) => code => `\u001B[${38 + offset};5;${code}m`;
const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`; const wrapAnsi16m = (offset = 0) => (red, green, blue) => `\u001B[${38 + offset};2;${red};${green};${blue}m`;
@@ -5901,8 +5899,10 @@ function assembleStyles() {
styles.color.close = '\u001B[39m'; styles.color.close = '\u001B[39m';
styles.bgColor.close = '\u001B[49m'; styles.bgColor.close = '\u001B[49m';
styles.color.ansi = wrapAnsi16();
styles.color.ansi256 = wrapAnsi256(); styles.color.ansi256 = wrapAnsi256();
styles.color.ansi16m = wrapAnsi16m(); styles.color.ansi16m = wrapAnsi16m();
styles.bgColor.ansi = wrapAnsi16(ANSI_BACKGROUND_OFFSET);
styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET); styles.bgColor.ansi256 = wrapAnsi256(ANSI_BACKGROUND_OFFSET);
styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET); styles.bgColor.ansi16m = wrapAnsi16m(ANSI_BACKGROUND_OFFSET);
@@ -5957,17 +5957,67 @@ function assembleStyles() {
hexToAnsi256: { hexToAnsi256: {
value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)), value: hex => styles.rgbToAnsi256(...styles.hexToRgb(hex)),
enumerable: false enumerable: false
},
ansi256ToAnsi: {
value: code => {
if (code < 8) {
return 30 + code;
}
if (code < 16) {
return 90 + (code - 8);
}
let red;
let green;
let blue;
if (code >= 232) {
red = (((code - 232) * 10) + 8) / 255;
green = red;
blue = red;
} else {
code -= 16;
const remainder = code % 36;
red = Math.floor(code / 36) / 5;
green = Math.floor(remainder / 6) / 5;
blue = (remainder % 6) / 5;
}
const value = Math.max(red, green, blue) * 2;
if (value === 0) {
return 30;
}
let result = 30 + ((Math.round(blue) << 2) | (Math.round(green) << 1) | Math.round(red));
if (value === 2) {
result += 60;
}
return result;
},
enumerable: false
},
rgbToAnsi: {
value: (red, green, blue) => styles.ansi256ToAnsi(styles.rgbToAnsi256(red, green, blue)),
enumerable: false
},
hexToAnsi: {
value: hex => styles.ansi256ToAnsi(styles.hexToAnsi256(hex)),
enumerable: false
} }
}); });
return styles; return styles;
} }
// Make the export immutable const ansiStyles = assembleStyles();
Object.defineProperty(module, 'exports', {
enumerable: true, /* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (ansiStyles);
get: assembleStyles
});
/***/ }), /***/ }),
@@ -8958,8 +9008,8 @@ module.exports = require("zlib");;
/******/ } /******/ }
/******/ // Create a new module (and put it into the cache) /******/ // Create a new module (and put it into the cache)
/******/ var module = __webpack_module_cache__[moduleId] = { /******/ var module = __webpack_module_cache__[moduleId] = {
/******/ id: moduleId, /******/ // no module.id needed
/******/ loaded: false, /******/ // no module.loaded needed
/******/ exports: {} /******/ exports: {}
/******/ }; /******/ };
/******/ /******/
@@ -8972,20 +9022,36 @@ module.exports = require("zlib");;
/******/ if(threw) delete __webpack_module_cache__[moduleId]; /******/ if(threw) delete __webpack_module_cache__[moduleId];
/******/ } /******/ }
/******/ /******/
/******/ // Flag the module as loaded
/******/ module.loaded = true;
/******/
/******/ // Return the exports of the module /******/ // Return the exports of the module
/******/ return module.exports; /******/ return module.exports;
/******/ } /******/ }
/******/ /******/
/************************************************************************/ /************************************************************************/
/******/ /* webpack/runtime/node module decorator */ /******/ /* webpack/runtime/define property getters */
/******/ (() => { /******/ (() => {
/******/ __nccwpck_require__.nmd = (module) => { /******/ // define getter functions for harmony exports
/******/ module.paths = []; /******/ __nccwpck_require__.d = (exports, definition) => {
/******/ if (!module.children) module.children = []; /******/ for(var key in definition) {
/******/ return module; /******/ if(__nccwpck_require__.o(definition, key) && !__nccwpck_require__.o(exports, key)) {
/******/ Object.defineProperty(exports, key, { enumerable: true, get: definition[key] });
/******/ }
/******/ }
/******/ };
/******/ })();
/******/
/******/ /* webpack/runtime/hasOwnProperty shorthand */
/******/ (() => {
/******/ __nccwpck_require__.o = (obj, prop) => Object.prototype.hasOwnProperty.call(obj, prop)
/******/ })();
/******/
/******/ /* webpack/runtime/make namespace object */
/******/ (() => {
/******/ // define __esModule on exports
/******/ __nccwpck_require__.r = (exports) => {
/******/ if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/ Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/ }
/******/ Object.defineProperty(exports, '__esModule', { value: true });
/******/ }; /******/ };
/******/ })(); /******/ })();
/******/ /******/

View File

@@ -8,7 +8,6 @@ import {isDateMoreRecentThan} from '../functions/dates/is-date-more-recent-than'
import {isValidDate} from '../functions/dates/is-valid-date'; import {isValidDate} from '../functions/dates/is-valid-date';
import {isBoolean} from '../functions/is-boolean'; import {isBoolean} from '../functions/is-boolean';
import {isLabeled} from '../functions/is-labeled'; import {isLabeled} from '../functions/is-labeled';
import { cleanLabel } from '../functions/clean-label';
import {shouldMarkWhenStale} from '../functions/should-mark-when-stale'; import {shouldMarkWhenStale} from '../functions/should-mark-when-stale';
import {wordsToList} from '../functions/words-to-list'; import {wordsToList} from '../functions/words-to-list';
import {IComment} from '../interfaces/comment'; import {IComment} from '../interfaces/comment';
@@ -30,7 +29,7 @@ import {LoggerService} from '../services/logger.service';
*/ */
export class IssuesProcessor { export class IssuesProcessor {
private static _updatedSince(timestamp: string, num_days: number): boolean { private static _updatedSince(timestamp: string, num_days: number): boolean {
const daysInMillis = 1000 * 60 * 60 * 24 * num_days; const daysInMillis = 1000 * 60 * num_days; //temporarily number of minutes
const millisSinceLastUpdated = const millisSinceLastUpdated =
new Date().getTime() - new Date(timestamp).getTime(); new Date().getTime() - new Date(timestamp).getTime();
@@ -106,6 +105,7 @@ export class IssuesProcessor {
async processIssues(page: Readonly<number> = 1): Promise<number> { async processIssues(page: Readonly<number> = 1): Promise<number> {
// get the next batch of issues // get the next batch of issues
const issues: Issue[] = await this.getIssues(page); const issues: Issue[] = await this.getIssues(page);
const actor: string = await this.getActor();
if (issues.length <= 0) { if (issues.length <= 0) {
this._logger.info( this._logger.info(
@@ -145,6 +145,7 @@ export class IssuesProcessor {
await issueLogger.grouping(`$$type #${issue.number}`, async () => { await issueLogger.grouping(`$$type #${issue.number}`, async () => {
await this.processIssue( await this.processIssue(
issue, issue,
actor,
labelsToAddWhenUnstale, labelsToAddWhenUnstale,
labelsToRemoveWhenUnstale labelsToRemoveWhenUnstale
); );
@@ -183,6 +184,7 @@ export class IssuesProcessor {
async processIssue( async processIssue(
issue: Issue, issue: Issue,
actor: string,
labelsToAddWhenUnstale: Readonly<string>[], labelsToAddWhenUnstale: Readonly<string>[],
labelsToRemoveWhenUnstale: Readonly<string>[] labelsToRemoveWhenUnstale: Readonly<string>[]
): Promise<void> { ): Promise<void> {
@@ -453,7 +455,7 @@ export class IssuesProcessor {
await this._processStaleIssue( await this._processStaleIssue(
issue, issue,
staleLabel, staleLabel,
staleMessage, actor,
labelsToAddWhenUnstale, labelsToAddWhenUnstale,
labelsToRemoveWhenUnstale, labelsToRemoveWhenUnstale,
closeMessage, closeMessage,
@@ -486,6 +488,20 @@ export class IssuesProcessor {
} }
} }
// get the actor from the GitHub token or context
async getActor(): Promise<string> {
let actor;
try {
this.operations.consumeOperation();
actor = await this.client.users.getAuthenticated();
} catch (error) {
return context.actor;
}
return actor.data.login;
}
// grab issues from github in batches of 100 // grab issues from github in batches of 100
async getIssues(page: number): Promise<Issue[]> { async getIssues(page: number): Promise<Issue[]> {
// generate type for response // generate type for response
@@ -535,9 +551,10 @@ export class IssuesProcessor {
const events: IIssueEvent[] = await this.client.paginate(options); const events: IIssueEvent[] = await this.client.paginate(options);
const reversedEvents = events.reverse(); const reversedEvents = events.reverse();
issueLogger.info(`Reversed Events: ${JSON.stringify(reversedEvents)}`)
const staleLabeledEvent = reversedEvents.find( const staleLabeledEvent = reversedEvents.find(
event => event.event === 'labeled' && cleanLabel(event.label.name) === cleanLabel(label) event => event.event === 'labeled' && event.label.name === label
); );
if (!staleLabeledEvent) { if (!staleLabeledEvent) {
@@ -552,7 +569,7 @@ export class IssuesProcessor {
private async _processStaleIssue( private async _processStaleIssue(
issue: Issue, issue: Issue,
staleLabel: string, staleLabel: string,
staleMessage: string, actor: string,
labelsToAddWhenUnstale: Readonly<string>[], labelsToAddWhenUnstale: Readonly<string>[],
labelsToRemoveWhenUnstale: Readonly<string>[], labelsToRemoveWhenUnstale: Readonly<string>[],
closeMessage?: string, closeMessage?: string,
@@ -568,7 +585,7 @@ export class IssuesProcessor {
const issueHasComments: boolean = await this._hasCommentsSince( const issueHasComments: boolean = await this._hasCommentsSince(
issue, issue,
markedStaleOn, markedStaleOn,
staleMessage actor
); );
issueLogger.info( issueLogger.info(
`$$type has been commented on: ${LoggerService.cyan(issueHasComments)}` `$$type has been commented on: ${LoggerService.cyan(issueHasComments)}`
@@ -656,7 +673,7 @@ export class IssuesProcessor {
private async _hasCommentsSince( private async _hasCommentsSince(
issue: Issue, issue: Issue,
sinceDate: string, sinceDate: string,
staleMessage: string actor: string
): Promise<boolean> { ): Promise<boolean> {
const issueLogger: IssueLogger = new IssueLogger(issue); const issueLogger: IssueLogger = new IssueLogger(issue);
@@ -671,14 +688,14 @@ export class IssuesProcessor {
// find any comments since the date // find any comments since the date
const comments = await this.listIssueComments(issue.number, sinceDate); const comments = await this.listIssueComments(issue.number, sinceDate);
core.debug(`The actor is: ${actor}`)
core.debug(`The comments are ${JSON.stringify(comments)}`)
const filteredComments = comments.filter( const filteredComments = comments.filter(
comment => comment => comment.user.type === 'User' && comment.body !== IssuesProcessor._getStaleMessageUsedOptionName(issue)
comment.user.type === 'User' &&
comment.body.toLowerCase() !== staleMessage.toLowerCase()
); );
issueLogger.info( issueLogger.info(
`Comments that are not the stale comment or another bot: ${LoggerService.cyan( `Comments not made by actor or another bot: ${LoggerService.cyan(
filteredComments.length filteredComments.length
)}` )}`
); );

View File

@@ -1,14 +0,0 @@
import deburr from 'lodash.deburr';
import { CleanLabel } from '../types/clean-label';
/**
* @description
* Clean a label by lowercasing it and deburring it for consistency
*
* @param {string} label A raw GitHub label
*
* @return {string} A lowercased, deburred version of the passed in label
*/
export function cleanLabel(label: Readonly<string>): CleanLabel {
return deburr(label.toLowerCase());
}

View File

@@ -1,6 +1,7 @@
import deburr from 'lodash.deburr';
import {Issue} from '../classes/issue'; import {Issue} from '../classes/issue';
import {ILabel} from '../interfaces/label'; import {ILabel} from '../interfaces/label';
import {cleanLabel} from './clean-label'; import {CleanLabel} from '../types/clean-label';
/** /**
* @description * @description
@@ -19,3 +20,7 @@ export function isLabeled(
return cleanLabel(label) === cleanLabel(issueLabel.name); return cleanLabel(label) === cleanLabel(issueLabel.name);
}); });
} }
function cleanLabel(label: Readonly<string>): CleanLabel {
return deburr(label.toLowerCase());
}