diff --git a/README.md b/README.md index 06c2a4723..9bd091bd7 100644 --- a/README.md +++ b/README.md @@ -45,6 +45,8 @@ Every argument is optional. | Input | Description | Default | | ------------------------------------------------------------------- | --------------------------------------------------------------------------- | --------------------- | | [repo-token](#repo-token) | PAT for GitHub API authentication | `${{ github.token }}` | +| [repo-owner](#repo-owner) | Owner of the repository | `${{ github.repository_owner }}` | +| [repo-name](#repo-name) | Name of the repository | `${{ github.event.repository.name }}` | | [days-before-stale](#days-before-stale) | Idle number of days before marking issues/PRs stale | `60` | | [days-before-issue-stale](#days-before-issue-stale) | Override [days-before-stale](#days-before-stale) for issues only | | | [days-before-pr-stale](#days-before-pr-stale) | Override [days-before-stale](#days-before-stale) for PRs only | | @@ -109,11 +111,23 @@ Every argument is optional. #### repo-token -Personal Access Token (PAT) that allows the stale workflow to authenticate and perform API calls to GitHub. +Personal Access Token (PAT) that allows the stale workflow to authenticate and perform API calls to GitHub in the specified repository. Under the hood, it uses the [@actions/github](https://www.npmjs.com/package/@actions/github) package. Default value: `${{ github.token }}` +#### repo-owner + +The owner / organization of the repository that you wish to run the stale workflow on. + +Default value: `${{ github.repository_owner }}` + +#### repo-name + +The name of the repository that you wish to run the stale workflow on. + +Default value: `${{ github.event.repository.name }}` + #### days-before-stale The idle number of days before marking the issues or the pull requests as stale (by adding a label). diff --git a/__tests__/constants/default-processor-options.ts b/__tests__/constants/default-processor-options.ts index 0265b6446..3b7cedb72 100644 --- a/__tests__/constants/default-processor-options.ts +++ b/__tests__/constants/default-processor-options.ts @@ -4,6 +4,8 @@ import {IIssuesProcessorOptions} from '../../src/interfaces/issues-processor-opt // Mirrors the defaults defined in action.yml export const DefaultProcessorOptions: IIssuesProcessorOptions = Object.freeze({ repoToken: 'none', + repoOwner: '', + repoName: '', staleIssueMessage: 'This issue is stale', stalePrMessage: 'This PR is stale', closeIssueMessage: 'This issue is being closed', diff --git a/action.yml b/action.yml index 251c93925..4e4d013e5 100644 --- a/action.yml +++ b/action.yml @@ -6,6 +6,12 @@ inputs: description: 'Token for the repository. Can be passed in using `{{ secrets.GITHUB_TOKEN }}`.' required: false default: ${{ github.token }} + repo-owner: + description: 'Name of the organization / owner of the repository that you want to manage' + required: false + repo-name: + description: 'Name of the repository that you want to apply stale bot' + required: false stale-issue-message: description: 'The message to post on the issue when tagging it. If none provided, will not mark issues stale.' required: false diff --git a/dist/index.js b/dist/index.js index cfcb005d8..32b022a60 100644 --- a/dist/index.js +++ b/dist/index.js @@ -659,8 +659,8 @@ class IssuesProcessor { this._consumeIssueOperation(issue); (_a = this.statistics) === null || _a === void 0 ? void 0 : _a.incrementFetchedItemsCommentsCount(); const comments = yield this.client.rest.issues.listComments({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, since: sinceDate }); @@ -676,11 +676,12 @@ class IssuesProcessor { getIssues(page) { var _a; return __awaiter(this, void 0, void 0, function* () { + this._logger.info(logger_service_1.LoggerService.green(`Processing: ${this.options.repoOwner}/${this.options.repoName}`)); try { this.operations.consumeOperation(); const issueResult = yield this.client.rest.issues.listForRepo({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, state: 'open', per_page: 100, direction: this.options.ascending ? 'asc' : 'desc', @@ -704,8 +705,8 @@ class IssuesProcessor { 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, + owner: this.options.repoOwner, + repo: this.options.repoName, per_page: 100, issue_number: issue.number }); @@ -728,8 +729,8 @@ class IssuesProcessor { this._consumeIssueOperation(issue); (_a = this.statistics) === null || _a === void 0 ? void 0 : _a.incrementFetchedPullRequestsCount(); const pullRequest = yield this.client.rest.pulls.get({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, pull_number: issue.number }); return pullRequest.data; @@ -848,8 +849,8 @@ class IssuesProcessor { (_a = this.statistics) === null || _a === void 0 ? void 0 : _a.incrementAddedItemsComment(issue); if (!this.options.debugOnly) { yield this.client.rest.issues.createComment({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, body: staleMessage }); @@ -865,8 +866,8 @@ class IssuesProcessor { (_c = this.statistics) === null || _c === void 0 ? void 0 : _c.incrementStaleItemsCount(issue); if (!this.options.debugOnly) { yield this.client.rest.issues.addLabels({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, labels: [staleLabel] }); @@ -891,8 +892,8 @@ class IssuesProcessor { this.addedCloseCommentIssues.push(issue); if (!this.options.debugOnly) { yield this.client.rest.issues.createComment({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, body: closeMessage }); @@ -908,8 +909,8 @@ class IssuesProcessor { (_b = this.statistics) === null || _b === void 0 ? void 0 : _b.incrementAddedItemsLabel(issue); if (!this.options.debugOnly) { yield this.client.rest.issues.addLabels({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, labels: [closeLabel] }); @@ -924,8 +925,8 @@ class IssuesProcessor { (_c = this.statistics) === null || _c === void 0 ? void 0 : _c.incrementClosedItemsCount(issue); if (!this.options.debugOnly) { yield this.client.rest.issues.update({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, state: 'closed', state_reason: this.options.closeIssueReason || undefined @@ -955,15 +956,15 @@ class IssuesProcessor { const branch = pullRequest.head.ref; if (pullRequest.head.repo === null || pullRequest.head.repo.full_name === - `${github_1.context.repo.owner}/${github_1.context.repo.repo}`) { + `${this.options.repoOwner}/${this.options.repoName}`) { issueLogger.info(`Deleting the branch "${logger_service_1.LoggerService.cyan(branch)}" from closed $$type`); try { this._consumeIssueOperation(issue); (_a = this.statistics) === null || _a === void 0 ? void 0 : _a.incrementDeletedBranchesCount(); if (!this.options.debugOnly) { yield this.client.rest.git.deleteRef({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, ref: `heads/${branch}` }); } @@ -989,8 +990,8 @@ class IssuesProcessor { (_a = this.statistics) === null || _a === void 0 ? void 0 : _a.incrementDeletedItemsLabelsCount(issue); if (!this.options.debugOnly) { yield this.client.rest.issues.removeLabel({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, name: label }); @@ -1089,8 +1090,8 @@ class IssuesProcessor { (_a = this.statistics) === null || _a === void 0 ? void 0 : _a.incrementAddedItemsLabel(issue); if (!this.options.debugOnly) { yield this.client.rest.issues.addLabels({ - owner: github_1.context.repo.owner, - repo: github_1.context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, labels: labelsToAdd }); @@ -2173,6 +2174,8 @@ exports.Option = void 0; var Option; (function (Option) { Option["RepoToken"] = "repo-token"; + Option["RepoOwner"] = "repo-owner"; + Option["RepoName"] = "repo-name"; Option["StaleIssueMessage"] = "stale-issue-message"; Option["StalePrMessage"] = "stale-pr-message"; Option["CloseIssueMessage"] = "close-issue-message"; @@ -2480,6 +2483,7 @@ var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, ge }; Object.defineProperty(exports, "__esModule", ({ value: true })); const core = __importStar(__nccwpck_require__(2186)); +const github_1 = __nccwpck_require__(5438); const issues_processor_1 = __nccwpck_require__(3292); const is_valid_date_1 = __nccwpck_require__(891); const state_service_1 = __nccwpck_require__(6330); @@ -2514,6 +2518,12 @@ function _run() { function _getAndValidateArgs() { const args = { repoToken: core.getInput('repo-token'), + repoOwner: core.getInput('repo-owner') === '' + ? github_1.context.repo.owner + : core.getInput('repo-owner'), + repoName: core.getInput('repo-name') === '' + ? github_1.context.repo.repo + : core.getInput('repo-name'), staleIssueMessage: core.getInput('stale-issue-message'), stalePrMessage: core.getInput('stale-pr-message'), closeIssueMessage: core.getInput('close-issue-message'), diff --git a/src/classes/issue.spec.ts b/src/classes/issue.spec.ts index a2c82e268..c0c8224d2 100644 --- a/src/classes/issue.spec.ts +++ b/src/classes/issue.spec.ts @@ -38,6 +38,8 @@ describe('Issue', (): void => { removeIssueStaleWhenUpdated: undefined, removePrStaleWhenUpdated: undefined, repoToken: '', + repoOwner: '', + repoName: '', staleIssueMessage: '', stalePrMessage: '', startDate: undefined, diff --git a/src/classes/issues-processor.ts b/src/classes/issues-processor.ts index 31bbb99d6..ed7b42fbe 100644 --- a/src/classes/issues-processor.ts +++ b/src/classes/issues-processor.ts @@ -1,5 +1,5 @@ import * as core from '@actions/core'; -import {context, getOctokit} from '@actions/github'; +import {getOctokit} from '@actions/github'; import {GitHub} from '@actions/github/lib/utils'; import {Option} from '../enums/option'; import {getHumanizedDate} from '../functions/dates/get-humanized-date'; @@ -548,8 +548,8 @@ export class IssuesProcessor { this._consumeIssueOperation(issue); this.statistics?.incrementFetchedItemsCommentsCount(); const comments = await this.client.rest.issues.listComments({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, since: sinceDate }); @@ -562,11 +562,16 @@ export class IssuesProcessor { // grab issues from github in batches of 100 async getIssues(page: number): Promise { + this._logger.info( + LoggerService.green( + `Processing: ${this.options.repoOwner}/${this.options.repoName}` + ) + ); try { this.operations.consumeOperation(); const issueResult = await this.client.rest.issues.listForRepo({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, state: 'open', per_page: 100, direction: this.options.ascending ? 'asc' : 'desc', @@ -596,8 +601,8 @@ 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, + owner: this.options.repoOwner, + repo: this.options.repoName, per_page: 100, issue_number: issue.number }); @@ -627,8 +632,8 @@ export class IssuesProcessor { this.statistics?.incrementFetchedPullRequestsCount(); const pullRequest = await this.client.rest.pulls.get({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, pull_number: issue.number }); @@ -847,8 +852,8 @@ export class IssuesProcessor { if (!this.options.debugOnly) { await this.client.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, body: staleMessage }); @@ -865,8 +870,8 @@ export class IssuesProcessor { if (!this.options.debugOnly) { await this.client.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, labels: [staleLabel] }); @@ -895,8 +900,8 @@ export class IssuesProcessor { if (!this.options.debugOnly) { await this.client.rest.issues.createComment({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, body: closeMessage }); @@ -913,8 +918,8 @@ export class IssuesProcessor { if (!this.options.debugOnly) { await this.client.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, labels: [closeLabel] }); @@ -930,8 +935,8 @@ export class IssuesProcessor { if (!this.options.debugOnly) { await this.client.rest.issues.update({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, state: 'closed', state_reason: this.options.closeIssueReason || undefined @@ -967,7 +972,7 @@ export class IssuesProcessor { if ( pullRequest.head.repo === null || pullRequest.head.repo.full_name === - `${context.repo.owner}/${context.repo.repo}` + `${this.options.repoOwner}/${this.options.repoName}` ) { issueLogger.info( `Deleting the branch "${LoggerService.cyan(branch)}" from closed $$type` @@ -979,8 +984,8 @@ export class IssuesProcessor { if (!this.options.debugOnly) { await this.client.rest.git.deleteRef({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, ref: `heads/${branch}` }); } @@ -1023,8 +1028,8 @@ export class IssuesProcessor { if (!this.options.debugOnly) { await this.client.rest.issues.removeLabel({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, name: label }); @@ -1161,8 +1166,8 @@ export class IssuesProcessor { this.statistics?.incrementAddedItemsLabel(issue); if (!this.options.debugOnly) { await this.client.rest.issues.addLabels({ - owner: context.repo.owner, - repo: context.repo.repo, + owner: this.options.repoOwner, + repo: this.options.repoName, issue_number: issue.number, labels: labelsToAdd }); diff --git a/src/enums/option.ts b/src/enums/option.ts index 7a9bff026..ae5478831 100644 --- a/src/enums/option.ts +++ b/src/enums/option.ts @@ -1,5 +1,7 @@ export enum Option { RepoToken = 'repo-token', + RepoOwner = 'repo-owner', + RepoName = 'repo-name', StaleIssueMessage = 'stale-issue-message', StalePrMessage = 'stale-pr-message', CloseIssueMessage = 'close-issue-message', diff --git a/src/interfaces/issues-processor-options.ts b/src/interfaces/issues-processor-options.ts index 930992284..cd4db75af 100644 --- a/src/interfaces/issues-processor-options.ts +++ b/src/interfaces/issues-processor-options.ts @@ -2,6 +2,8 @@ import {IsoOrRfcDateString} from '../types/iso-or-rfc-date-string'; export interface IIssuesProcessorOptions { repoToken: string; + repoOwner: string; + repoName: string; staleIssueMessage: string; stalePrMessage: string; closeIssueMessage: string; diff --git a/src/main.ts b/src/main.ts index a7836c160..a94917561 100644 --- a/src/main.ts +++ b/src/main.ts @@ -1,4 +1,5 @@ import * as core from '@actions/core'; +import {context} from '@actions/github'; import {IssuesProcessor} from './classes/issues-processor'; import {isValidDate} from './functions/dates/is-valid-date'; import {IIssuesProcessorOptions} from './interfaces/issues-processor-options'; @@ -57,6 +58,14 @@ async function _run(): Promise { function _getAndValidateArgs(): IIssuesProcessorOptions { const args: IIssuesProcessorOptions = { repoToken: core.getInput('repo-token'), + repoOwner: + core.getInput('repo-owner') === '' + ? context.repo.owner + : core.getInput('repo-owner'), + repoName: + core.getInput('repo-name') === '' + ? context.repo.repo + : core.getInput('repo-name'), staleIssueMessage: core.getInput('stale-issue-message'), stalePrMessage: core.getInput('stale-pr-message'), closeIssueMessage: core.getInput('close-issue-message'),