refactor(release): move the version-anchor package.json rewrite into the shared lib
Makes the re-anchor file mutation unit-testable alongside the anchor decision.
This commit is contained in:
@@ -10,12 +10,16 @@ Regression context: v0.73.0 was cut on `release` while `main` stayed in the
|
||||
|
||||
import test from "node:test";
|
||||
import assert from "node:assert/strict";
|
||||
import { mkdtempSync, readFileSync, writeFileSync } from "node:fs";
|
||||
import { tmpdir } from "node:os";
|
||||
import { join } from "node:path";
|
||||
|
||||
import {
|
||||
compareReleaseVersions,
|
||||
evaluateBetaCycleAnchor,
|
||||
isVersionAheadOfStable,
|
||||
latestStableVersionFromTags,
|
||||
setPackageJsonVersions,
|
||||
} from "../lib/release-version-anchor.mjs";
|
||||
|
||||
test("compareReleaseVersions ranks a prerelease below its stable", () => {
|
||||
@@ -82,3 +86,21 @@ test("isVersionAheadOfStable rejects releases at or below the newest stable", ()
|
||||
assert.equal(isVersionAheadOfStable("0.74.0", "0.73.0"), true);
|
||||
assert.equal(isVersionAheadOfStable("0.1.0", null), true);
|
||||
});
|
||||
|
||||
test("setPackageJsonVersions re-anchors only the files that need it", () => {
|
||||
const dir = mkdtempSync(join(tmpdir(), "fusion-anchor-test-"));
|
||||
const root = join(dir, "package.json");
|
||||
const cli = join(dir, "cli.package.json");
|
||||
const missing = join(dir, "nope.package.json");
|
||||
writeFileSync(root, JSON.stringify({ name: "root", version: "0.73.0-beta.6" }, null, 2) + "\n");
|
||||
writeFileSync(cli, JSON.stringify({ name: "cli", version: "0.73.0" }, null, 2) + "\n");
|
||||
|
||||
const rewritten = setPackageJsonVersions([root, cli, missing], "0.73.0");
|
||||
|
||||
// Already-anchored and absent files are left alone; the stale one is rewritten.
|
||||
assert.deepEqual(rewritten, [root]);
|
||||
assert.equal(JSON.parse(readFileSync(root, "utf8")).version, "0.73.0");
|
||||
assert.equal(JSON.parse(readFileSync(cli, "utf8")).version, "0.73.0");
|
||||
// Unrelated fields survive the rewrite.
|
||||
assert.equal(JSON.parse(readFileSync(root, "utf8")).name, "root");
|
||||
});
|
||||
|
||||
@@ -14,6 +14,8 @@ and the dev checkout (`pnpm dev`, dashboard version badge) still reported the
|
||||
last beta.
|
||||
*/
|
||||
|
||||
import { existsSync, readFileSync, writeFileSync } from "node:fs";
|
||||
|
||||
/**
|
||||
* Prerelease-aware semver comparison: returns <0, 0, >0.
|
||||
* `1.2.3-beta.1` sorts BELOW `1.2.3`; numeric prerelease identifiers compare
|
||||
@@ -91,6 +93,27 @@ export function evaluateBetaCycleAnchor({ cycleBase, latestStable }) {
|
||||
return { stale, anchor: stale ? latestStable : cycleBase };
|
||||
}
|
||||
|
||||
/**
|
||||
* Point each package.json at `version`, skipping files already there or absent.
|
||||
* Used to re-anchor the fixed group (plus the workspace root) on the shipped
|
||||
* stable before `changeset pre enter`, which snapshots these versions into
|
||||
* pre.json's `initialVersions` and derives every X.Y.Z-beta.N from them.
|
||||
*
|
||||
* @returns {string[]} the paths actually rewritten, so a dry-run can restore them.
|
||||
*/
|
||||
export function setPackageJsonVersions(paths, version) {
|
||||
const rewritten = [];
|
||||
for (const path of paths) {
|
||||
if (!existsSync(path)) continue;
|
||||
const pkg = JSON.parse(readFileSync(path, "utf8"));
|
||||
if (pkg.version === version) continue;
|
||||
pkg.version = version;
|
||||
writeFileSync(path, JSON.stringify(pkg, null, 2) + "\n");
|
||||
rewritten.push(path);
|
||||
}
|
||||
return rewritten;
|
||||
}
|
||||
|
||||
/**
|
||||
* Backstop applied to both channels: a release must be strictly newer than the
|
||||
* newest published stable. Catches hand-edited pre.json, a back-merge resolved
|
||||
|
||||
@@ -52,6 +52,7 @@ import {
|
||||
evaluateBetaCycleAnchor,
|
||||
isVersionAheadOfStable,
|
||||
latestStableVersionFromTags,
|
||||
setPackageJsonVersions,
|
||||
} from "./lib/release-version-anchor.mjs";
|
||||
import {
|
||||
archivePointerLine,
|
||||
@@ -418,24 +419,12 @@ function readFixedGroupPackageNames() {
|
||||
* Returns the list of rewritten paths so a dry-run can restore them.
|
||||
*/
|
||||
function rewriteFixedGroupVersions(version) {
|
||||
const rewritten = [];
|
||||
const paths = ["package.json"];
|
||||
for (const name of readFixedGroupPackageNames()) {
|
||||
const dir = findPackageDir(name);
|
||||
if (!dir) continue;
|
||||
const pkgPath = join(dir, "package.json");
|
||||
const pkg = JSON.parse(readFileSync(pkgPath, "utf8"));
|
||||
if (pkg.version === version) continue;
|
||||
pkg.version = version;
|
||||
writeFileSync(pkgPath, JSON.stringify(pkg, null, 2) + "\n");
|
||||
rewritten.push(pkgPath);
|
||||
if (dir) paths.push(join(dir, "package.json"));
|
||||
}
|
||||
const rootPkg = JSON.parse(readFileSync("package.json", "utf8"));
|
||||
if (rootPkg.version !== version) {
|
||||
rootPkg.version = version;
|
||||
writeFileSync("package.json", JSON.stringify(rootPkg, null, 2) + "\n");
|
||||
rewritten.push("package.json");
|
||||
}
|
||||
return rewritten;
|
||||
return setPackageJsonVersions(paths, version);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user