mirror of
https://github.com/heygen-com/hyperframes.git
synced 2026-09-14 18:01:20 +08:00
248f640734
* feat(docs): add changelog release workflow * fix(scripts): resolve CodeQL findings in release scripts - draft-changelog.ts: replace existsSync+writeFileSync check-then-act with an atomic exclusive-write flag (flag: wx) to fix the js/file-system-race TOCTOU finding; overwrite only under --force (flag: w). - set-version.ts: switch execSync shell-string git calls to execFileSync with argument arrays so the interpolated version/paths can never be interpreted by a shell, resolving the js/indirect-command-line-injection findings. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(scripts): lower writeReleaseNotes complexity below CRAP threshold The exclusive-write fix pushed writeReleaseNotes to cyclomatic 5 / CRAP 30.0 (fallow/high-crap-score, threshold 30.0). The '!force' guard in the catch is redundant — EEXIST is only reachable under the 'wx' flag (force=false), since 'w' overwrites without throwing. Dropping it returns the function to cyclomatic 4 / CRAP 20 with identical behavior. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> * fix(docs): address changelog review feedback --------- Co-authored-by: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
76 lines
1.9 KiB
TypeScript
76 lines
1.9 KiB
TypeScript
import assert from "node:assert/strict";
|
|
import { describe, it } from "node:test";
|
|
import {
|
|
changelogArtifacts,
|
|
gitStatusPath,
|
|
isPrerelease,
|
|
parseReleaseOptions,
|
|
releaseRequiresChangelog,
|
|
} from "./set-version.ts";
|
|
|
|
describe("set-version release options", () => {
|
|
it("parses stable release flags", () => {
|
|
assert.deepEqual(parseReleaseOptions(["1.2.3", "--no-tag", "--skip-changelog-check"]), {
|
|
version: "1.2.3",
|
|
skipTag: true,
|
|
skipChangelogCheck: true,
|
|
});
|
|
});
|
|
|
|
it("requires reviewed changelog artifacts for stable tagged releases", () => {
|
|
assert.equal(
|
|
releaseRequiresChangelog({
|
|
version: "1.2.3",
|
|
skipTag: false,
|
|
skipChangelogCheck: false,
|
|
}),
|
|
true,
|
|
);
|
|
});
|
|
|
|
it("does not require changelog artifacts for prereleases, no-tag bumps, or emergency skips", () => {
|
|
assert.equal(isPrerelease("1.2.3-alpha.1"), true);
|
|
assert.equal(
|
|
releaseRequiresChangelog({
|
|
version: "1.2.3-alpha.1",
|
|
skipTag: false,
|
|
skipChangelogCheck: false,
|
|
}),
|
|
false,
|
|
);
|
|
assert.equal(
|
|
releaseRequiresChangelog({
|
|
version: "1.2.3",
|
|
skipTag: true,
|
|
skipChangelogCheck: false,
|
|
}),
|
|
false,
|
|
);
|
|
assert.equal(
|
|
releaseRequiresChangelog({
|
|
version: "1.2.3",
|
|
skipTag: false,
|
|
skipChangelogCheck: true,
|
|
}),
|
|
false,
|
|
);
|
|
});
|
|
|
|
it("tracks both GitHub release and docs changelog artifacts", () => {
|
|
assert.deepEqual(changelogArtifacts("1.2.3"), [
|
|
"releases/v1.2.3.md",
|
|
"docs/changelog.mdx#HyperFrames v1.2.3",
|
|
]);
|
|
});
|
|
});
|
|
|
|
describe("git status parsing", () => {
|
|
it("extracts unquoted porcelain paths", () => {
|
|
assert.equal(gitStatusPath(" M docs/changelog.mdx"), "docs/changelog.mdx");
|
|
});
|
|
|
|
it("extracts quoted porcelain paths", () => {
|
|
assert.equal(gitStatusPath('?? "releases/v1.2.3.md"'), "releases/v1.2.3.md");
|
|
});
|
|
});
|