-
Notifications
You must be signed in to change notification settings - Fork 2.9k
/
createOrUpdateStagingDeploy.js
165 lines (145 loc) · 7.36 KB
/
createOrUpdateStagingDeploy.js
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
const _ = require('underscore');
const core = require('@actions/core');
const moment = require('moment');
const GithubUtils = require('../../libs/GithubUtils');
const GitUtils = require('../../libs/GitUtils');
const run = function () {
const newVersion = core.getInput('NPM_VERSION');
let shouldCreateNewStagingDeployCash = false;
let currentStagingDeployCashIssueNumber = null;
// Start by fetching the list of recent StagingDeployCash issues, along with the list of open deploy blockers
return Promise.all([
GithubUtils.octokit.issues.listForRepo({
log: console,
owner: GithubUtils.GITHUB_OWNER,
repo: GithubUtils.EXPENSIFY_CASH_REPO,
labels: GithubUtils.STAGING_DEPLOY_CASH_LABEL,
state: 'all',
}),
GithubUtils.octokit.issues.listForRepo({
log: console,
owner: GithubUtils.GITHUB_OWNER,
repo: GithubUtils.EXPENSIFY_CASH_REPO,
labels: GithubUtils.DEPLOY_BLOCKER_CASH_LABEL,
}),
])
.then((results) => {
const [stagingDeployResponse, deployBlockerResponse] = results;
if (!stagingDeployResponse || !stagingDeployResponse.data || _.isEmpty(stagingDeployResponse.data)) {
console.error('Failed fetching StagingDeployCash issues from Github!', stagingDeployResponse);
throw new Error('Failed fetching StagingDeployCash issues from Github');
}
if (!deployBlockerResponse || !deployBlockerResponse.data) {
console.log('Failed fetching DeployBlockerCash issues from Github, continuing...');
}
// Look at the state of the most recent StagingDeployCash,
// if it is open then we'll update the existing one, otherwise, we'll create a new one.
shouldCreateNewStagingDeployCash = Boolean(stagingDeployResponse.data[0].state !== 'open');
if (shouldCreateNewStagingDeployCash) {
console.log('Latest StagingDeployCash is closed, creating a new one.', stagingDeployResponse.data[0]);
} else {
console.log(
'Latest StagingDeployCash is open, updating it instead of creating a new one.',
'Current:', stagingDeployResponse.data[0],
'Previous:', stagingDeployResponse.data[1],
);
}
// Parse the data from the previous StagingDeployCash
// (newest if there are none open, otherwise second-newest)
const previousStagingDeployCashData = shouldCreateNewStagingDeployCash
? GithubUtils.getStagingDeployCashData(stagingDeployResponse.data[0])
: GithubUtils.getStagingDeployCashData(stagingDeployResponse.data[1]);
console.log('Found tag of previous StagingDeployCash:', previousStagingDeployCashData.tag);
// Find the list of PRs merged between the last StagingDeployCash and the new version
const mergedPRs = GitUtils.getPullRequestsMergedBetween(previousStagingDeployCashData.tag, newVersion);
console.log(
'The following PRs have been merged between the previous StagingDeployCash and new version:',
mergedPRs,
);
if (shouldCreateNewStagingDeployCash) {
// We're in the create flow, not update
// TODO: if there are open DeployBlockers and we are opening a new checklist,
// then we should close / remove the DeployBlockerCash label from those
return GithubUtils.generateStagingDeployCashBody(
newVersion,
_.map(mergedPRs, GithubUtils.getPullRequestURLFromNumber),
);
}
// There is an open StagingDeployCash, so we'll be updating it, not creating a new one
const currentStagingDeployCashData = GithubUtils.getStagingDeployCashData(stagingDeployResponse.data[0]);
console.log('Parsed the following data from the current StagingDeployCash:', currentStagingDeployCashData);
currentStagingDeployCashIssueNumber = currentStagingDeployCashData.number;
const newDeployBlockers = _.map(deployBlockerResponse.data, ({html_url}) => ({
url: html_url,
number: GithubUtils.getIssueOrPullRequestNumberFromURL(html_url),
isResolved: false,
}));
// If we aren't sent a tag, then use the existing tag
const tag = newVersion || currentStagingDeployCashData.tag;
// Generate the PR list, preserving the previous state of `isVerified` for existing PRs
const PRList = _.sortBy(
_.unique(
_.union(currentStagingDeployCashData.PRList, _.map(mergedPRs, number => ({
number,
url: GithubUtils.getPullRequestURLFromNumber(number),
// Since this is the second argument to _.union,
// it will appear later in the array than any duplicate.
// Since it is later in the array, it will be truncated by _.unique,
// and the original value of isVerified will be preserved.
isVerified: false,
}))),
false,
item => item.number,
),
'number',
);
// Generate the deploy blocker list, preserving the previous state of `isResolved`
const deployBlockers = _.sortBy(
_.unique(
_.union(currentStagingDeployCashData.deployBlockers, newDeployBlockers),
false,
item => item.number,
),
'number',
);
return GithubUtils.generateStagingDeployCashBody(
tag,
_.pluck(PRList, 'url'),
_.pluck(_.where(PRList, {isVerified: true}), 'url'),
_.pluck(deployBlockers, 'url'),
_.pluck(_.where(deployBlockers, {isResolved: true}), 'url'),
);
})
.then((body) => {
const defaultPayload = {
owner: GithubUtils.GITHUB_OWNER,
repo: GithubUtils.EXPENSIFY_CASH_REPO,
body,
};
if (shouldCreateNewStagingDeployCash) {
return GithubUtils.octokit.issues.create({
...defaultPayload,
title: `Deploy Checklist: Expensify.cash ${moment().format('YYYY-MM-DD')}`,
labels: [GithubUtils.STAGING_DEPLOY_CASH_LABEL],
assignees: [GithubUtils.APPLAUSE_BOT],
});
}
return GithubUtils.octokit.issues.update({
...defaultPayload,
issue_number: currentStagingDeployCashIssueNumber,
});
})
.then(({data}) => {
// eslint-disable-next-line max-len
console.log(`Successfully ${shouldCreateNewStagingDeployCash ? 'created new' : 'updated'} StagingDeployCash! 🎉 ${data.html_url}`);
return data;
})
.catch((err) => {
console.error('An unknown error occurred!', err);
core.setFailed(err);
});
};
if (require.main === module) {
run();
}
module.exports = run;