forked from cloudflare/workers-sdk
-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathchangeset-version.js
132 lines (121 loc) · 5.15 KB
/
changeset-version.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
const assert = require("node:assert");
const fs = require("node:fs");
const path = require("node:path");
const { execSync } = require("node:child_process");
// This script is used by the `release.yml` workflow to update the version of the packages being released.
// The standard step is only to run `changeset version` but this does not update the lockfile.
// So we also run `pnpm install`, which does this update.
// This is a workaround until this is handled automatically by `changeset version`.
// See https://github.com/changesets/changesets/issues/421.
function getPkg(filePath) {
return JSON.parse(fs.readFileSync(filePath, "utf8"));
}
function setPkg(filePath, newPkg) {
fs.writeFileSync(filePath, `${JSON.stringify(newPkg, null, "\t")}\n`);
}
function parseVersion(version) {
// Extract `<major>.<minor>.<patch>` from version (could be a constraint)
const match = /(\d+)\.(\d+)\.(\d+)/.exec(version);
assert(match !== null, `Expected ${version} to be <major>.<minor>.<patch>`);
return [parseInt(match[1]), parseInt(match[2]), parseInt(match[3])];
}
const rootPath = path.resolve(__dirname, "..");
const miniflarePath = path.join(rootPath, "packages/miniflare");
const miniflarePkgPath = path.join(miniflarePath, "package.json");
const miniflareChangelogPath = path.join(miniflarePath, "CHANGELOG.md");
/**
* Gets the correct version to bump `miniflare` to, ensuring the minor versions
* of `workerd` and `miniflare` match. Minor bumps in changesets will become
* patch bumps if the `workerd` version hasn't changed.
* See `changeset-version.test.js` for examples.
*
* @param workerdVersion `workerd` version constraint in `miniflare` package
* @param previousVersion `miniflare` version before running `changeset version`
* @param version `miniflare` version after running `changeset version`
*/
function getNextMiniflareVersion(workerdVersion, previousVersion, version) {
const [, workerdMinor] = parseVersion(workerdVersion);
const [, , previousPatch] = parseVersion(previousVersion);
const [major, minor] = parseVersion(version);
if (workerdMinor === minor) {
// If the minor versions match already, there's nothing we need to do
return version;
} else if (workerdMinor > minor) {
// If the workerd minor is greater than the miniflare minor,
// use the workerd minor and reset patch to 0
return `${major}.${workerdMinor}.0`;
} else {
// Otherwise, if the workerd minor is less than the miniflare minor,
// use the workerd minor and bump the patch instead
return `${major}.${workerdMinor}.${previousPatch + 1}`;
}
}
exports.getNextMiniflareVersion = getNextMiniflareVersion;
function main() {
// 1. Get `miniflare` version before applying changesets, so we know if the
// minor version was bumped
const previousMiniflarePkg = getPkg(miniflarePkgPath);
const previousMiniflareVersion = previousMiniflarePkg.version;
// 2. Run standard `changeset version` command to apply changesets, bump
// versions, and update changelogs
execSync("pnpm exec changeset version");
// 3. Force `miniflare`'s minor version to be the same as `workerd`
const miniflarePkg = getPkg(miniflarePkgPath);
const miniflareVersion = miniflarePkg.version;
const workerdVersion = miniflarePkg.dependencies.workerd;
const nextMiniflareVersion = getNextMiniflareVersion(
workerdVersion,
previousMiniflareVersion,
miniflareVersion
);
if (nextMiniflareVersion !== miniflareVersion) {
// If `changeset version` didn't produce the correct version on its own...
// ...update `miniflare`'s `package.json` version
miniflarePkg.version = nextMiniflareVersion;
setPkg(miniflarePkgPath, miniflarePkg);
const changedPathsBuffer = execSync("git ls-files --modified", {
cwd: rootPath,
});
const changedPaths = changedPathsBuffer.toString().trim().split("\n");
for (const relativeChangedPath of changedPaths) {
const changedPath = path.resolve(rootPath, relativeChangedPath);
const name = path.basename(changedPath);
if (name === "package.json") {
// ...update `miniflare` version in dependencies of other packages
const pkg = getPkg(changedPath);
let changed = false;
for (const key of [
"dependencies",
"devDependencies",
"peerDependencies",
"optionalDependencies",
]) {
const constraint = pkg[key]?.["miniflare"];
if (constraint === undefined) continue;
// Don't update `workspace:`-style constraints
if (constraint.startsWith("workspace:")) continue;
pkg[key]["miniflare"] = nextMiniflareVersion;
changed = true;
}
if (changed) setPkg(changedPath, pkg);
} else if (name === "CHANGELOG.md") {
// ...update `CHANGELOG.md`s with correct version
let changelog = fs.readFileSync(changedPath, "utf8");
// Replace version header in `miniflare` `CHANGELOG.md`
changelog = changelog.replace(
`## ${miniflareVersion}`,
`## ${nextMiniflareVersion}`
);
// Replace `Updated dependencies` line in other `CHANGELOG.md`s
changelog = changelog.replace(
`- miniflare@${miniflareVersion}`,
`- miniflare@${nextMiniflareVersion}`
);
fs.writeFileSync(changedPath, changelog);
}
}
}
// 4. Update the lockfile
execSync("pnpm install");
}
if (require.main === module) main();