From 139be3d7ba6366e9d7da49a14059367dce65609e Mon Sep 17 00:00:00 2001 From: Sofia Papagiannaki Date: Tue, 26 May 2020 17:26:16 +0300 Subject: [PATCH] grafana/toolkit: Modify close milestone task to remove label from more than 100 pull requests and add dry run option (#25108) * Fix close milestone to remove label from all the required pull requests There used to be a limit to 100 pull requests. * Add dry run option in close-milestone task --- packages/grafana-toolkit/src/cli/index.ts | 2 + .../src/cli/tasks/closeMilestone.ts | 89 +++++++++++-------- 2 files changed, 56 insertions(+), 35 deletions(-) diff --git a/packages/grafana-toolkit/src/cli/index.ts b/packages/grafana-toolkit/src/cli/index.ts index 977b3293395..4b28ee9ba21 100644 --- a/packages/grafana-toolkit/src/cli/index.ts +++ b/packages/grafana-toolkit/src/cli/index.ts @@ -104,6 +104,7 @@ export const run = (includeInternalScripts = false) => { program .command('close-milestone') .option('-m, --milestone ', 'Specify milestone') + .option('--dryRun', 'Only simulate actions') .description('Helps ends a milestone by removing the cherry-pick label and closing it') .action(async cmd => { if (!cmd.milestone) { @@ -113,6 +114,7 @@ export const run = (includeInternalScripts = false) => { await execTask(closeMilestoneTask)({ milestone: cmd.milestone, + dryRun: !!cmd.dryRun, }); }); diff --git a/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts b/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts index 3cc10b66538..0ac396a36fe 100644 --- a/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts +++ b/packages/grafana-toolkit/src/cli/tasks/closeMilestone.ts @@ -3,9 +3,10 @@ import GithubClient from '../utils/githubClient'; interface CloseMilestoneOptions { milestone: string; + dryRun: boolean; } -const closeMilestoneTaskRunner: TaskRunner = async ({ milestone }) => { +const closeMilestoneTaskRunner: TaskRunner = async ({ milestone, dryRun }) => { const githubClient = new GithubClient({ required: true }); const cherryPickLabel = 'cherry-pick needed'; @@ -16,6 +17,10 @@ const closeMilestoneTaskRunner: TaskRunner = async ({ mil return; } + if (dryRun) { + console.log('dry run is enabled'); + } + const milestoneRes = await client.get(`/milestones/${milestone}`, {}); const milestoneState = milestoneRes.data.state; @@ -27,46 +32,60 @@ const closeMilestoneTaskRunner: TaskRunner = async ({ mil console.log('fetching issues/PRs of the milestone โฌ'); - // Get all the issues/PRs with the label cherry-pick - // Every pull request is actually an issue - const issuesRes = await client.get('/issues', { - params: { - state: 'closed', - labels: cherryPickLabel, - per_page: 100, - milestone: milestone, - }, - }); + let totalIssues = 0; - if (issuesRes.data.length < 1) { - console.log('no issues to remove label from'); - } else { - console.log(`found ${issuesRes.data.length} issues to remove the cherry-pick label from ๐Ÿ”Ž`); - } + while (true) { + // Get first 100 issues/PRs with the label cherry-pick + // Every pull request is actually an issue + const issuesRes = await client.get('/issues', { + params: { + state: 'closed', + labels: cherryPickLabel, + per_page: 100, + milestone: milestone, + }, + }); - for (const issue of issuesRes.data) { - // the reason for using stdout.write is for achieving 'action -> result' on - // the same line - process.stdout.write(`๐Ÿ”งremoving label from issue #${issue.number} ๐Ÿ—‘...`); - const resDelete = await client.delete(`/issues/${issue.number}/labels/${cherryPickLabel}`, {}); - if (resDelete.status === 200) { - process.stdout.write('done โœ…\n'); - } else { - console.log('failed โŒ'); + if (issuesRes.data.length < 1) { + break; + } + + const comparativeStr = totalIssues === 0 ? ' ' : ' more '; + console.log(`found ${issuesRes.data.length}${comparativeStr}issues to remove the cherry-pick label from ๐Ÿ”Ž`); + totalIssues += issuesRes.data.length; + + for (const issue of issuesRes.data) { + // the reason for using stdout.write is for achieving 'action -> result' on + // the same line + process.stdout.write(`๐Ÿ”งremoving label from issue #${issue.number} ๐Ÿ—‘...`); + if (!dryRun) { + const resDelete = await client.delete(`/issues/${issue.number}/labels/${cherryPickLabel}`, {}); + if (resDelete.status === 200) { + process.stdout.write('done โœ…\n'); + } else { + console.log('failed โŒ'); + } + } } } - console.log(`cleaned up ${issuesRes.data.length} issues/prs โšก๏ธ`); - - const resClose = await client.patch(`/milestones/${milestone}`, { - state: 'closed', - }); - - if (resClose.status === 200) { - console.log('milestone closed ๐Ÿ™Œ'); + if (totalIssues === 0) { + console.log('no issues to remove label from'); } else { - console.log('failed to close the milestone, response:'); - console.log(resClose); + console.log(`cleaned up ${totalIssues} issues/prs โšก๏ธ`); + } + + if (!dryRun) { + const resClose = await client.patch(`/milestones/${milestone}`, { + state: 'closed', + }); + + if (resClose.status === 200) { + console.log('milestone closed ๐Ÿ™Œ'); + } else { + console.log('failed to close the milestone, response:'); + console.log(resClose); + } } };