1*7195f9f8SGabriel Donadel Dall'Agnolimport { Command } from '@expo/commander'; 2*7195f9f8SGabriel Donadel Dall'Agnol 3*7195f9f8SGabriel Donadel Dall'Agnolimport * as GitHub from '../GitHub'; 4*7195f9f8SGabriel Donadel Dall'Agnolimport * as Linear from '../Linear'; 5*7195f9f8SGabriel Donadel Dall'Agnolimport logger from '../Logger'; 6*7195f9f8SGabriel Donadel Dall'Agnol 7*7195f9f8SGabriel Donadel Dall'Agnoltype ActionOptions = { 8*7195f9f8SGabriel Donadel Dall'Agnol issue: string; 9*7195f9f8SGabriel Donadel Dall'Agnol}; 10*7195f9f8SGabriel Donadel Dall'Agnol 11*7195f9f8SGabriel Donadel Dall'Agnolexport default (program: Command) => { 12*7195f9f8SGabriel Donadel Dall'Agnol program 13*7195f9f8SGabriel Donadel Dall'Agnol .command('close-linear-issue-from-github') 14*7195f9f8SGabriel Donadel Dall'Agnol .alias('clifg') 15*7195f9f8SGabriel Donadel Dall'Agnol .description('Close a Linear issue imported from GitHub.') 16*7195f9f8SGabriel Donadel Dall'Agnol .option('-i, --issue <string>', 'Number of the original GitHub issue.') 17*7195f9f8SGabriel Donadel Dall'Agnol .asyncAction(action); 18*7195f9f8SGabriel Donadel Dall'Agnol}; 19*7195f9f8SGabriel Donadel Dall'Agnol 20*7195f9f8SGabriel Donadel Dall'Agnolasync function action(options: ActionOptions) { 21*7195f9f8SGabriel Donadel Dall'Agnol if (isNaN(Number(options.issue))) { 22*7195f9f8SGabriel Donadel Dall'Agnol throw new Error('Flag `--issue` must be provided with a number value'); 23*7195f9f8SGabriel Donadel Dall'Agnol } 24*7195f9f8SGabriel Donadel Dall'Agnol if (!process.env.GITHUB_TOKEN) { 25*7195f9f8SGabriel Donadel Dall'Agnol throw new Error('Environment variable `GITHUB_TOKEN` is required for this command.'); 26*7195f9f8SGabriel Donadel Dall'Agnol } 27*7195f9f8SGabriel Donadel Dall'Agnol if (!process.env.LINEAR_API_KEY) { 28*7195f9f8SGabriel Donadel Dall'Agnol throw new Error('Environment variable `LINEAR_API_KEY` is required for this command.'); 29*7195f9f8SGabriel Donadel Dall'Agnol } 30*7195f9f8SGabriel Donadel Dall'Agnol 31*7195f9f8SGabriel Donadel Dall'Agnol try { 32*7195f9f8SGabriel Donadel Dall'Agnol await closeIssueAsync(+options.issue); 33*7195f9f8SGabriel Donadel Dall'Agnol } catch (error) { 34*7195f9f8SGabriel Donadel Dall'Agnol logger.error(error); 35*7195f9f8SGabriel Donadel Dall'Agnol throw error; 36*7195f9f8SGabriel Donadel Dall'Agnol } 37*7195f9f8SGabriel Donadel Dall'Agnol} 38*7195f9f8SGabriel Donadel Dall'Agnol 39*7195f9f8SGabriel Donadel Dall'Agnolasync function closeIssueAsync(githubIssueNumber: number) { 40*7195f9f8SGabriel Donadel Dall'Agnol const linearIssues = await Linear.getIssuesAsync({ 41*7195f9f8SGabriel Donadel Dall'Agnol teamId: Linear.ENG_TEAM_ID, 42*7195f9f8SGabriel Donadel Dall'Agnol filter: { 43*7195f9f8SGabriel Donadel Dall'Agnol description: { 44*7195f9f8SGabriel Donadel Dall'Agnol containsIgnoreCase: `https://github.com/expo/expo/issues/${githubIssueNumber}`, 45*7195f9f8SGabriel Donadel Dall'Agnol }, 46*7195f9f8SGabriel Donadel Dall'Agnol labels: { 47*7195f9f8SGabriel Donadel Dall'Agnol some: { 48*7195f9f8SGabriel Donadel Dall'Agnol name: { eq: 'GitHub' }, 49*7195f9f8SGabriel Donadel Dall'Agnol }, 50*7195f9f8SGabriel Donadel Dall'Agnol }, 51*7195f9f8SGabriel Donadel Dall'Agnol }, 52*7195f9f8SGabriel Donadel Dall'Agnol }); 53*7195f9f8SGabriel Donadel Dall'Agnol const linearIssue = linearIssues?.[0]; 54*7195f9f8SGabriel Donadel Dall'Agnol 55*7195f9f8SGabriel Donadel Dall'Agnol if (!linearIssue) { 56*7195f9f8SGabriel Donadel Dall'Agnol throw new Error( 57*7195f9f8SGabriel Donadel Dall'Agnol `Unable to find a Linear issue referring to the Github issue #${githubIssueNumber}.` 58*7195f9f8SGabriel Donadel Dall'Agnol ); 59*7195f9f8SGabriel Donadel Dall'Agnol } 60*7195f9f8SGabriel Donadel Dall'Agnol 61*7195f9f8SGabriel Donadel Dall'Agnol await Linear.closeIssueAsync({ issueId: linearIssue.id, teamId: Linear.ENG_TEAM_ID }); 62*7195f9f8SGabriel Donadel Dall'Agnol 63*7195f9f8SGabriel Donadel Dall'Agnol const issueCloserPR = await GitHub.getIssueCloserPrUrlAsync(githubIssueNumber); 64*7195f9f8SGabriel Donadel Dall'Agnol 65*7195f9f8SGabriel Donadel Dall'Agnol if (issueCloserPR) { 66*7195f9f8SGabriel Donadel Dall'Agnol await Linear.commentIssueAsync({ 67*7195f9f8SGabriel Donadel Dall'Agnol issueId: linearIssue.id, 68*7195f9f8SGabriel Donadel Dall'Agnol comment: `This issue was automatically marked as done by ${issueCloserPR}`, 69*7195f9f8SGabriel Donadel Dall'Agnol }); 70*7195f9f8SGabriel Donadel Dall'Agnol } 71*7195f9f8SGabriel Donadel Dall'Agnol} 72