mirror of
https://github.com/actions/stale.git
synced 2025-12-25 09:58:16 +00:00
Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
997185467f | ||
|
|
5611b9defa | ||
|
|
fad0de84e5 | ||
|
|
39bea7de61 | ||
|
|
e46bbabb3e | ||
|
|
65d1d4804d | ||
|
|
5f858e3efb | ||
|
|
3a9db7e6a4 |
2
.github/workflows/e2e-tests.yml
vendored
2
.github/workflows/e2e-tests.yml
vendored
@@ -15,7 +15,7 @@ jobs:
|
|||||||
dry-run-test: # make sure the action works on a clean machine without building
|
dry-run-test: # make sure the action works on a clean machine without building
|
||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- uses: actions/checkout@v4
|
- uses: actions/checkout@v6
|
||||||
- uses: ./
|
- uses: ./
|
||||||
id: stale
|
id: stale
|
||||||
with:
|
with:
|
||||||
|
|||||||
@@ -14,7 +14,7 @@ jobs:
|
|||||||
|
|
||||||
steps:
|
steps:
|
||||||
- name: Checking out
|
- name: Checking out
|
||||||
uses: actions/checkout@v4
|
uses: actions/checkout@v6
|
||||||
- name: Publish
|
- name: Publish
|
||||||
id: publish
|
id: publish
|
||||||
uses: actions/publish-immutable-action@v0.0.4
|
uses: actions/publish-immutable-action@v0.0.4
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Update the ${{ env.TAG_NAME }} tag
|
- name: Update the ${{ env.TAG_NAME }} tag
|
||||||
uses: actions/publish-action@v0.3.0
|
uses: actions/publish-action@v0.4.0
|
||||||
with:
|
with:
|
||||||
source-tag: ${{ env.TAG_NAME }}
|
source-tag: ${{ env.TAG_NAME }}
|
||||||
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
slack-webhook: ${{ secrets.SLACK_WEBHOOK }}
|
||||||
|
|||||||
2
.licenses/npm/@types/node.dep.yml
generated
2
.licenses/npm/@types/node.dep.yml
generated
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: "@types/node"
|
name: "@types/node"
|
||||||
version: 24.1.0
|
version: 24.3.1
|
||||||
type: npm
|
type: npm
|
||||||
summary: TypeScript definitions for node
|
summary: TypeScript definitions for node
|
||||||
homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node
|
homepage: https://github.com/DefinitelyTyped/DefinitelyTyped/tree/master/types/node
|
||||||
|
|||||||
2
.licenses/npm/undici-types.dep.yml
generated
2
.licenses/npm/undici-types.dep.yml
generated
@@ -1,6 +1,6 @@
|
|||||||
---
|
---
|
||||||
name: undici-types
|
name: undici-types
|
||||||
version: 7.8.0
|
version: 7.10.0
|
||||||
type: npm
|
type: npm
|
||||||
summary: A stand-alone types package for Undici
|
summary: A stand-alone types package for Undici
|
||||||
homepage: https://undici.nodejs.org
|
homepage: https://undici.nodejs.org
|
||||||
|
|||||||
30
CHANGELOG.md
30
CHANGELOG.md
@@ -1,5 +1,35 @@
|
|||||||
# Changelog
|
# Changelog
|
||||||
|
|
||||||
|
# [10.1.0]
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
|
||||||
|
* Add only-issue-types option to filter issues by type by @Bibo-Joshi in https://github.com/actions/stale/pull/1255
|
||||||
|
|
||||||
|
# [10.0.0]
|
||||||
|
|
||||||
|
## What's Changed
|
||||||
|
|
||||||
|
## Breaking Changes
|
||||||
|
* Upgrade to node 24 by @salmanmkc in https://github.com/actions/stale/pull/1279
|
||||||
|
Make sure your runner is on version v2.327.1 or later to ensure compatibility with this release. [Release Notes](https://github.com/actions/runner/releases/tag/v2.327.1)
|
||||||
|
|
||||||
|
## Enhancement
|
||||||
|
- Introducing sort-by option by @suyashgaonkar in https://github.com/actions/stale/pull/1254
|
||||||
|
|
||||||
|
## Dependency Upgrades
|
||||||
|
* Upgrade actions/publish-immutable-action from 0.0.3 to 0.0.4 by @dependabot[bot] in https://github.com/actions/stale/pull/1186
|
||||||
|
* Upgrade undici from 5.28.4 to 5.28.5 by @dependabot[bot] in https://github.com/actions/stale/pull/1201
|
||||||
|
* Upgrade @action/cache from 4.0.0 to 4.0.2 by @aparnajyothi-y in https://github.com/actions/stale/pull/1226
|
||||||
|
* Upgrade @action/cache from 4.0.2 to 4.0.3 by @suyashgaonkar in https://github.com/actions/stale/pull/1233
|
||||||
|
* Upgrade undici from 5.28.5 to 5.29.0 by @dependabot[bot] in https://github.com/actions/stale/pull/1251
|
||||||
|
* Upgrade form-data to bring in fix for critical vulnerability by @gowridurgad in https://github.com/actions/stale/pull/1277
|
||||||
|
|
||||||
|
## Documentation changes
|
||||||
|
|
||||||
|
- Changelog update for recent releases by @suyashgaonkar in https://github.com/actions/stale/pull/1224
|
||||||
|
- Permissions update in Readme by @ghadimir in https://github.com/actions/stale/pull/1248
|
||||||
|
|
||||||
# [9.1.0]
|
# [9.1.0]
|
||||||
|
|
||||||
## What's Changed
|
## What's Changed
|
||||||
|
|||||||
17
README.md
17
README.md
@@ -3,6 +3,13 @@
|
|||||||
[](https://github.com/actions/stale/actions/workflows/basic-validation.yml)
|
[](https://github.com/actions/stale/actions/workflows/basic-validation.yml)
|
||||||
[](https://github.com/actions/stale/actions/workflows/e2e-tests.yml)
|
[](https://github.com/actions/stale/actions/workflows/e2e-tests.yml)
|
||||||
|
|
||||||
|
## Breaking changes in V10
|
||||||
|
|
||||||
|
- Upgraded action from node20 to node 24
|
||||||
|
> Make sure your runner is on version v2.327.1 or later to ensure compatibility with this release. [Release Notes](https://github.com/actions/runner/releases/tag/v2.327.1)
|
||||||
|
|
||||||
|
For more details, see the full release notes on the [release page](https://github.com/actions/stale/releases/tag/v10.0.0)
|
||||||
|
|
||||||
Warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
Warns and then closes issues and PRs that have had no activity for a specified amount of time.
|
||||||
|
|
||||||
The configuration must be on the default branch and the default values will:
|
The configuration must be on the default branch and the default values will:
|
||||||
@@ -98,7 +105,8 @@ Every argument is optional.
|
|||||||
| [ignore-issue-updates](#ignore-issue-updates) | Override [ignore-updates](#ignore-updates) for issues only | |
|
| [ignore-issue-updates](#ignore-issue-updates) | Override [ignore-updates](#ignore-updates) for issues only | |
|
||||||
| [ignore-pr-updates](#ignore-pr-updates) | Override [ignore-updates](#ignore-updates) for PRs only | |
|
| [ignore-pr-updates](#ignore-pr-updates) | Override [ignore-updates](#ignore-updates) for PRs only | |
|
||||||
| [include-only-assigned](#include-only-assigned) | Process only assigned issues | `false` |
|
| [include-only-assigned](#include-only-assigned) | Process only assigned issues | `false` |
|
||||||
| [sort-by](#sort-by) | What to sort issues and PRs by | `created` |
|
| [sort-by](#sort-by) | What to sort issues and PRs by | `created` |
|
||||||
|
| [only-issue-types](#only-issue-types) | Only issues with a matching type are processed as stale/closed. | |
|
||||||
|
|
||||||
### List of output options
|
### List of output options
|
||||||
|
|
||||||
@@ -555,6 +563,13 @@ Useful to sort the issues and PRs by the specified field. It accepts `created`,
|
|||||||
|
|
||||||
Default value: `created`
|
Default value: `created`
|
||||||
|
|
||||||
|
#### only-issue-types
|
||||||
|
|
||||||
|
A comma separated list of allowed issue types. Only issues with a matching type will be processed (e.g.: `bug,question`).
|
||||||
|
|
||||||
|
If unset (or an empty string), this option will not alter the stale workflow.
|
||||||
|
|
||||||
|
Default value: unset
|
||||||
|
|
||||||
### Usage
|
### Usage
|
||||||
|
|
||||||
|
|||||||
@@ -15,7 +15,8 @@ export function generateIssue(
|
|||||||
isClosed = false,
|
isClosed = false,
|
||||||
isLocked = false,
|
isLocked = false,
|
||||||
milestone: string | undefined = undefined,
|
milestone: string | undefined = undefined,
|
||||||
assignees: string[] = []
|
assignees: string[] = [],
|
||||||
|
issue_type?: string
|
||||||
): Issue {
|
): Issue {
|
||||||
return new Issue(options, {
|
return new Issue(options, {
|
||||||
number: id,
|
number: id,
|
||||||
@@ -39,6 +40,7 @@ export function generateIssue(
|
|||||||
login: assignee,
|
login: assignee,
|
||||||
type: 'User'
|
type: 'User'
|
||||||
};
|
};
|
||||||
})
|
}),
|
||||||
|
...(issue_type ? {type: {name: issue_type}} : {})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
125
__tests__/only-issue-types.spec.ts
Normal file
125
__tests__/only-issue-types.spec.ts
Normal file
@@ -0,0 +1,125 @@
|
|||||||
|
import {Issue} from '../src/classes/issue';
|
||||||
|
import {IIssuesProcessorOptions} from '../src/interfaces/issues-processor-options';
|
||||||
|
import {IssuesProcessorMock} from './classes/issues-processor-mock';
|
||||||
|
import {DefaultProcessorOptions} from './constants/default-processor-options';
|
||||||
|
import {generateIssue} from './functions/generate-issue';
|
||||||
|
import {alwaysFalseStateMock} from './classes/state-mock';
|
||||||
|
|
||||||
|
describe('only-issue-types option', () => {
|
||||||
|
test('should only process issues with allowed type', async () => {
|
||||||
|
const opts: IIssuesProcessorOptions = {
|
||||||
|
...DefaultProcessorOptions,
|
||||||
|
onlyIssueTypes: 'bug,question'
|
||||||
|
};
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(
|
||||||
|
opts,
|
||||||
|
1,
|
||||||
|
'A bug',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
'bug'
|
||||||
|
),
|
||||||
|
generateIssue(
|
||||||
|
opts,
|
||||||
|
2,
|
||||||
|
'A feature',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
'feature'
|
||||||
|
),
|
||||||
|
generateIssue(
|
||||||
|
opts,
|
||||||
|
3,
|
||||||
|
'A question',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
'question'
|
||||||
|
)
|
||||||
|
];
|
||||||
|
const processor = new IssuesProcessorMock(
|
||||||
|
opts,
|
||||||
|
alwaysFalseStateMock,
|
||||||
|
async p => (p === 1 ? TestIssueList : []),
|
||||||
|
async () => [],
|
||||||
|
async () => new Date().toDateString()
|
||||||
|
);
|
||||||
|
await processor.processIssues(1);
|
||||||
|
expect(processor.staleIssues.map(i => i.title)).toEqual([
|
||||||
|
'A bug',
|
||||||
|
'A question'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
|
||||||
|
test('should process all issues if onlyIssueTypes is unset', async () => {
|
||||||
|
const opts: IIssuesProcessorOptions = {
|
||||||
|
...DefaultProcessorOptions,
|
||||||
|
onlyIssueTypes: ''
|
||||||
|
};
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(
|
||||||
|
opts,
|
||||||
|
1,
|
||||||
|
'A bug',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
'bug'
|
||||||
|
),
|
||||||
|
generateIssue(
|
||||||
|
opts,
|
||||||
|
2,
|
||||||
|
'A feature',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
[],
|
||||||
|
false,
|
||||||
|
false,
|
||||||
|
undefined,
|
||||||
|
[],
|
||||||
|
'feature'
|
||||||
|
)
|
||||||
|
];
|
||||||
|
const processor = new IssuesProcessorMock(
|
||||||
|
opts,
|
||||||
|
alwaysFalseStateMock,
|
||||||
|
async p => (p === 1 ? TestIssueList : []),
|
||||||
|
async () => [],
|
||||||
|
async () => new Date().toDateString()
|
||||||
|
);
|
||||||
|
await processor.processIssues(1);
|
||||||
|
expect(processor.staleIssues.map(i => i.title)).toEqual([
|
||||||
|
'A bug',
|
||||||
|
'A feature'
|
||||||
|
]);
|
||||||
|
});
|
||||||
|
});
|
||||||
@@ -208,6 +208,10 @@ inputs:
|
|||||||
description: 'Only the issues or the pull requests with an assignee will be marked as stale automatically.'
|
description: 'Only the issues or the pull requests with an assignee will be marked as stale automatically.'
|
||||||
default: 'false'
|
default: 'false'
|
||||||
required: false
|
required: false
|
||||||
|
only-issue-types:
|
||||||
|
description: 'Only issues with a matching type are processed as stale/closed. Defaults to `[]` (disabled) and can be a comma-separated list of issue types.'
|
||||||
|
default: ''
|
||||||
|
required: false
|
||||||
outputs:
|
outputs:
|
||||||
closed-issues-prs:
|
closed-issues-prs:
|
||||||
description: 'List of all closed issues and pull requests.'
|
description: 'List of all closed issues and pull requests.'
|
||||||
|
|||||||
32
dist/index.js
vendored
32
dist/index.js
vendored
@@ -289,6 +289,13 @@ class Issue {
|
|||||||
this.assignees = issue.assignees || [];
|
this.assignees = issue.assignees || [];
|
||||||
this.isStale = (0, is_labeled_1.isLabeled)(this, this.staleLabel);
|
this.isStale = (0, is_labeled_1.isLabeled)(this, this.staleLabel);
|
||||||
this.markedStaleThisRun = false;
|
this.markedStaleThisRun = false;
|
||||||
|
if (typeof issue.type === 'object' &&
|
||||||
|
issue.type !== null) {
|
||||||
|
this.issue_type = issue.type.name;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
this.issue_type = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
get isPullRequest() {
|
get isPullRequest() {
|
||||||
return (0, is_pull_request_1.isPullRequest)(this);
|
return (0, is_pull_request_1.isPullRequest)(this);
|
||||||
@@ -506,6 +513,18 @@ class IssuesProcessor {
|
|||||||
IssuesProcessor._endIssueProcessing(issue);
|
IssuesProcessor._endIssueProcessing(issue);
|
||||||
return; // If the issue has an 'include-only-assigned' option set, process only issues with nonempty assignees list
|
return; // If the issue has an 'include-only-assigned' option set, process only issues with nonempty assignees list
|
||||||
}
|
}
|
||||||
|
if (this.options.onlyIssueTypes) {
|
||||||
|
const allowedTypes = this.options.onlyIssueTypes
|
||||||
|
.split(',')
|
||||||
|
.map(t => t.trim().toLowerCase())
|
||||||
|
.filter(Boolean);
|
||||||
|
const issueType = (issue.issue_type || '').toLowerCase();
|
||||||
|
if (!allowedTypes.includes(issueType)) {
|
||||||
|
issueLogger.info(`Skipping this $$type because its type ('${issue.issue_type}') is not in onlyIssueTypes (${allowedTypes.join(', ')})`);
|
||||||
|
IssuesProcessor._endIssueProcessing(issue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
const onlyLabels = (0, words_to_list_1.wordsToList)(this._getOnlyLabels(issue));
|
const onlyLabels = (0, words_to_list_1.wordsToList)(this._getOnlyLabels(issue));
|
||||||
if (onlyLabels.length > 0) {
|
if (onlyLabels.length > 0) {
|
||||||
issueLogger.info(`The option ${issueLogger.createOptionLink(option_1.Option.OnlyLabels)} was specified to only process issues and pull requests with all those labels (${logger_service_1.LoggerService.cyan(onlyLabels.length)})`);
|
issueLogger.info(`The option ${issueLogger.createOptionLink(option_1.Option.OnlyLabels)} was specified to only process issues and pull requests with all those labels (${logger_service_1.LoggerService.cyan(onlyLabels.length)})`);
|
||||||
@@ -742,6 +761,7 @@ class IssuesProcessor {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
getRateLimit() {
|
getRateLimit() {
|
||||||
|
var _a;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
const logger = new logger_1.Logger();
|
const logger = new logger_1.Logger();
|
||||||
try {
|
try {
|
||||||
@@ -749,7 +769,13 @@ class IssuesProcessor {
|
|||||||
return new rate_limit_1.RateLimit(rateLimitResult.data.rate);
|
return new rate_limit_1.RateLimit(rateLimitResult.data.rate);
|
||||||
}
|
}
|
||||||
catch (error) {
|
catch (error) {
|
||||||
logger.error(`Error when getting rateLimit: ${error.message}`);
|
const status = error === null || error === void 0 ? void 0 : error.status;
|
||||||
|
const message = (_a = error === null || error === void 0 ? void 0 : error.message) !== null && _a !== void 0 ? _a : String(error);
|
||||||
|
if (status === 404 && message.includes('Rate limiting is not enabled')) {
|
||||||
|
logger.warning('Rate limiting is not enabled on this instance. Proceeding without rate limit checks.');
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
logger.error(`Error when getting rateLimit: ${message}`);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
@@ -2225,6 +2251,7 @@ var Option;
|
|||||||
Option["IgnorePrUpdates"] = "ignore-pr-updates";
|
Option["IgnorePrUpdates"] = "ignore-pr-updates";
|
||||||
Option["ExemptDraftPr"] = "exempt-draft-pr";
|
Option["ExemptDraftPr"] = "exempt-draft-pr";
|
||||||
Option["CloseIssueReason"] = "close-issue-reason";
|
Option["CloseIssueReason"] = "close-issue-reason";
|
||||||
|
Option["OnlyIssueTypes"] = "only-issue-types";
|
||||||
})(Option || (exports.Option = Option = {}));
|
})(Option || (exports.Option = Option = {}));
|
||||||
|
|
||||||
|
|
||||||
@@ -2590,7 +2617,8 @@ function _getAndValidateArgs() {
|
|||||||
ignorePrUpdates: _toOptionalBoolean('ignore-pr-updates'),
|
ignorePrUpdates: _toOptionalBoolean('ignore-pr-updates'),
|
||||||
exemptDraftPr: core.getInput('exempt-draft-pr') === 'true',
|
exemptDraftPr: core.getInput('exempt-draft-pr') === 'true',
|
||||||
closeIssueReason: core.getInput('close-issue-reason'),
|
closeIssueReason: core.getInput('close-issue-reason'),
|
||||||
includeOnlyAssigned: core.getInput('include-only-assigned') === 'true'
|
includeOnlyAssigned: core.getInput('include-only-assigned') === 'true',
|
||||||
|
onlyIssueTypes: core.getInput('only-issue-types')
|
||||||
};
|
};
|
||||||
for (const numberInput of ['days-before-stale']) {
|
for (const numberInput of ['days-before-stale']) {
|
||||||
if (isNaN(parseFloat(core.getInput(numberInput)))) {
|
if (isNaN(parseFloat(core.getInput(numberInput)))) {
|
||||||
|
|||||||
28
package-lock.json
generated
28
package-lock.json
generated
@@ -20,14 +20,14 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/lodash.deburr": "^4.1.6",
|
"@types/lodash.deburr": "^4.1.6",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "^24.3.1",
|
||||||
"@types/semver": "^7.5.0",
|
"@types/semver": "^7.5.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
||||||
"@typescript-eslint/parser": "^6.2.1",
|
"@typescript-eslint/parser": "^6.2.1",
|
||||||
"@vercel/ncc": "^0.36.1",
|
"@vercel/ncc": "^0.36.1",
|
||||||
"ansi-styles": "5.2.0",
|
"ansi-styles": "5.2.0",
|
||||||
"eslint": "^8.46.0",
|
"eslint": "^8.46.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-jest": "^27.2.3",
|
"eslint-plugin-jest": "^27.2.3",
|
||||||
"eslint-plugin-node": "^11.1.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"jest": "^29.6.2",
|
"jest": "^29.6.2",
|
||||||
@@ -1854,12 +1854,12 @@
|
|||||||
"dev": true
|
"dev": true
|
||||||
},
|
},
|
||||||
"node_modules/@types/node": {
|
"node_modules/@types/node": {
|
||||||
"version": "24.1.0",
|
"version": "24.3.1",
|
||||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.1.0.tgz",
|
"resolved": "https://registry.npmjs.org/@types/node/-/node-24.3.1.tgz",
|
||||||
"integrity": "sha512-ut5FthK5moxFKH2T1CUOC6ctR67rQRvvHdFLCD2Ql6KXmMuCrjsSsRI9UsLCm9M18BMwClv4pn327UvB7eeO1w==",
|
"integrity": "sha512-3vXmQDXy+woz+gnrTvuvNrPzekOi+Ds0ReMxw0LzBiK3a+1k0kQn9f2NWk+lgD4rJehFUmYy2gMhJ2ZI+7YP9g==",
|
||||||
"license": "MIT",
|
"license": "MIT",
|
||||||
"dependencies": {
|
"dependencies": {
|
||||||
"undici-types": "~7.8.0"
|
"undici-types": "~7.10.0"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/@types/node-fetch": {
|
"node_modules/@types/node-fetch": {
|
||||||
@@ -3477,13 +3477,17 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/eslint-config-prettier": {
|
"node_modules/eslint-config-prettier": {
|
||||||
"version": "8.10.0",
|
"version": "10.1.8",
|
||||||
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-8.10.0.tgz",
|
"resolved": "https://registry.npmjs.org/eslint-config-prettier/-/eslint-config-prettier-10.1.8.tgz",
|
||||||
"integrity": "sha512-SM8AMJdeQqRYT9O9zguiruQZaN7+z+E4eAP9oiLNGKMtomwaB1E9dcgUD6ZAn/eQAb52USbvezbiljfZUhbJcg==",
|
"integrity": "sha512-82GZUjRS0p/jganf6q1rEO25VSoHH0hKPCTrgillPjdI/3bgBhAE1QzHrHTizjpRvy6pGAvKjDJtk2pF9NDq8w==",
|
||||||
"dev": true,
|
"dev": true,
|
||||||
|
"license": "MIT",
|
||||||
"bin": {
|
"bin": {
|
||||||
"eslint-config-prettier": "bin/cli.js"
|
"eslint-config-prettier": "bin/cli.js"
|
||||||
},
|
},
|
||||||
|
"funding": {
|
||||||
|
"url": "https://opencollective.com/eslint-config-prettier"
|
||||||
|
},
|
||||||
"peerDependencies": {
|
"peerDependencies": {
|
||||||
"eslint": ">=7.0.0"
|
"eslint": ">=7.0.0"
|
||||||
}
|
}
|
||||||
@@ -7522,9 +7526,9 @@
|
|||||||
}
|
}
|
||||||
},
|
},
|
||||||
"node_modules/undici-types": {
|
"node_modules/undici-types": {
|
||||||
"version": "7.8.0",
|
"version": "7.10.0",
|
||||||
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.8.0.tgz",
|
"resolved": "https://registry.npmjs.org/undici-types/-/undici-types-7.10.0.tgz",
|
||||||
"integrity": "sha512-9UJ2xGDvQ43tYyVMpuHlsgApydB8ZKfVYTsLDhXkFL/6gfkp+U8xTGdh8pMJv1SpZna0zxG1DwsKZsreLbXBxw==",
|
"integrity": "sha512-t5Fy/nfn+14LuOc2KNYg75vZqClpAiqscVvMygNnlsHBFpSXdJaYtXMcdNLpl/Qvc3P2cB3s6lOV51nqsFq4ag==",
|
||||||
"license": "MIT"
|
"license": "MIT"
|
||||||
},
|
},
|
||||||
"node_modules/universal-user-agent": {
|
"node_modules/universal-user-agent": {
|
||||||
|
|||||||
@@ -48,14 +48,14 @@
|
|||||||
"devDependencies": {
|
"devDependencies": {
|
||||||
"@types/jest": "^29.5.14",
|
"@types/jest": "^29.5.14",
|
||||||
"@types/lodash.deburr": "^4.1.6",
|
"@types/lodash.deburr": "^4.1.6",
|
||||||
"@types/node": "^24.1.0",
|
"@types/node": "^24.3.1",
|
||||||
"@types/semver": "^7.5.0",
|
"@types/semver": "^7.5.0",
|
||||||
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
"@typescript-eslint/eslint-plugin": "^6.2.1",
|
||||||
"@typescript-eslint/parser": "^6.2.1",
|
"@typescript-eslint/parser": "^6.2.1",
|
||||||
"@vercel/ncc": "^0.36.1",
|
"@vercel/ncc": "^0.36.1",
|
||||||
"ansi-styles": "5.2.0",
|
"ansi-styles": "5.2.0",
|
||||||
"eslint": "^8.46.0",
|
"eslint": "^8.46.0",
|
||||||
"eslint-config-prettier": "^8.8.0",
|
"eslint-config-prettier": "^10.1.8",
|
||||||
"eslint-plugin-jest": "^27.2.3",
|
"eslint-plugin-jest": "^27.2.3",
|
||||||
"eslint-plugin-node": "^11.1.0",
|
"eslint-plugin-node": "^11.1.0",
|
||||||
"jest": "^29.6.2",
|
"jest": "^29.6.2",
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ export class Issue implements IIssue {
|
|||||||
markedStaleThisRun: boolean;
|
markedStaleThisRun: boolean;
|
||||||
operations = new Operations();
|
operations = new Operations();
|
||||||
private readonly _options: IIssuesProcessorOptions;
|
private readonly _options: IIssuesProcessorOptions;
|
||||||
|
readonly issue_type?: string;
|
||||||
|
|
||||||
constructor(
|
constructor(
|
||||||
options: Readonly<IIssuesProcessorOptions>,
|
options: Readonly<IIssuesProcessorOptions>,
|
||||||
@@ -43,6 +44,15 @@ export class Issue implements IIssue {
|
|||||||
this.assignees = issue.assignees || [];
|
this.assignees = issue.assignees || [];
|
||||||
this.isStale = isLabeled(this, this.staleLabel);
|
this.isStale = isLabeled(this, this.staleLabel);
|
||||||
this.markedStaleThisRun = false;
|
this.markedStaleThisRun = false;
|
||||||
|
|
||||||
|
if (
|
||||||
|
typeof (issue as any).type === 'object' &&
|
||||||
|
(issue as any).type !== null
|
||||||
|
) {
|
||||||
|
this.issue_type = (issue as any).type.name;
|
||||||
|
} else {
|
||||||
|
this.issue_type = undefined;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
get isPullRequest(): boolean {
|
get isPullRequest(): boolean {
|
||||||
|
|||||||
@@ -252,6 +252,23 @@ export class IssuesProcessor {
|
|||||||
return; // If the issue has an 'include-only-assigned' option set, process only issues with nonempty assignees list
|
return; // If the issue has an 'include-only-assigned' option set, process only issues with nonempty assignees list
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (this.options.onlyIssueTypes) {
|
||||||
|
const allowedTypes = this.options.onlyIssueTypes
|
||||||
|
.split(',')
|
||||||
|
.map(t => t.trim().toLowerCase())
|
||||||
|
.filter(Boolean);
|
||||||
|
const issueType = (issue.issue_type || '').toLowerCase();
|
||||||
|
if (!allowedTypes.includes(issueType)) {
|
||||||
|
issueLogger.info(
|
||||||
|
`Skipping this $$type because its type ('${
|
||||||
|
issue.issue_type
|
||||||
|
}') is not in onlyIssueTypes (${allowedTypes.join(', ')})`
|
||||||
|
);
|
||||||
|
IssuesProcessor._endIssueProcessing(issue);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const onlyLabels: string[] = wordsToList(this._getOnlyLabels(issue));
|
const onlyLabels: string[] = wordsToList(this._getOnlyLabels(issue));
|
||||||
|
|
||||||
if (onlyLabels.length > 0) {
|
if (onlyLabels.length > 0) {
|
||||||
@@ -643,11 +660,22 @@ export class IssuesProcessor {
|
|||||||
|
|
||||||
async getRateLimit(): Promise<IRateLimit | undefined> {
|
async getRateLimit(): Promise<IRateLimit | undefined> {
|
||||||
const logger: Logger = new Logger();
|
const logger: Logger = new Logger();
|
||||||
|
|
||||||
try {
|
try {
|
||||||
const rateLimitResult = await this.client.rest.rateLimit.get();
|
const rateLimitResult = await this.client.rest.rateLimit.get();
|
||||||
return new RateLimit(rateLimitResult.data.rate);
|
return new RateLimit(rateLimitResult.data.rate);
|
||||||
} catch (error) {
|
} catch (error: unknown) {
|
||||||
logger.error(`Error when getting rateLimit: ${error.message}`);
|
const status = (error as {status?: number})?.status;
|
||||||
|
const message = (error as {message?: string})?.message ?? String(error);
|
||||||
|
|
||||||
|
if (status === 404 && message.includes('Rate limiting is not enabled')) {
|
||||||
|
logger.warning(
|
||||||
|
'Rate limiting is not enabled on this instance. Proceeding without rate limit checks.'
|
||||||
|
);
|
||||||
|
return undefined;
|
||||||
|
}
|
||||||
|
|
||||||
|
logger.error(`Error when getting rateLimit: ${message}`);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,5 +49,6 @@ export enum Option {
|
|||||||
IgnoreIssueUpdates = 'ignore-issue-updates',
|
IgnoreIssueUpdates = 'ignore-issue-updates',
|
||||||
IgnorePrUpdates = 'ignore-pr-updates',
|
IgnorePrUpdates = 'ignore-pr-updates',
|
||||||
ExemptDraftPr = 'exempt-draft-pr',
|
ExemptDraftPr = 'exempt-draft-pr',
|
||||||
CloseIssueReason = 'close-issue-reason'
|
CloseIssueReason = 'close-issue-reason',
|
||||||
|
OnlyIssueTypes = 'only-issue-types'
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -15,6 +15,7 @@ export interface IIssue {
|
|||||||
locked: boolean;
|
locked: boolean;
|
||||||
milestone?: IMilestone | null;
|
milestone?: IMilestone | null;
|
||||||
assignees?: Assignee[] | null;
|
assignees?: Assignee[] | null;
|
||||||
|
issue_type?: string;
|
||||||
}
|
}
|
||||||
|
|
||||||
export type OctokitIssue = components['schemas']['issue'];
|
export type OctokitIssue = components['schemas']['issue'];
|
||||||
|
|||||||
@@ -55,4 +55,5 @@ export interface IIssuesProcessorOptions {
|
|||||||
exemptDraftPr: boolean;
|
exemptDraftPr: boolean;
|
||||||
closeIssueReason: string;
|
closeIssueReason: string;
|
||||||
includeOnlyAssigned: boolean;
|
includeOnlyAssigned: boolean;
|
||||||
|
onlyIssueTypes?: string;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -124,7 +124,8 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
|
|||||||
ignorePrUpdates: _toOptionalBoolean('ignore-pr-updates'),
|
ignorePrUpdates: _toOptionalBoolean('ignore-pr-updates'),
|
||||||
exemptDraftPr: core.getInput('exempt-draft-pr') === 'true',
|
exemptDraftPr: core.getInput('exempt-draft-pr') === 'true',
|
||||||
closeIssueReason: core.getInput('close-issue-reason'),
|
closeIssueReason: core.getInput('close-issue-reason'),
|
||||||
includeOnlyAssigned: core.getInput('include-only-assigned') === 'true'
|
includeOnlyAssigned: core.getInput('include-only-assigned') === 'true',
|
||||||
|
onlyIssueTypes: core.getInput('only-issue-types')
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const numberInput of ['days-before-stale']) {
|
for (const numberInput of ['days-before-stale']) {
|
||||||
|
|||||||
Reference in New Issue
Block a user