forked from w3c/webref
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathrelease-package.js
193 lines (171 loc) · 5.55 KB
/
release-package.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
180
181
182
183
184
185
186
187
188
189
190
191
192
193
/**
* Publish a Webref package to npm, using the commit on which the pre-release
* PR is based.
*/
const Octokit = require("./octokit");
const fs = require("fs");
const path = require("path");
const os = require("os");
const { execSync } = require("child_process");
const { rimraf } = require("rimraf");
const { npmPublish } = require("@jsdevtools/npm-publish");
const owner = "w3c";
const repo = "webref";
/**
* Release package at the requested version.
*
* @function
* @param {Number} prNumber Pre-release PR number
*/
async function releasePackage(prNumber) {
console.log(`Retrieve pre-release PR`);
const prResponse = await octokit.pulls.get({
owner, repo,
pull_number: prNumber
});
const preReleasePR = prResponse?.data;
if (!preReleasePR) {
console.log("- Given PR does not seem to exist, nothing to release");
return;
}
// Extract type from PR title
console.log(`- Given PR title: ${preReleasePR.title}`);
const match = preReleasePR.title.match(/^📦 Release @webref\/(.*)@(.*)$/);
if (!match) {
console.log("- Given PR is not a pre-release PR, nothing to release");
return;
}
const type = match[1];
if (!["css", "elements", "events", "idl"].includes(type)) {
console.log(`- Unknown package type "${type}", nothing to release`);
return;
}
// Extract commit to release from PR
const preReleaseSha = preReleasePR.base.sha;
console.log(`- Found commit to release: ${preReleaseSha}`);
// Find corresponding commit in curated branch from PR body
const curatedShaRegex = /triggered by curated data at ([0-9a-f]+)./;
const curatedShaArr = curatedShaRegex.exec(preReleasePR.body);
const curatedSha = curatedShaArr[1];
if (curatedSha) {
console.log(`- Found corresponding commit on curated branch: ${curatedSha}`);
}
else {
console.log('- No corresponding commit on curated branch');
}
console.log();
console.log("Publish package to npm");
console.log("- Checkout repo at right commit in temporary folder");
const tmpFolder = fs.mkdtempSync(path.join(os.tmpdir(), "webref-"));
try {
execSync(`git clone https://github.com/${owner}/${repo}`, {
cwd: tmpFolder
});
const installFolder = path.join(tmpFolder, "webref");
execSync(`git reset --hard ${preReleaseSha}`, {
cwd: installFolder
});
console.log(`- Installation folder: ${installFolder}`);
console.log("- Prepare package files");
execSync("npm ci", {
cwd: installFolder
});
execSync("npm run curate", {
cwd: installFolder
});
console.log(`- Publish packages/${type} folder to npm`);
const packageFolder = path.join(installFolder, "packages", type, "package.json");
const pubResult = await npmPublish({
package: packageFolder,
token: NPM_TOKEN
//, debug: console.debug
});
console.log(`- Published version was ${pubResult.oldVersion}`);
console.log(`- Version bump: ${pubResult.type}`);
console.log(`- Published version is ${pubResult.version}`);
console.log();
console.log("Add release tag to commit");
if (pubResult.version === pubResult.oldVersion) {
console.log("- Skip, no actual package released");
}
else {
const rawTag = `@webref/raw-${type}@${pubResult.version}`;
await octokit.git.createRef({
owner, repo,
ref: `refs/tags/${rawTag}`,
sha: preReleaseSha
});
console.log(`- Tagged released commit ${preReleaseSha} with tag "${rawTag}"`);
if (curatedSha) {
const curatedTag = `@webref/${type}@${pubResult.version}`;
await octokit.git.createRef({
owner, repo,
ref: `refs/tags/${curatedTag}`,
sha: curatedSha
});
console.log(`- Tagged curated commit ${curatedSha} with tag "${curatedTag}"`);
await octokit.git.updateRef({
owner, repo,
ref: `heads/@webref/${type}@latest`,
sha: curatedSha
});
console.log(`- Updated ${type}-latest to point to curated commit ${curatedSha}`);
}
else {
console.log(`- No commit to tag on curated branch, ${type}-latest tag not updated`);
}
}
}
finally {
console.log("Clean temporary folder");
try {
rimraf.sync(tmpFolder);
console.log("- done");
}
catch {
}
}
}
/*******************************************************************************
Retrieve tokens from environment, prepare Octokit and kick things off
*******************************************************************************/
const GH_TOKEN = (() => {
try {
return require("../config.json").GH_TOKEN;
} catch {
return process.env.GH_TOKEN;
}
})();
if (!GH_TOKEN) {
console.error("GH_TOKEN must be set to some personal access token as an env variable or in a config.json file");
process.exit(1);
}
const NPM_TOKEN = (() => {
try {
return require("../config.json").NPM_TOKEN;
} catch {
return process.env.NPM_TOKEN;
}
})();
if (!NPM_TOKEN) {
console.error("NPM_TOKEN must be set to an npm token as an env variable or in a config.json file");
process.exit(1);
}
// Note: npm-publish has a bug and needs an "INPUT_TOKEN" env variable:
// https://github.com/JS-DevTools/npm-publish/issues/15
// (we're passing the token to the function directly, no need to set it here)
process.env.INPUT_TOKEN = "";
const octokit = new Octokit({
auth: GH_TOKEN
//, log: console
});
const prereleasePR = parseInt(process.argv[2], 10);
releasePackage(prereleasePR)
.then(() => {
console.log();
console.log("== The end ==");
})
.catch(err => {
console.error(err);
process.exit(1);
});