closeMilestone.ts 2.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475
  1. import { Task, TaskRunner } from './task';
  2. import GithubClient from '../utils/githubClient';
  3. interface CloseMilestoneOptions {
  4. milestone: string;
  5. }
  6. const closeMilestoneTaskRunner: TaskRunner<CloseMilestoneOptions> = async ({ milestone }) => {
  7. const githubClient = new GithubClient(true);
  8. const cherryPickLabel = 'cherry-pick needed';
  9. const client = githubClient.client;
  10. if (!/^\d+$/.test(milestone)) {
  11. console.log('Use milestone number not title, find number in milestone url');
  12. return;
  13. }
  14. const milestoneRes = await client.get(`/milestones/${milestone}`, {});
  15. const milestoneState = milestoneRes.data.state;
  16. if (milestoneState === 'closed') {
  17. console.log('milestone already closed. ✅');
  18. return;
  19. }
  20. console.log('fetching issues/PRs of the milestone ⏬');
  21. // Get all the issues/PRs with the label cherry-pick
  22. // Every pull request is actually an issue
  23. const issuesRes = await client.get('/issues', {
  24. params: {
  25. state: 'closed',
  26. labels: cherryPickLabel,
  27. per_page: 100,
  28. milestone: milestone,
  29. },
  30. });
  31. if (issuesRes.data.length < 1) {
  32. console.log('no issues to remove label from');
  33. } else {
  34. console.log(`found ${issuesRes.data.length} issues to remove the cherry-pick label from 🔎`);
  35. }
  36. for (const issue of issuesRes.data) {
  37. // the reason for using stdout.write is for achieving 'action -> result' on
  38. // the same line
  39. process.stdout.write(`🔧removing label from issue #${issue.number} 🗑...`);
  40. const resDelete = await client.delete(`/issues/${issue.number}/labels/${cherryPickLabel}`, {});
  41. if (resDelete.status === 200) {
  42. process.stdout.write('done ✅\n');
  43. } else {
  44. console.log('failed ❌');
  45. }
  46. }
  47. console.log(`cleaned up ${issuesRes.data.length} issues/prs ⚡️`);
  48. const resClose = await client.patch(`/milestones/${milestone}`, {
  49. state: 'closed',
  50. });
  51. if (resClose.status === 200) {
  52. console.log('milestone closed 🙌');
  53. } else {
  54. console.log('failed to close the milestone, response:');
  55. console.log(resClose);
  56. }
  57. };
  58. export const closeMilestoneTask = new Task<CloseMilestoneOptions>();
  59. closeMilestoneTask.setName('Close Milestone generator task');
  60. closeMilestoneTask.setRunner(closeMilestoneTaskRunner);