mirror of
https://github.com/actions/stale.git
synced 2025-12-11 04:32:53 +00:00
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:
@@ -55,7 +55,9 @@ describe('Issue', (): void => {
|
||||
exemptAllAssignees: false,
|
||||
exemptAllIssueAssignees: undefined,
|
||||
exemptAllPrAssignees: undefined,
|
||||
enableStatistics: false
|
||||
enableStatistics: false,
|
||||
labelsToRemoveWhenUnstale: '',
|
||||
labelsToAddWhenUnstale: ''
|
||||
};
|
||||
issueInterface = {
|
||||
title: 'dummy-title',
|
||||
|
||||
@@ -75,6 +75,7 @@ export class IssuesProcessor {
|
||||
readonly closedIssues: Issue[] = [];
|
||||
readonly deletedBranchIssues: Issue[] = [];
|
||||
readonly removedLabelIssues: Issue[] = [];
|
||||
readonly addedLabelIssues: Issue[] = [];
|
||||
|
||||
constructor(options: IIssuesProcessorOptions) {
|
||||
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()) {
|
||||
// Stop the processing if no more operations remains
|
||||
if (!this.operations.hasRemainingOperations()) {
|
||||
@@ -135,7 +143,12 @@ export class IssuesProcessor {
|
||||
|
||||
const issueLogger: IssueLogger = new IssueLogger(issue);
|
||||
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);
|
||||
}
|
||||
|
||||
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);
|
||||
|
||||
const issueLogger: IssueLogger = new IssueLogger(issue);
|
||||
@@ -438,6 +456,8 @@ export class IssuesProcessor {
|
||||
issue,
|
||||
staleLabel,
|
||||
actor,
|
||||
labelsToAddWhenUnstale,
|
||||
labelsToRemoveWhenUnstale,
|
||||
closeMessage,
|
||||
closeLabel
|
||||
);
|
||||
@@ -549,6 +569,8 @@ export class IssuesProcessor {
|
||||
issue: Issue,
|
||||
staleLabel: string,
|
||||
actor: string,
|
||||
labelsToAddWhenUnstale: Readonly<string>[],
|
||||
labelsToRemoveWhenUnstale: Readonly<string>[],
|
||||
closeMessage?: string,
|
||||
closeLabel?: string
|
||||
) {
|
||||
@@ -608,6 +630,10 @@ export class IssuesProcessor {
|
||||
);
|
||||
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`);
|
||||
|
||||
return; // Nothing to do because it is no longer stale
|
||||
@@ -956,6 +982,63 @@ export class IssuesProcessor {
|
||||
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(
|
||||
issue: Issue,
|
||||
staleLabel: Readonly<string>
|
||||
|
||||
@@ -40,5 +40,7 @@ export enum Option {
|
||||
ExemptAllAssignees = 'exempt-all-assignees',
|
||||
ExemptAllIssueAssignees = 'exempt-all-issue-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;
|
||||
exemptAllPrAssignees: boolean | undefined;
|
||||
enableStatistics: boolean;
|
||||
labelsToRemoveWhenUnstale: string;
|
||||
labelsToAddWhenUnstale: string;
|
||||
}
|
||||
|
||||
@@ -81,7 +81,9 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
|
||||
exemptAllAssignees: core.getInput('exempt-all-assignees') === 'true',
|
||||
exemptAllIssueAssignees: _toOptionalBoolean('exempt-all-issue-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 [
|
||||
|
||||
Reference in New Issue
Block a user