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