Files
heygen-com__hyperframes/scripts/set-version.test.ts
T
James Russo 248f640734 feat(docs): add changelog release workflow (#1164)
* 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>
2026-06-02 15:51:16 -07:00

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");
});
});