Add skipPinned
This commit is contained in:
parent
465330b7e2
commit
f6f48c4485
|
@ -164,6 +164,10 @@ inputs:
|
|||
description: 'Exempt all issues with assignees from being marked as stale. Override "exempt-all-assignees" option regarding only the issues.'
|
||||
default: ''
|
||||
required: false
|
||||
exempt-pinned-issues:
|
||||
description: 'Exempt pinned issues from being marked as stale. Default to false.'
|
||||
default: 'false'
|
||||
required: false
|
||||
exempt-all-pr-assignees:
|
||||
description: 'Exempt all pull requests with assignees from being marked as stale. Override "exempt-all-assignees" option regarding only the pull requests.'
|
||||
default: ''
|
||||
|
|
|
@ -408,6 +408,8 @@ class IssuesProcessor {
|
|||
this.addedLabelIssues = [];
|
||||
this.addedCloseCommentIssues = [];
|
||||
this._logger = new logger_1.Logger();
|
||||
this._lastIssueEvents = [];
|
||||
this._lastIssueEventsIssueId = -1;
|
||||
this.options = options;
|
||||
this.state = state;
|
||||
this.client = (0, github_1.getOctokit)(this.options.repoToken, undefined, plugin_retry_1.retry);
|
||||
|
@ -464,6 +466,34 @@ class IssuesProcessor {
|
|||
return this.processIssues(page + 1);
|
||||
});
|
||||
}
|
||||
getIssueEvents(issue) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
if (issue.number !== this._lastIssueEventsIssueId) {
|
||||
const options = this.client.rest.issues.listEvents.endpoint.merge({
|
||||
owner: github_1.context.repo.owner,
|
||||
repo: github_1.context.repo.repo,
|
||||
per_page: 100,
|
||||
issue_number: issue.number
|
||||
});
|
||||
const events = yield this.client.paginate(options);
|
||||
this._lastIssueEvents = events.reverse();
|
||||
this._lastIssueEventsIssueId = issue.number;
|
||||
}
|
||||
return this._lastIssueEvents;
|
||||
});
|
||||
}
|
||||
getPinnedStatus(issue) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
const events = yield this.getIssueEvents(issue);
|
||||
const pinnedEvent = events.findIndex(event => event.event === 'pinned');
|
||||
if (pinnedEvent == -1)
|
||||
return false;
|
||||
const unpinnedEvent = events.findIndex(event => event.event === 'unpinned');
|
||||
if (unpinnedEvent == -1)
|
||||
return true;
|
||||
return pinnedEvent < unpinnedEvent;
|
||||
});
|
||||
}
|
||||
processIssue(issue, labelsToAddWhenUnstale, labelsToRemoveWhenUnstale, labelsToRemoveWhenStale) {
|
||||
var _a;
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
|
@ -504,6 +534,11 @@ class IssuesProcessor {
|
|||
IssuesProcessor._endIssueProcessing(issue);
|
||||
return; // If the issue has an 'include-only-assigned' option set, process only issues with nonempty assignees list
|
||||
}
|
||||
if (yield this._isSkipPinned(issue)) {
|
||||
issueLogger.info('Skipping this issue because it is pinned');
|
||||
IssuesProcessor._endIssueProcessing(issue);
|
||||
return; // Don't process pinned issues
|
||||
}
|
||||
const onlyLabels = (0, words_to_list_1.wordsToList)(this._getOnlyLabels(issue));
|
||||
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)})`);
|
||||
|
@ -702,15 +737,8 @@ class IssuesProcessor {
|
|||
issueLogger.info(`Checking for label on this $$type`);
|
||||
this._consumeIssueOperation(issue);
|
||||
(_a = this.statistics) === null || _a === void 0 ? void 0 : _a.incrementFetchedItemsEventsCount();
|
||||
const options = this.client.rest.issues.listEvents.endpoint.merge({
|
||||
owner: github_1.context.repo.owner,
|
||||
repo: github_1.context.repo.repo,
|
||||
per_page: 100,
|
||||
issue_number: issue.number
|
||||
});
|
||||
const events = yield this.client.paginate(options);
|
||||
const reversedEvents = events.reverse();
|
||||
const staleLabeledEvent = reversedEvents.find(event => event.event === 'labeled' &&
|
||||
const events = yield this.getIssueEvents(issue);
|
||||
const staleLabeledEvent = events.find(event => event.event === 'labeled' &&
|
||||
(0, clean_label_1.cleanLabel)(event.label.name) === (0, clean_label_1.cleanLabel)(label));
|
||||
if (!staleLabeledEvent) {
|
||||
// Must be old rather than labeled
|
||||
|
@ -1025,6 +1053,11 @@ class IssuesProcessor {
|
|||
_isIncludeOnlyAssigned(issue) {
|
||||
return this.options.includeOnlyAssigned && !issue.hasAssignees;
|
||||
}
|
||||
_isSkipPinned(issue) {
|
||||
return __awaiter(this, void 0, void 0, function* () {
|
||||
return (this.options.exemptPinnedIssues && (yield this.getPinnedStatus(issue)));
|
||||
});
|
||||
}
|
||||
_getAnyOfLabels(issue) {
|
||||
if (issue.isPullRequest) {
|
||||
if (this.options.anyOfPrLabels !== '') {
|
||||
|
@ -2461,6 +2494,7 @@ function _getAndValidateArgs() {
|
|||
staleIssueLabel: core.getInput('stale-issue-label', { required: true }),
|
||||
closeIssueLabel: core.getInput('close-issue-label'),
|
||||
exemptIssueLabels: core.getInput('exempt-issue-labels'),
|
||||
exemptPinnedIssues: core.getInput('exempt-pinned-issues') === 'true',
|
||||
stalePrLabel: core.getInput('stale-pr-label', { required: true }),
|
||||
closePrLabel: core.getInput('close-pr-label'),
|
||||
exemptPrLabels: core.getInput('exempt-pr-labels'),
|
||||
|
|
|
@ -193,6 +193,35 @@ export class IssuesProcessor {
|
|||
return this.processIssues(page + 1);
|
||||
}
|
||||
|
||||
private _lastIssueEvents: IIssueEvent[] = [];
|
||||
private _lastIssueEventsIssueId = -1;
|
||||
async getIssueEvents(issue: Issue): Promise<IIssueEvent[]> {
|
||||
if (issue.number !== this._lastIssueEventsIssueId) {
|
||||
const options = this.client.rest.issues.listEvents.endpoint.merge({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
per_page: 100,
|
||||
issue_number: issue.number
|
||||
});
|
||||
const events: IIssueEvent[] = await this.client.paginate(options);
|
||||
this._lastIssueEvents = events.reverse();
|
||||
this._lastIssueEventsIssueId = issue.number;
|
||||
}
|
||||
return this._lastIssueEvents;
|
||||
}
|
||||
|
||||
async getPinnedStatus(issue: Issue): Promise<boolean> {
|
||||
const events = await this.getIssueEvents(issue);
|
||||
const pinnedEvent = events.findIndex(event => event.event === 'pinned');
|
||||
|
||||
if (pinnedEvent == -1) return false;
|
||||
|
||||
const unpinnedEvent = events.findIndex(event => event.event === 'unpinned');
|
||||
if (unpinnedEvent == -1) return true;
|
||||
|
||||
return pinnedEvent < unpinnedEvent;
|
||||
}
|
||||
|
||||
async processIssue(
|
||||
issue: Issue,
|
||||
labelsToAddWhenUnstale: Readonly<string>[],
|
||||
|
@ -248,6 +277,12 @@ export class IssuesProcessor {
|
|||
return; // If the issue has an 'include-only-assigned' option set, process only issues with nonempty assignees list
|
||||
}
|
||||
|
||||
if (await this._isSkipPinned(issue)) {
|
||||
issueLogger.info('Skipping this issue because it is pinned');
|
||||
IssuesProcessor._endIssueProcessing(issue);
|
||||
return; // Don't process pinned issues
|
||||
}
|
||||
|
||||
const onlyLabels: string[] = wordsToList(this._getOnlyLabels(issue));
|
||||
|
||||
if (onlyLabels.length > 0) {
|
||||
|
@ -593,17 +628,9 @@ export class IssuesProcessor {
|
|||
|
||||
this._consumeIssueOperation(issue);
|
||||
this.statistics?.incrementFetchedItemsEventsCount();
|
||||
const options = this.client.rest.issues.listEvents.endpoint.merge({
|
||||
owner: context.repo.owner,
|
||||
repo: context.repo.repo,
|
||||
per_page: 100,
|
||||
issue_number: issue.number
|
||||
});
|
||||
|
||||
const events: IIssueEvent[] = await this.client.paginate(options);
|
||||
const reversedEvents = events.reverse();
|
||||
|
||||
const staleLabeledEvent = reversedEvents.find(
|
||||
const events = await this.getIssueEvents(issue);
|
||||
const staleLabeledEvent = events.find(
|
||||
event =>
|
||||
event.event === 'labeled' &&
|
||||
cleanLabel(event.label.name) === cleanLabel(label)
|
||||
|
@ -1074,6 +1101,12 @@ export class IssuesProcessor {
|
|||
return this.options.includeOnlyAssigned && !issue.hasAssignees;
|
||||
}
|
||||
|
||||
private async _isSkipPinned(issue: Issue): Promise<boolean> {
|
||||
return (
|
||||
this.options.exemptPinnedIssues && (await this.getPinnedStatus(issue))
|
||||
);
|
||||
}
|
||||
|
||||
private _getAnyOfLabels(issue: Issue): string {
|
||||
if (issue.isPullRequest) {
|
||||
if (this.options.anyOfPrLabels !== '') {
|
||||
|
|
|
@ -15,6 +15,7 @@ export interface IIssuesProcessorOptions {
|
|||
staleIssueLabel: string;
|
||||
closeIssueLabel: string;
|
||||
exemptIssueLabels: string;
|
||||
exemptPinnedIssues: boolean;
|
||||
stalePrLabel: string;
|
||||
closePrLabel: string;
|
||||
exemptPrLabels: string;
|
||||
|
|
|
@ -47,6 +47,7 @@ function _getAndValidateArgs(): IIssuesProcessorOptions {
|
|||
staleIssueLabel: core.getInput('stale-issue-label', {required: true}),
|
||||
closeIssueLabel: core.getInput('close-issue-label'),
|
||||
exemptIssueLabels: core.getInput('exempt-issue-labels'),
|
||||
exemptPinnedIssues: core.getInput('exempt-pinned-issues') === 'true',
|
||||
stalePrLabel: core.getInput('stale-pr-label', {required: true}),
|
||||
closePrLabel: core.getInput('close-pr-label'),
|
||||
exemptPrLabels: core.getInput('exempt-pr-labels'),
|
||||
|
|
Loading…
Reference in New Issue