Add support for adding & removing labels when no longer stale (#468)
* Add support for adding & removing labels when no longer stale * Add remove/addLabelsWhenUpdatedFromStale to relevant spec files. Modify arguments to remove ambiguity in 'labels' var & parameter * Change parameters for clarity, let autoformat do its thing * PR feedback: More useful logging when removing labels * Wrap client calls in try catches * Use Unstale in variable names * Don't run add label logic under debug * Add test for labels added to unstale issues * PR Feedback: logging * Update README * Rename vars to labels-to-add/remove-when-unstale * Apply doc suggestions from code review Co-authored-by: Geoffrey Testelin <geoffrey.testelin@gmail.com> * PR Feedback Co-authored-by: Geoffrey Testelin <geoffrey.testelin@gmail.com>
This commit is contained in:
parent
52f5648db3
commit
b1da9e1fb1
16
README.md
16
README.md
|
@ -43,6 +43,8 @@ Every argument is optional.
|
||||||
| [remove-stale-when-updated](#remove-stale-when-updated) | Remove stale label from issues/PRs on updates/comments | `true` |
|
| [remove-stale-when-updated](#remove-stale-when-updated) | Remove stale label from issues/PRs on updates/comments | `true` |
|
||||||
| [remove-issue-stale-when-updated](#remove-issue-stale-when-updated) | Remove stale label from issues on updates/comments | |
|
| [remove-issue-stale-when-updated](#remove-issue-stale-when-updated) | Remove stale label from issues on updates/comments | |
|
||||||
| [remove-pr-stale-when-updated](#remove-pr-stale-when-updated) | Remove stale label from PRs on updates/comments | |
|
| [remove-pr-stale-when-updated](#remove-pr-stale-when-updated) | Remove stale label from PRs on updates/comments | |
|
||||||
|
| [labels-to-add-when-unstale](#labels-to-add-when-unstale) | Add specified labels from issues/PRs when they become unstale | |
|
||||||
|
| [labels-to-remove-when-unstale](#labels-to-remove-when-unstale) | Remove specified labels from issues/PRs when they become unstale | |
|
||||||
| [debug-only](#debug-only) | Dry-run | `false` |
|
| [debug-only](#debug-only) | Dry-run | `false` |
|
||||||
| [ascending](#ascending) | Order to get issues/PRs | `false` |
|
| [ascending](#ascending) | Order to get issues/PRs | `false` |
|
||||||
| [start-date](#start-date) | Skip stale action for issues/PRs created before it | |
|
| [start-date](#start-date) | Skip stale action for issues/PRs created before it | |
|
||||||
|
@ -307,6 +309,20 @@ Override [remove-stale-when-updated](#remove-stale-when-updated) but only to aut
|
||||||
|
|
||||||
Default value: unset
|
Default value: unset
|
||||||
|
|
||||||
|
#### labels-to-add-when-unstale
|
||||||
|
|
||||||
|
A comma delimited list of labels to add when a stale issue or pull request receives activity and has the [stale-issue-label](#stale-issue-label) or [stale-pr-label](#stale-pr-label) removed from it.
|
||||||
|
|
||||||
|
Default value: unset
|
||||||
|
|
||||||
|
#### labels-to-remove-when-unstale
|
||||||
|
|
||||||
|
A comma delimited list of labels to remove when a stale issue or pull request receives activity and has the [stale-issue-label](#stale-issue-label) or [stale-pr-label](#stale-pr-label) removed from it.
|
||||||
|
|
||||||
|
Warning: each label results in a unique API call which can drastically consume the limit of [operations-per-run](#operations-per-run).
|
||||||
|
|
||||||
|
Default value: unset
|
||||||
|
|
||||||
#### debug-only
|
#### debug-only
|
||||||
|
|
||||||
Run the stale workflow as dry-run.
|
Run the stale workflow as dry-run.
|
||||||
|
|
|
@ -44,5 +44,7 @@ export const DefaultProcessorOptions: IIssuesProcessorOptions = Object.freeze({
|
||||||
exemptAllAssignees: false,
|
exemptAllAssignees: false,
|
||||||
exemptAllIssueAssignees: undefined,
|
exemptAllIssueAssignees: undefined,
|
||||||
exemptAllPrAssignees: undefined,
|
exemptAllPrAssignees: undefined,
|
||||||
enableStatistics: true
|
enableStatistics: true,
|
||||||
|
labelsToRemoveWhenUnstale: '',
|
||||||
|
labelsToAddWhenUnstale: ''
|
||||||
});
|
});
|
||||||
|
|
|
@ -1255,6 +1255,50 @@ test('stale label should be removed if a comment was added to a stale issue', as
|
||||||
expect(processor.removedLabelIssues).toHaveLength(1);
|
expect(processor.removedLabelIssues).toHaveLength(1);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
test('when the option "labelsToAddWhenUnstale" is set, the labels should be added when unstale', async () => {
|
||||||
|
expect.assertions(4);
|
||||||
|
const opts = {
|
||||||
|
...DefaultProcessorOptions,
|
||||||
|
removeStaleWhenUpdated: true,
|
||||||
|
labelsToAddWhenUnstale: 'test'
|
||||||
|
};
|
||||||
|
const TestIssueList: Issue[] = [
|
||||||
|
generateIssue(
|
||||||
|
opts,
|
||||||
|
1,
|
||||||
|
'An issue that should have labels added to it when unstale',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
'2020-01-01T17:00:00Z',
|
||||||
|
false,
|
||||||
|
['Stale']
|
||||||
|
)
|
||||||
|
];
|
||||||
|
const processor = new IssuesProcessorMock(
|
||||||
|
opts,
|
||||||
|
async () => 'abot',
|
||||||
|
async p => (p === 1 ? TestIssueList : []),
|
||||||
|
async () => [
|
||||||
|
{
|
||||||
|
user: {
|
||||||
|
login: 'notme',
|
||||||
|
type: 'User'
|
||||||
|
}
|
||||||
|
}
|
||||||
|
], // return a fake comment to indicate there was an update
|
||||||
|
async () => new Date().toDateString()
|
||||||
|
);
|
||||||
|
|
||||||
|
// process our fake issue list
|
||||||
|
await processor.processIssues(1);
|
||||||
|
|
||||||
|
expect(processor.closedIssues).toHaveLength(0);
|
||||||
|
expect(processor.staleIssues).toHaveLength(0);
|
||||||
|
// Stale should have been removed
|
||||||
|
expect(processor.removedLabelIssues).toHaveLength(1);
|
||||||
|
// Some label should have been added
|
||||||
|
expect(processor.addedLabelIssues).toHaveLength(1);
|
||||||
|
});
|
||||||
|
|
||||||
test('stale label should not be removed if a comment was added by the bot (and the issue should be closed)', async () => {
|
test('stale label should not be removed if a comment was added by the bot (and the issue should be closed)', async () => {
|
||||||
const opts = {...DefaultProcessorOptions, removeStaleWhenUpdated: true};
|
const opts = {...DefaultProcessorOptions, removeStaleWhenUpdated: true};
|
||||||
github.context.actor = 'abot';
|
github.context.actor = 'abot';
|
||||||
|
|
|
@ -253,6 +253,7 @@ class IssuesProcessor {
|
||||||
this.closedIssues = [];
|
this.closedIssues = [];
|
||||||
this.deletedBranchIssues = [];
|
this.deletedBranchIssues = [];
|
||||||
this.removedLabelIssues = [];
|
this.removedLabelIssues = [];
|
||||||
|
this.addedLabelIssues = [];
|
||||||
this.options = options;
|
this.options = options;
|
||||||
this.client = github_1.getOctokit(this.options.repoToken);
|
this.client = github_1.getOctokit(this.options.repoToken);
|
||||||
this.operations = new stale_operations_1.StaleOperations(this.options);
|
this.operations = new stale_operations_1.StaleOperations(this.options);
|
||||||
|
@ -299,6 +300,8 @@ class IssuesProcessor {
|
||||||
else {
|
else {
|
||||||
this._logger.info(`${logger_service_1.LoggerService.yellow('Processing the batch of issues')} ${logger_service_1.LoggerService.cyan(`#${page}`)} ${logger_service_1.LoggerService.yellow('containing')} ${logger_service_1.LoggerService.cyan(issues.length)} ${logger_service_1.LoggerService.yellow(`issue${issues.length > 1 ? 's' : ''}...`)}`);
|
this._logger.info(`${logger_service_1.LoggerService.yellow('Processing the batch of issues')} ${logger_service_1.LoggerService.cyan(`#${page}`)} ${logger_service_1.LoggerService.yellow('containing')} ${logger_service_1.LoggerService.cyan(issues.length)} ${logger_service_1.LoggerService.yellow(`issue${issues.length > 1 ? 's' : ''}...`)}`);
|
||||||
}
|
}
|
||||||
|
const labelsToAddWhenUnstale = words_to_list_1.wordsToList(this.options.labelsToAddWhenUnstale);
|
||||||
|
const labelsToRemoveWhenUnstale = words_to_list_1.wordsToList(this.options.labelsToRemoveWhenUnstale);
|
||||||
for (const issue of issues.values()) {
|
for (const issue of issues.values()) {
|
||||||
// Stop the processing if no more operations remains
|
// Stop the processing if no more operations remains
|
||||||
if (!this.operations.hasRemainingOperations()) {
|
if (!this.operations.hasRemainingOperations()) {
|
||||||
|
@ -306,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, actor);
|
yield this.processIssue(issue, actor, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale);
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
if (!this.operations.hasRemainingOperations()) {
|
if (!this.operations.hasRemainingOperations()) {
|
||||||
|
@ -320,7 +323,7 @@ class IssuesProcessor {
|
||||||
return this.processIssues(page + 1);
|
return this.processIssues(page + 1);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
processIssue(issue, actor) {
|
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);
|
||||||
|
@ -469,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, actor, closeMessage, closeLabel);
|
yield this._processStaleIssue(issue, staleLabel, actor, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale, closeMessage, closeLabel);
|
||||||
}
|
}
|
||||||
IssuesProcessor._endIssueProcessing(issue);
|
IssuesProcessor._endIssueProcessing(issue);
|
||||||
});
|
});
|
||||||
|
@ -561,7 +564,7 @@ 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, actor, 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;
|
||||||
|
@ -586,6 +589,9 @@ class IssuesProcessor {
|
||||||
if (shouldRemoveStaleWhenUpdated && issueHasComments) {
|
if (shouldRemoveStaleWhenUpdated && issueHasComments) {
|
||||||
issueLogger.info(`Remove the stale label since the $$type has a comment and the workflow should remove the stale label when updated`);
|
issueLogger.info(`Remove the stale label since the $$type has a comment and the workflow should remove the stale label when updated`);
|
||||||
yield this._removeStaleLabel(issue, staleLabel);
|
yield this._removeStaleLabel(issue, staleLabel);
|
||||||
|
// Are there labels to remove or add when an issue is no longer stale?
|
||||||
|
yield this._removeLabelsWhenUnstale(issue, labelsToRemoveWhenUnstale);
|
||||||
|
yield this._addLabelsWhenUnstale(issue, labelsToAddWhenUnstale);
|
||||||
issueLogger.info(`Skipping the process since the $$type is now un-stale`);
|
issueLogger.info(`Skipping the process since the $$type is now un-stale`);
|
||||||
return; // Nothing to do because it is no longer stale
|
return; // Nothing to do because it is no longer stale
|
||||||
}
|
}
|
||||||
|
@ -854,6 +860,44 @@ class IssuesProcessor {
|
||||||
}
|
}
|
||||||
return this.options.removeStaleWhenUpdated;
|
return this.options.removeStaleWhenUpdated;
|
||||||
}
|
}
|
||||||
|
_removeLabelsWhenUnstale(issue, removeLabels) {
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (!removeLabels.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const issueLogger = new issue_logger_1.IssueLogger(issue);
|
||||||
|
issueLogger.info(`Removing all the labels specified via the ${this._logger.createOptionLink(option_1.Option.LabelsToRemoveWhenUnstale)} option.`);
|
||||||
|
for (const label of removeLabels.values()) {
|
||||||
|
yield this._removeLabel(issue, label);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
|
_addLabelsWhenUnstale(issue, labelsToAdd) {
|
||||||
|
var _a;
|
||||||
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
if (!labelsToAdd.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
const issueLogger = new issue_logger_1.IssueLogger(issue);
|
||||||
|
issueLogger.info(`Adding all the labels specified via the ${this._logger.createOptionLink(option_1.Option.LabelsToAddWhenUnstale)} option.`);
|
||||||
|
this.addedLabelIssues.push(issue);
|
||||||
|
try {
|
||||||
|
this.operations.consumeOperation();
|
||||||
|
(_a = this._statistics) === null || _a === void 0 ? void 0 : _a.incrementAddedItemsLabel(issue);
|
||||||
|
if (!this.options.debugOnly) {
|
||||||
|
yield this.client.issues.addLabels({
|
||||||
|
owner: github_1.context.repo.owner,
|
||||||
|
repo: github_1.context.repo.repo,
|
||||||
|
issue_number: issue.number,
|
||||||
|
labels: labelsToAdd
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (error) {
|
||||||
|
this._logger.error(`Error when adding labels after updated from stale: ${error.message}`);
|
||||||
|
}
|
||||||
|
});
|
||||||
|
}
|
||||||
_removeStaleLabel(issue, staleLabel) {
|
_removeStaleLabel(issue, staleLabel) {
|
||||||
var _a;
|
var _a;
|
||||||
return __awaiter(this, void 0, void 0, function* () {
|
return __awaiter(this, void 0, void 0, function* () {
|
||||||
|
@ -1692,6 +1736,8 @@ var Option;
|
||||||
Option["ExemptAllIssueAssignees"] = "exempt-all-issue-assignees";
|
Option["ExemptAllIssueAssignees"] = "exempt-all-issue-assignees";
|
||||||
Option["ExemptAllPrAssignees"] = "exempt-all-pr-assignees";
|
Option["ExemptAllPrAssignees"] = "exempt-all-pr-assignees";
|
||||||
Option["EnableStatistics"] = "enable-statistics";
|
Option["EnableStatistics"] = "enable-statistics";
|
||||||
|
Option["LabelsToRemoveWhenUnstale"] = "labels-to-remove-when-unstale";
|
||||||
|
Option["LabelsToAddWhenUnstale"] = "labels-to-add-when-unstale";
|
||||||
})(Option = exports.Option || (exports.Option = {}));
|
})(Option = exports.Option || (exports.Option = {}));
|
||||||
|
|
||||||
|
|
||||||
|
@ -1975,7 +2021,9 @@ function _getAndValidateArgs() {
|
||||||
exemptAllAssignees: core.getInput('exempt-all-assignees') === 'true',
|
exemptAllAssignees: core.getInput('exempt-all-assignees') === 'true',
|
||||||
exemptAllIssueAssignees: _toOptionalBoolean('exempt-all-issue-assignees'),
|
exemptAllIssueAssignees: _toOptionalBoolean('exempt-all-issue-assignees'),
|
||||||
exemptAllPrAssignees: _toOptionalBoolean('exempt-all-pr-assignees'),
|
exemptAllPrAssignees: _toOptionalBoolean('exempt-all-pr-assignees'),
|
||||||
enableStatistics: core.getInput('enable-statistics') === 'true'
|
enableStatistics: core.getInput('enable-statistics') === 'true',
|
||||||
|
labelsToRemoveWhenUnstale: core.getInput('labels-to-remove-when-unstale'),
|
||||||
|
labelsToAddWhenUnstale: core.getInput('labels-to-add-when-unstale')
|
||||||
};
|
};
|
||||||
for (const numberInput of [
|
for (const numberInput of [
|
||||||
'days-before-stale',
|
'days-before-stale',
|
||||||
|
|
|
@ -55,7 +55,9 @@ describe('Issue', (): void => {
|
||||||
exemptAllAssignees: false,
|
exemptAllAssignees: false,
|
||||||
exemptAllIssueAssignees: undefined,
|
exemptAllIssueAssignees: undefined,
|
||||||
exemptAllPrAssignees: undefined,
|
exemptAllPrAssignees: undefined,
|
||||||
enableStatistics: false
|
enableStatistics: false,
|
||||||
|
labelsToRemoveWhenUnstale: '',
|
||||||
|
labelsToAddWhenUnstale: ''
|
||||||
};
|
};
|
||||||
issueInterface = {
|
issueInterface = {
|
||||||
title: 'dummy-title',
|
title: 'dummy-title',
|
||||||
|
|
|
@ -75,6 +75,7 @@ export class IssuesProcessor {
|
||||||
readonly closedIssues: Issue[] = [];
|
readonly closedIssues: Issue[] = [];
|
||||||
readonly deletedBranchIssues: Issue[] = [];
|
readonly deletedBranchIssues: Issue[] = [];
|
||||||
readonly removedLabelIssues: Issue[] = [];
|
readonly removedLabelIssues: Issue[] = [];
|
||||||
|
readonly addedLabelIssues: Issue[] = [];
|
||||||
|
|
||||||
constructor(options: IIssuesProcessorOptions) {
|
constructor(options: IIssuesProcessorOptions) {
|
||||||
this.options = options;
|
this.options = options;
|
||||||
|
@ -127,6 +128,13 @@ export class IssuesProcessor {
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
const labelsToAddWhenUnstale: string[] = wordsToList(
|
||||||
|
this.options.labelsToAddWhenUnstale
|
||||||
|
);
|
||||||
|
const labelsToRemoveWhenUnstale: string[] = wordsToList(
|
||||||
|
this.options.labelsToRemoveWhenUnstale
|
||||||
|
);
|
||||||
|
|
||||||
for (const issue of issues.values()) {
|
for (const issue of issues.values()) {
|
||||||
// Stop the processing if no more operations remains
|
// Stop the processing if no more operations remains
|
||||||
if (!this.operations.hasRemainingOperations()) {
|
if (!this.operations.hasRemainingOperations()) {
|
||||||
|
@ -135,7 +143,12 @@ export class IssuesProcessor {
|
||||||
|
|
||||||
const issueLogger: IssueLogger = new IssueLogger(issue);
|
const issueLogger: IssueLogger = new IssueLogger(issue);
|
||||||
await issueLogger.grouping(`$$type #${issue.number}`, async () => {
|
await issueLogger.grouping(`$$type #${issue.number}`, async () => {
|
||||||
await this.processIssue(issue, actor);
|
await this.processIssue(
|
||||||
|
issue,
|
||||||
|
actor,
|
||||||
|
labelsToAddWhenUnstale,
|
||||||
|
labelsToRemoveWhenUnstale
|
||||||
|
);
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -169,7 +182,12 @@ export class IssuesProcessor {
|
||||||
return this.processIssues(page + 1);
|
return this.processIssues(page + 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
async processIssue(issue: Issue, actor: string): Promise<void> {
|
async processIssue(
|
||||||
|
issue: Issue,
|
||||||
|
actor: string,
|
||||||
|
labelsToAddWhenUnstale: Readonly<string>[],
|
||||||
|
labelsToRemoveWhenUnstale: Readonly<string>[]
|
||||||
|
): Promise<void> {
|
||||||
this._statistics?.incrementProcessedItemsCount(issue);
|
this._statistics?.incrementProcessedItemsCount(issue);
|
||||||
|
|
||||||
const issueLogger: IssueLogger = new IssueLogger(issue);
|
const issueLogger: IssueLogger = new IssueLogger(issue);
|
||||||
|
@ -438,6 +456,8 @@ export class IssuesProcessor {
|
||||||
issue,
|
issue,
|
||||||
staleLabel,
|
staleLabel,
|
||||||
actor,
|
actor,
|
||||||
|
labelsToAddWhenUnstale,
|
||||||
|
labelsToRemoveWhenUnstale,
|
||||||
closeMessage,
|
closeMessage,
|
||||||
closeLabel
|
closeLabel
|
||||||
);
|
);
|
||||||
|
@ -549,6 +569,8 @@ export class IssuesProcessor {
|
||||||
issue: Issue,
|
issue: Issue,
|
||||||
staleLabel: string,
|
staleLabel: string,
|
||||||
actor: string,
|
actor: string,
|
||||||
|
labelsToAddWhenUnstale: Readonly<string>[],
|
||||||
|
labelsToRemoveWhenUnstale: Readonly<string>[],
|
||||||
closeMessage?: string,
|
closeMessage?: string,
|
||||||
closeLabel?: string
|
closeLabel?: string
|
||||||
) {
|
) {
|
||||||
|
@ -608,6 +630,10 @@ export class IssuesProcessor {
|
||||||
);
|
);
|
||||||
await this._removeStaleLabel(issue, staleLabel);
|
await this._removeStaleLabel(issue, staleLabel);
|
||||||
|
|
||||||
|
// Are there labels to remove or add when an issue is no longer stale?
|
||||||
|
await this._removeLabelsWhenUnstale(issue, labelsToRemoveWhenUnstale);
|
||||||
|
await this._addLabelsWhenUnstale(issue, labelsToAddWhenUnstale);
|
||||||
|
|
||||||
issueLogger.info(`Skipping the process since the $$type is now un-stale`);
|
issueLogger.info(`Skipping the process since the $$type is now un-stale`);
|
||||||
|
|
||||||
return; // Nothing to do because it is no longer stale
|
return; // Nothing to do because it is no longer stale
|
||||||
|
@ -956,6 +982,63 @@ export class IssuesProcessor {
|
||||||
return this.options.removeStaleWhenUpdated;
|
return this.options.removeStaleWhenUpdated;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private async _removeLabelsWhenUnstale(
|
||||||
|
issue: Issue,
|
||||||
|
removeLabels: Readonly<string>[]
|
||||||
|
): Promise<void> {
|
||||||
|
if (!removeLabels.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const issueLogger: IssueLogger = new IssueLogger(issue);
|
||||||
|
|
||||||
|
issueLogger.info(
|
||||||
|
`Removing all the labels specified via the ${this._logger.createOptionLink(
|
||||||
|
Option.LabelsToRemoveWhenUnstale
|
||||||
|
)} option.`
|
||||||
|
);
|
||||||
|
|
||||||
|
for (const label of removeLabels.values()) {
|
||||||
|
await this._removeLabel(issue, label);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private async _addLabelsWhenUnstale(
|
||||||
|
issue: Issue,
|
||||||
|
labelsToAdd: Readonly<string>[]
|
||||||
|
): Promise<void> {
|
||||||
|
if (!labelsToAdd.length) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
const issueLogger: IssueLogger = new IssueLogger(issue);
|
||||||
|
|
||||||
|
issueLogger.info(
|
||||||
|
`Adding all the labels specified via the ${this._logger.createOptionLink(
|
||||||
|
Option.LabelsToAddWhenUnstale
|
||||||
|
)} option.`
|
||||||
|
);
|
||||||
|
|
||||||
|
this.addedLabelIssues.push(issue);
|
||||||
|
|
||||||
|
try {
|
||||||
|
this.operations.consumeOperation();
|
||||||
|
this._statistics?.incrementAddedItemsLabel(issue);
|
||||||
|
if (!this.options.debugOnly) {
|
||||||
|
await this.client.issues.addLabels({
|
||||||
|
owner: context.repo.owner,
|
||||||
|
repo: context.repo.repo,
|
||||||
|
issue_number: issue.number,
|
||||||
|
labels: labelsToAdd
|
||||||
|
});
|
||||||
|
}
|
||||||
|
} catch (error) {
|
||||||
|
this._logger.error(
|
||||||
|
`Error when adding labels after updated from stale: ${error.message}`
|
||||||
|
);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private async _removeStaleLabel(
|
private async _removeStaleLabel(
|
||||||
issue: Issue,
|
issue: Issue,
|
||||||
staleLabel: Readonly<string>
|
staleLabel: Readonly<string>
|
||||||
|
|
|
@ -40,5 +40,7 @@ export enum Option {
|
||||||
ExemptAllAssignees = 'exempt-all-assignees',
|
ExemptAllAssignees = 'exempt-all-assignees',
|
||||||
ExemptAllIssueAssignees = 'exempt-all-issue-assignees',
|
ExemptAllIssueAssignees = 'exempt-all-issue-assignees',
|
||||||
ExemptAllPrAssignees = 'exempt-all-pr-assignees',
|
ExemptAllPrAssignees = 'exempt-all-pr-assignees',
|
||||||
EnableStatistics = 'enable-statistics'
|
EnableStatistics = 'enable-statistics',
|
||||||
|
LabelsToRemoveWhenUnstale = 'labels-to-remove-when-unstale',
|
||||||
|
LabelsToAddWhenUnstale = 'labels-to-add-when-unstale'
|
||||||
}
|
}
|
||||||
|
|
|
@ -45,4 +45,6 @@ export interface IIssuesProcessorOptions {
|
||||||
exemptAllIssueAssignees: boolean | undefined;
|
exemptAllIssueAssignees: boolean | undefined;
|
||||||
exemptAllPrAssignees: boolean | undefined;
|
exemptAllPrAssignees: boolean | undefined;
|
||||||
enableStatistics: boolean;
|
enableStatistics: boolean;
|
||||||
|
labelsToRemoveWhenUnstale: string;
|
||||||
|
labelsToAddWhenUnstale: string;
|
||||||
}
|
}
|
||||||
|
|
|
@ -81,7 +81,9 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
|
||||||
exemptAllAssignees: core.getInput('exempt-all-assignees') === 'true',
|
exemptAllAssignees: core.getInput('exempt-all-assignees') === 'true',
|
||||||
exemptAllIssueAssignees: _toOptionalBoolean('exempt-all-issue-assignees'),
|
exemptAllIssueAssignees: _toOptionalBoolean('exempt-all-issue-assignees'),
|
||||||
exemptAllPrAssignees: _toOptionalBoolean('exempt-all-pr-assignees'),
|
exemptAllPrAssignees: _toOptionalBoolean('exempt-all-pr-assignees'),
|
||||||
enableStatistics: core.getInput('enable-statistics') === 'true'
|
enableStatistics: core.getInput('enable-statistics') === 'true',
|
||||||
|
labelsToRemoveWhenUnstale: core.getInput('labels-to-remove-when-unstale'),
|
||||||
|
labelsToAddWhenUnstale: core.getInput('labels-to-add-when-unstale')
|
||||||
};
|
};
|
||||||
|
|
||||||
for (const numberInput of [
|
for (const numberInput of [
|
||||||
|
|
Loading…
Reference in New Issue