mirror of
https://gitea.com/actions/stale.git
synced 2026-09-01 10:14:23 +00:00
eaf9131fae
- Changed import statements across multiple files to use the .js extension for ES module compatibility. - Refactored test files to utilize jest's unstable_mockModule for mocking core actions. - Removed unnecessary spy instances in tests, replacing them with direct mocked function calls. - Updated TypeScript configuration to target ES2022 and use NodeNext module resolution. - Removed the tsconfig.spec.json file and adjusted the main tsconfig.json to exclude test files.
291 lines
8.8 KiB
TypeScript
291 lines
8.8 KiB
TypeScript
import deburr from 'lodash.deburr';
|
|
import {Option} from '../enums/option.js';
|
|
import {wordsToList} from '../functions/words-to-list.js';
|
|
import {Assignee} from '../interfaces/assignee.js';
|
|
import {IIssuesProcessorOptions} from '../interfaces/issues-processor-options.js';
|
|
import {Issue} from './issue.js';
|
|
import {IssueLogger} from './loggers/issue-logger.js';
|
|
import {LoggerService} from '../services/logger.service.js';
|
|
|
|
type CleanAssignee = string;
|
|
|
|
export class Assignees {
|
|
private readonly _options: IIssuesProcessorOptions;
|
|
private readonly _issue: Issue;
|
|
private readonly _issueLogger: IssueLogger;
|
|
|
|
constructor(options: Readonly<IIssuesProcessorOptions>, issue: Issue) {
|
|
this._options = options;
|
|
this._issue = issue;
|
|
this._issueLogger = new IssueLogger(issue);
|
|
}
|
|
|
|
private static _cleanAssignee(assignee: Readonly<string>): CleanAssignee {
|
|
return deburr(assignee.toLowerCase());
|
|
}
|
|
|
|
shouldExemptAssignees(): boolean {
|
|
if (!this._issue.hasAssignees) {
|
|
this._issueLogger.info('This $$type has no assignee');
|
|
this._logSkip();
|
|
|
|
return false;
|
|
}
|
|
|
|
if (this._shouldExemptAllAssignees()) {
|
|
this._issueLogger.info(
|
|
LoggerService.white('└──'),
|
|
'Skipping this $$type because it has an exempt assignee'
|
|
);
|
|
|
|
return true;
|
|
}
|
|
|
|
const exemptAssignees: string[] = this._getExemptAssignees();
|
|
|
|
if (exemptAssignees.length === 0) {
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`No assignee option was specified to skip the stale process for this $$type`
|
|
);
|
|
this._logSkip();
|
|
|
|
return false;
|
|
}
|
|
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`Found ${LoggerService.cyan(exemptAssignees.length)} assignee${
|
|
exemptAssignees.length > 1 ? 's' : ''
|
|
} that can exempt stale on this $$type`
|
|
);
|
|
|
|
const hasExemptAssignee: boolean = exemptAssignees.some(
|
|
(exemptAssignee: Readonly<string>): boolean =>
|
|
this._hasAssignee(exemptAssignee)
|
|
);
|
|
|
|
if (!hasExemptAssignee) {
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
'No assignee on this $$type can exempt the stale process'
|
|
);
|
|
this._logSkip();
|
|
} else {
|
|
this._issueLogger.info(
|
|
LoggerService.white('└──'),
|
|
'Skipping this $$type because it has an exempt assignee'
|
|
);
|
|
}
|
|
|
|
return hasExemptAssignee;
|
|
}
|
|
|
|
private _getExemptAssignees(): string[] {
|
|
return this._issue.isPullRequest
|
|
? this._getExemptPullRequestAssignees()
|
|
: this._getExemptIssueAssignees();
|
|
}
|
|
|
|
private _getExemptIssueAssignees(): string[] {
|
|
if (this._options.exemptIssueAssignees === '') {
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptIssueAssignees
|
|
)} is disabled. No specific assignee can skip the stale process for this $$type`
|
|
);
|
|
|
|
if (this._options.exemptAssignees === '') {
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptAssignees
|
|
)} is disabled. No specific assignee can skip the stale process for this $$type`
|
|
);
|
|
|
|
return [];
|
|
}
|
|
|
|
const exemptAssignees: string[] = wordsToList(
|
|
this._options.exemptAssignees
|
|
);
|
|
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptAssignees
|
|
)} is set. ${LoggerService.cyan(exemptAssignees.length)} assignee${
|
|
exemptAssignees.length === 1 ? '' : 's'
|
|
} can skip the stale process for this $$type`
|
|
);
|
|
|
|
return exemptAssignees;
|
|
}
|
|
|
|
const exemptAssignees: string[] = wordsToList(
|
|
this._options.exemptIssueAssignees
|
|
);
|
|
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptIssueAssignees
|
|
)} is set. ${LoggerService.cyan(exemptAssignees.length)} assignee${
|
|
exemptAssignees.length === 1 ? '' : 's'
|
|
} can skip the stale process for this $$type`
|
|
);
|
|
|
|
return exemptAssignees;
|
|
}
|
|
|
|
private _getExemptPullRequestAssignees(): string[] {
|
|
if (this._options.exemptPrAssignees === '') {
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptPrAssignees
|
|
)} is disabled. No specific assignee can skip the stale process for this $$type`
|
|
);
|
|
|
|
if (this._options.exemptAssignees === '') {
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptAssignees
|
|
)} is disabled. No specific assignee can skip the stale process for this $$type`
|
|
);
|
|
|
|
return [];
|
|
}
|
|
|
|
const exemptAssignees: string[] = wordsToList(
|
|
this._options.exemptAssignees
|
|
);
|
|
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptAssignees
|
|
)} is set. ${LoggerService.cyan(exemptAssignees.length)} assignee${
|
|
exemptAssignees.length === 1 ? '' : 's'
|
|
} can skip the stale process for this $$type`
|
|
);
|
|
|
|
return exemptAssignees;
|
|
}
|
|
|
|
const exemptAssignees: string[] = wordsToList(
|
|
this._options.exemptPrAssignees
|
|
);
|
|
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptPrAssignees
|
|
)} is set. ${LoggerService.cyan(exemptAssignees.length)} assignee${
|
|
exemptAssignees.length === 1 ? '' : 's'
|
|
} can skip the stale process for this $$type`
|
|
);
|
|
|
|
return exemptAssignees;
|
|
}
|
|
|
|
private _hasAssignee(assignee: Readonly<string>): boolean {
|
|
const cleanAssignee: CleanAssignee = Assignees._cleanAssignee(assignee);
|
|
|
|
return this._issue.assignees.some(
|
|
(issueAssignee: Readonly<Assignee>): boolean => {
|
|
const isSameAssignee: boolean =
|
|
cleanAssignee === Assignees._cleanAssignee(issueAssignee.login);
|
|
|
|
if (isSameAssignee) {
|
|
this._issueLogger.info(
|
|
LoggerService.white('├──'),
|
|
`@${issueAssignee.login} is assigned on this $$type and is an exempt assignee`
|
|
);
|
|
}
|
|
|
|
return isSameAssignee;
|
|
}
|
|
);
|
|
}
|
|
|
|
private _shouldExemptAllAssignees(): boolean {
|
|
return this._issue.isPullRequest
|
|
? this._shouldExemptAllPullRequestAssignees()
|
|
: this._shouldExemptAllIssueAssignees();
|
|
}
|
|
|
|
private _shouldExemptAllIssueAssignees(): boolean {
|
|
if (this._options.exemptAllIssueAssignees === true) {
|
|
this._issueLogger.info(
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptAllIssueAssignees
|
|
)} is enabled. Any assignee on this $$type will skip the stale process`
|
|
);
|
|
|
|
return true;
|
|
} else if (this._options.exemptAllIssueAssignees === false) {
|
|
this._issueLogger.info(
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptAllIssueAssignees
|
|
)} is disabled. Only some specific assignees on this $$type will skip the stale process`
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
this._logExemptAllAssigneesOption();
|
|
|
|
return this._options.exemptAllAssignees;
|
|
}
|
|
|
|
private _shouldExemptAllPullRequestAssignees(): boolean {
|
|
if (this._options.exemptAllPrAssignees === true) {
|
|
this._issueLogger.info(
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptAllPrAssignees
|
|
)} is enabled. Any assignee on this $$type will skip the stale process`
|
|
);
|
|
|
|
return true;
|
|
} else if (this._options.exemptAllPrAssignees === false) {
|
|
this._issueLogger.info(
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptAllPrAssignees
|
|
)} is disabled. Only some specific assignees on this $$type will skip the stale process`
|
|
);
|
|
|
|
return false;
|
|
}
|
|
|
|
this._logExemptAllAssigneesOption();
|
|
|
|
return this._options.exemptAllAssignees;
|
|
}
|
|
|
|
private _logExemptAllAssigneesOption(): void {
|
|
if (this._options.exemptAllAssignees) {
|
|
this._issueLogger.info(
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptAllAssignees
|
|
)} is enabled. Any assignee on this $$type will skip the stale process`
|
|
);
|
|
} else {
|
|
this._issueLogger.info(
|
|
`The option ${this._issueLogger.createOptionLink(
|
|
Option.ExemptAllAssignees
|
|
)} is disabled. Only some specific assignees on this $$type will skip the stale process`
|
|
);
|
|
}
|
|
}
|
|
|
|
private _logSkip(): void {
|
|
this._issueLogger.info(
|
|
LoggerService.white('└──'),
|
|
'Skip the assignees checks'
|
|
);
|
|
}
|
|
}
|