fix: resume replacement release drafts after reserving versions

This commit is contained in:
tianma-if committed 2026-10-13 18:29:39 +08:00
1 parent 30a4ab08ca
commit a05e4f8d39
2 files changed
+29 -1

No files matched your search

+11 -1
View File
@@ -313,7 +313,17 @@ export const resolveReleaseVersion = ({
}
if (draftCandidate.targetCommitish === headSha) {
if (packageVersion !== expectedNextVersion) {
const expectedParts = expectedNextVersion.split(".").map(Number);
const packageParts = packageVersion.split(".").map(Number);
const bumpIndex = { major: 0, minor: 1, patch: 2 }[bump];
// Replacement Drafts reserve prior failed versions. They remain resumable
// when repeated bumps at the explicitly requested level reach this version.
const compatibleVersion = packageParts.length === 3 && packageParts.every((part, index) =>
Number.isInteger(part) && (index === bumpIndex
? part >= expectedParts[index]
: part === expectedParts[index])
);
if (!compatibleVersion) {
throw new Error(
`${draftCandidate.tagName} cannot resume because --bump ${bump} expects v${expectedNextVersion}.`,
);
+18
View File
@@ -406,6 +406,24 @@ describe("release automation", () => {
});
});
test("resumes replacement Drafts after earlier version numbers were reserved", () => {
for (const [bump, packageVersion] of [["patch", "1.17.2"], ["minor", "1.19.0"], ["major", "3.0.0"]]) {
const draftCandidate = {
tagName: `v${packageVersion}`, isDraft: true, isPrerelease: false,
targetCommitish: "current-head",
};
expect(resolveReleaseVersion({
previousVersion: "1.17.0", packageVersion, bump,
headSha: "current-head", draftCandidate,
})).toMatchObject({ releaseVersion: packageVersion, resumedDraft: draftCandidate, releaseBaseTag: "v1.17.0" });
}
expect(() => resolveReleaseVersion({
previousVersion: "1.17.0", packageVersion: "1.19.0", bump: "patch",
headSha: "current-head",
draftCandidate: { tagName: "v1.19.0", isDraft: true, isPrerelease: false, targetCommitish: "current-head" },
})).toThrow("cannot resume");
});
test("reserves a withdrawn Draft version and keeps the published audit baseline", () => {
const draftCandidate = {
tagName: "v1.17.1",