Skip to content

Commit

Permalink
Merge pull request #937 from ckeditor/ck/15697
Browse files Browse the repository at this point in the history
Feature (stale-bot): Added support for pending issues so that they can be flagged sooner as stale ones. Closes ckeditor/ckeditor5#15697.
  • Loading branch information
pomek committed Feb 5, 2024
2 parents cea05e5 + b30d285 commit c21d7ee
Show file tree
Hide file tree
Showing 14 changed files with 1,698 additions and 748 deletions.
8 changes: 5 additions & 3 deletions packages/ckeditor5-dev-stale-bot/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -27,9 +27,9 @@ The following configuration options are supported by the stale bot:

* `GITHUB_TOKEN` – Required. A GitHub token with the `repo:*` scope needed for managing repositories and issues.
* `REPOSITORY_SLUG` – Required. The repository name in the format of `owner/name`, where stale bot will check for stale issues and pull requests.
* `STALE_LABELS` – Required. List of labels to add on staled issues and pull requests.
* `CLOSE_ISSUE_LABELS` – Required. List of labels to add after closing a stale issue.
* `CLOSE_PR_LABELS` – Required. List of labels to add after closing a stale pull request.
* `STALE_LABELS` – Required. A list of labels to add on staled issues and pull requests.
* `CLOSE_ISSUE_LABELS` – Required. A list of labels to add after closing a stale issue.
* `CLOSE_PR_LABELS` – Required. A list of labels to add after closing a stale pull request.
* `STALE_ISSUE_MESSAGE` – Required. A comment that is added on the staled issues.
* `STALE_PR_MESSAGE` – Required. A comment that is added on the staled pull requests.
* `CLOSE_ISSUE_MESSAGE` – Required. A comment that is added on the closed issues.
Expand All @@ -40,6 +40,8 @@ The following configuration options are supported by the stale bot:
* the last date of adding a reaction to the body of issue or pull request,
* the last date of adding or editing a comment,
* the last date of changing a label.
* `DAYS_BEFORE_STALE_PENDING_ISSUE` – Optional, 14 by default. The number of days without a comment on pending issue from a non-team member that qualifies the issue to be marked as stale.
* `PENDING_ISSUE_LABELS` – Optional, an empty array by default. A list of labels that identify a pending issue. If empty, then pending issues are not processed.
* `DAYS_BEFORE_CLOSE` – Optional, 30 by default. The number of days before closing the stale issues or the stale pull requests.
* `IGNORE_VIEWER_ACTIVITY` – Optional, `true` by default. If set, the activity from the currently authenticated user is ignored.
* `IGNORED_ISSUE_LABELS` – Optional, an empty array by default. A list of labels, whose assignment to an issue causes the issue to be ignored, even if it fits the stale criteria.
Expand Down
52 changes: 46 additions & 6 deletions packages/ckeditor5-dev-stale-bot/bin/stale-bot.js
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ main().catch( error => {

/**
* Launches the stale bot that searches the issues and pull requests to stale, unstale or close.
* It also may check if pending issues should be staled or have the pending labels removed.
*
* @returns {Promise}
*/
Expand Down Expand Up @@ -50,13 +51,15 @@ async function main() {
const {
issuesOrPullRequestsToStale,
issuesOrPullRequestsToClose,
issuesOrPullRequestsToUnstale
issuesOrPullRequestsToUnstale,
pendingIssuesToUnlabel
} = searchResult;

if ( !dryRun ) {
const staleLabels = await githubRepository.getLabels( options.repositorySlug, options.staleLabels );
const closeIssueLabels = await githubRepository.getLabels( options.repositorySlug, options.closeIssueLabels );
const closePullRequestLabels = await githubRepository.getLabels( options.repositorySlug, options.closePullRequestLabels );
const pendingIssueLabels = await githubRepository.getLabels( options.repositorySlug, options.pendingIssueLabels );

if ( issuesOrPullRequestsToStale.length ) {
const actions = {
Expand Down Expand Up @@ -96,15 +99,25 @@ async function main() {

await handleActions( githubRepository, issuesOrPullRequestsToClose, actions, spinner );
}

if ( pendingIssuesToUnlabel.length ) {
const actions = {
title: 'Unlabeling pending issues...',
labelsToRemove: pendingIssueLabels
};

await handleActions( githubRepository, pendingIssuesToUnlabel, actions, spinner );
}
}

spinner.instance.stop();

printStatus( dryRun, searchResult );
printStatus( dryRun, searchResult, options );
}

/**
* Searches for new issues or pull requests to stale and already staled ones that should be unstaled or closed.
* It also searches for pending issues that should be staled or unlabeled.
*
* @param {GitHubRepository} githubRepository GitHubRepository instance.
* @param {Options} options Configuration options.
Expand All @@ -127,10 +140,22 @@ async function search( githubRepository, options, spinner ) {
issuesOrPullRequestsToUnstale
} = await githubRepository.searchStaleIssuesOrPullRequests( options, spinner.onProgress() );

let pendingIssuesToStale = [];
let pendingIssuesToUnlabel = [];

if ( options.shouldProcessPendingIssues ) {
spinner.printStatus( 'Searching for pending issues...' );

const pendingIssues = await githubRepository.searchPendingIssues( options, spinner.onProgress() );
pendingIssuesToStale = pendingIssues.pendingIssuesToStale;
pendingIssuesToUnlabel = pendingIssues.pendingIssuesToUnlabel;
}

return {
issuesOrPullRequestsToStale: [ ...issuesToStale, ...pullRequestsToStale ],
issuesOrPullRequestsToStale: [ ...issuesToStale, ...pullRequestsToStale, ...pendingIssuesToStale ],
issuesOrPullRequestsToUnstale,
issuesOrPullRequestsToClose
issuesOrPullRequestsToClose,
pendingIssuesToUnlabel
};
}

Expand Down Expand Up @@ -194,12 +219,14 @@ function printWelcomeMessage( dryRun ) {
*
* @param {Boolean} dryRun Indicates if dry run mode is enabled.
* @param {SearchResult} searchResult Found issues and pull requests that require an action.
* @param {Options} options Configuration options.
*/
function printStatus( dryRun, searchResult ) {
function printStatus( dryRun, searchResult, options ) {
const {
issuesOrPullRequestsToStale,
issuesOrPullRequestsToClose,
issuesOrPullRequestsToUnstale
issuesOrPullRequestsToUnstale,
pendingIssuesToUnlabel
} = searchResult;

if ( !issuesOrPullRequestsToStale.length ) {
Expand Down Expand Up @@ -231,6 +258,18 @@ function printStatus( dryRun, searchResult ) {

printStatusSection( statusMessage, issuesOrPullRequestsToClose );
}

if ( options.shouldProcessPendingIssues ) {
if ( !pendingIssuesToUnlabel.length ) {
console.log( chalk.green.bold( '💡 No pending issues can be unlabeled now.\n' ) );
} else {
const statusMessage = dryRun ?
'🔖 The following pending issues should be unlabeled:\n' :
'🔖 The following pending issues were unlabeled:\n';

printStatusSection( statusMessage, pendingIssuesToUnlabel );
}
}
}

/**
Expand All @@ -252,6 +291,7 @@ function printStatusSection( statusMessage, entries ) {
* @property {Array.<IssueOrPullRequestResult>} issuesOrPullRequestsToClose
* @property {Array.<IssueOrPullRequestResult>} issuesOrPullRequestsToStale
* @property {Array.<IssueOrPullRequestResult>} issuesOrPullRequestsToUnstale
* @property {Array.<IssueOrPullRequestResult>} pendingIssuesToUnlabel
*/

/**
Expand Down
13 changes: 11 additions & 2 deletions packages/ckeditor5-dev-stale-bot/bin/utils/parseconfig.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,9 @@ module.exports = function parseConfig( viewerLogin, config ) {
CLOSE_ISSUE_MESSAGE,
CLOSE_PR_LABELS,
CLOSE_PR_MESSAGE,
PENDING_ISSUE_LABELS = [],
DAYS_BEFORE_STALE = 365,
DAYS_BEFORE_STALE_PENDING_ISSUE = 14,
DAYS_BEFORE_CLOSE = 30,
IGNORE_VIEWER_ACTIVITY = true,
IGNORED_ISSUE_LABELS = [],
Expand All @@ -35,14 +37,17 @@ module.exports = function parseConfig( viewerLogin, config ) {

const now = new Date();
const staleDate = formatISO( subDays( now, DAYS_BEFORE_STALE ) );
const staleDatePendingIssue = formatISO( subDays( now, DAYS_BEFORE_STALE_PENDING_ISSUE ) );
const closeDate = formatISO( subDays( now, DAYS_BEFORE_CLOSE ) );

return {
repositorySlug: REPOSITORY_SLUG,
staleDate,
staleDatePendingIssue,
closeDate,
searchDate: staleDate,
staleLabels: STALE_LABELS,
shouldProcessPendingIssues: PENDING_ISSUE_LABELS.length > 0,
pendingIssueLabels: PENDING_ISSUE_LABELS,
staleIssueMessage: STALE_ISSUE_MESSAGE,
stalePullRequestMessage: STALE_PR_MESSAGE,
closeIssueLabels: CLOSE_ISSUE_LABELS,
Expand All @@ -69,7 +74,9 @@ module.exports = function parseConfig( viewerLogin, config ) {
* @property {String} CLOSE_ISSUE_MESSAGE
* @property {Array.<String>} CLOSE_PR_LABELS
* @property {String} CLOSE_PR_MESSAGE
* @property {Array.<String>} [PENDING_ISSUE_LABELS=[]]
* @property {Number} [DAYS_BEFORE_STALE=365]
* @property {Number} [DAYS_BEFORE_STALE_PENDING_ISSUE=14]
* @property {Number} [DAYS_BEFORE_CLOSE=30]
* @property {Boolean} [IGNORE_VIEWER_ACTIVITY=true]
* @property {Array.<String>} [IGNORED_ISSUE_LABELS=[]]
Expand All @@ -82,9 +89,11 @@ module.exports = function parseConfig( viewerLogin, config ) {
* @typedef {Object} Options
* @property {String} repositorySlug
* @property {String} staleDate
* @property {String} staleDatePendingIssue
* @property {String} closeDate
* @property {String} searchDate
* @property {Array.<String>} staleLabels
* @property {Boolean} shouldProcessPendingIssues
* @property {Array.<String>} pendingIssueLabels
* @property {String} staleIssueMessage
* @property {String} stalePullRequestMessage
* @property {Array.<String>} closeIssueLabels
Expand Down
Loading

0 comments on commit c21d7ee

Please sign in to comment.