-
Notifications
You must be signed in to change notification settings - Fork 1.2k
/
new-version-pr-generator.js
179 lines (146 loc) · 6.24 KB
/
new-version-pr-generator.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
166
167
168
169
170
171
172
173
174
175
176
177
178
179
/* eslint-disable no-console */
const {execSync} = require('child_process');
const {readFileSync} = require('fs');
const path = require('path');
const {mkdir} = require('shelljs');
const yaml = require('js-yaml');
const semver = require('semver');
const {version: PACKAGE_VERSION} = require('../package.json');
const secrets = require('../secrets.json');
const retry = require('./utilities/retry');
const repositories = ['polaris-styleguide', 'web'];
const YARN_VERSION = yaml
.safeLoad(readFileSync(path.resolve(__dirname, '..', 'dev.yml'), 'utf8'))
.up.find((obj) => Object.keys(obj).includes('node')).node.yarn;
const root = path.resolve(__dirname, '../');
const sandbox = path.resolve(root, 'sandbox');
const releaseVersion = `v${PACKAGE_VERSION}`;
function isMajorPrerelease(version) {
return (
semver.prerelease(version) &&
semver.minor(version) === 0 &&
semver.patch(version) === 0
);
}
const baseBranch = isMajorPrerelease(PACKAGE_VERSION)
? `v${semver.major(PACKAGE_VERSION)}`
: 'master';
const polarisBotName = 'Shopify Polaris Bot';
const polarisBotEmail = 'shopify-polaris-bot@users.noreply.github.com';
const polarisBotToken = secrets.github['shopify-polaris'];
const shopifyPolarisBotGitOverride = `GIT_COMMITTER_NAME='${polarisBotName}' GIT_COMMITTER_EMAIL='${polarisBotEmail}'`;
function pullRequestTemplate(repository, version) {
let prodAssetChecklist = '';
if (repository === 'web') {
prodAssetChecklist = `
### How to [tophat](https://development.shopify.io/engineering/developing_at_Shopify/write-code/tophatting)
<!-- Tophatting instructions, and/ or what you want reviewers to concentrate on. -->
⚠️ This PR must be tophatted with [production assets](https://github.com/Shopify/web/blob/master/documentation/guides/assets.md) because it updates a key dependency (Polaris React).
### Before you deploy
- [ ] This PR is [safe to rollback](https://development.shopify.io/guides/shipping/safe_to_merge#Signs_your_PR_is_safe_to_rollback). ⚠️ This field is required.
<!-- If it is not safe, please detail what would need to happen to make it safe. For example, if this PR removes a GraphQL field that will then be removed from the schema, link to the Shopify Core PR that removes the field. -->
- [ ] I [tophatted](https://development.shopify.io/engineering/developing_at_Shopify/write-code/tophatting) this change with production assets.
<!-- If you are having difficulties running the production build, please ask in #shopify-web. -->
`;
}
return `
## Version ${version} of @shopify/polaris just got published!
See what’s new: https://github.com/Shopify/polaris-react/releases/tag/${version}
${prodAssetChecklist}
---
<details>
<summary>🚨 What to do if you see “Your tests failed on CircleCI”?</summary>
If tests fail, you may have to troubleshoot the problem locally.
1. Checkout the \`update-polaris-${version}\` branch:
\`\`\`bash
dev cd ${repository}
git fetch
git checkout update-polaris-${version}
dev up
\`\`\`
1. Apply changes/fixes
1. Commit
1. Push your work to the \`update-polaris-${version}\` branch:
\`\`\`bash
git push origin update-polaris-${version}
\`\`\`
1. Repeat until the build & tests go ✅
1. 🎩
1. :shipit:
</details>
`.trim();
}
function failedUpdateMessage(repository, version) {
return `
The automatic branch creation for ${repository} failed. This can be due to many reasons. To resolve this follow these steps:
1. Checkout "${repository}"
2. Get the latest version of master "git checkout master && git pull"
3. Create a new branch based on the version that failed "git checkout -b update-polaris-v${version}"
4. Update "@shopify/polaris" by running "npx yarn upgrade @shopify/polaris@${version}"
5. Add the changed files to git by running "git add package.json yarn.lock"
6. Commit the changes with "git commit -m 'Update @shopify/polaris to ${version}'"
7. Push the changes with "git push origin update-polaris-v${version}"
8. Create a new pull request for the branch in "${repository}"
`;
}
mkdir(sandbox);
const jobs = repositories.map((repository) => {
// We should fix this but I've not got the time at the moment
// SEE https://eslint.org/docs/rules/no-async-promise-executor
// eslint-disable-next-line no-async-promise-executor
return new Promise(async (resolve, reject) => {
try {
const repositoryDirectory = path.resolve(sandbox, repository);
await retry(() => {
execSync(
`git clone --branch ${baseBranch} --single-branch https://${polarisBotToken}@github.com/Shopify/${repository}.git`,
{
// Clone into the sandbox directory
cwd: sandbox,
stdio: 'inherit',
},
);
});
const commands = [
`git checkout -b update-polaris-${releaseVersion}`,
`npx yarn@${YARN_VERSION} upgrade @shopify/polaris@${releaseVersion.replace(
'v',
'',
)} --no-progress --ignore-engines`,
`git add package.json yarn.lock`,
`${shopifyPolarisBotGitOverride} git commit -m "Update @shopify/polaris to ${releaseVersion}" --author "${polarisBotName} <${polarisBotEmail}>" -m "${releaseVersion}" --allow-empty`,
`git push origin update-polaris-${releaseVersion}`,
`curl -d '${JSON.stringify({
title: `Update @shopify/polaris to ${releaseVersion} 🚀`,
body: pullRequestTemplate(repository, releaseVersion),
head: `update-polaris-${releaseVersion}`,
base: baseBranch,
})}' -X POST https://api.github.com/repos/shopify/${repository}/pulls?access_token=${polarisBotToken}`,
];
for (const command of commands) {
await retry(() => {
execSync(command, {
// Run the commands in the cloned repository directories
cwd: repositoryDirectory,
stdio: 'inherit',
});
});
}
resolve(
`Pull request made in shopify/${repository} for version ${releaseVersion}`,
);
} catch (error) {
const errorMessage = `${error}\n\n${failedUpdateMessage(
repository,
releaseVersion,
)}`;
reject(errorMessage);
}
});
});
Promise.all(jobs)
.then((result) => console.log(result))
.catch((error) => {
console.error(error);
process.exit(0);
});