This repository uses semantic-release for tag-derived versions and GitHub Release notes. Normal publication does not modify or commit repository files.
Release policy and stable-graduation criteria live in SemVer And Release Posture. The exact current version is the latest immutable GitHub Release tag.
commit S passes every required CI job
|
v
semantic-release derives version V from real tags + Conventional Commits
|
v
build and validate one deterministic Haxelib ZIP from S
|
v
create immutable tag vV at S
|
v
publish ZIP + checksum and verify hosted SHA-256
The tag identifies the exact commit that passed CI. There is no generated release commit, no release-time changelog commit, and no tracked patch-version synchronization step.
The release job is the final job in .github/workflows/ci.yml and runs only for a push to main.
It depends on the required security, Rust, Windows, harness, performance, and stdlib jobs from the
same workflow run, checks out ${{ github.sha }}, and alone receives contents: write.
The dependency audit fails on every finding except a short-lived list of exact advisory URLs under
the installed but unused @semantic-release/npm plugin. The project does not configure npm package
publication. The exception also requires the exact unused dependency paths, rejects critical or new
findings, and expires on 2026-09-30 so an available upstream npm fix replaces it instead of silently
turning into permanent policy.
Normal publication has no workflow_dispatch entry point. Manual operation is isolated in
.github/workflows/release-repair.yml, which accepts only an existing vMAJOR.MINOR.PATCH tag and
cannot derive, create, move, or delete a version tag.
release-manifest.json contains policy only:
- major zero is
initial-development, - breaking commits on ungraduated
0.xproduce the next minor release, - every stable major owns its own durable approval record,
- missing or unapproved stable majors fail closed,
- prerelease channels and build metadata are rejected until explicitly modeled.
scripts/release/semantic-release-policy.cjs delegates Conventional Commit parsing to the pinned
official analyzer and applies only that project policy. Exact release versions use the small
source-owned SemVer 2.0.0 syntax parser in scripts/release/semantic-version.js; it performs no range
selection and keeps package bytes independent of executable validation code in node_modules.
A repository adopting this policy without existing version tags must establish and review an
initial major-zero baseline tag (normally v0.0.0) before enabling automatic publication.
semantic-release otherwise treats its first release as 1.0.0, which this manifest correctly
rejects while stable major one remains unapproved.
Tracked metadata intentionally describes a development checkout:
package.json/package-lock.json:0.0.0-development,haxelib.json:0.0.0,haxe_libraries/reflaxe.rust.hxml:0.0.0-development.
Those values never determine a release. Real tags determine the exact version. During artifact
staging, scripts/release/prepare-package-metadata.js writes the derived version and release note
into the copied haxelib.json and adds release-metadata.json with the version, tag, and source
commit SHA. The tracked working tree must remain unchanged.
Git installs remain pinned by tag. Packaged Haxelib installs receive the exact staged package version. Code should treat the source-checkout HXML version as a development sentinel rather than a published-version oracle.
scripts/release/package-haxelib.sh still delegates generic Haxelib layout work to vendored
Reflaxe, then adds the target-specific runtime/ and vendor/ trees. It finishes with the pinned
pure-JavaScript deterministic ZIP writer rather than system zip.
The release adapter:
- starts only after an externally loaded Git-object bootstrap has rechecked every tracked source byte,
- builds the complete package twice from literal blobs in different temporary environments,
- requires byte-identical ZIPs,
- validates central-directory names, order, modes, compression, and path safety,
- validates required compiler/runtime/vendor entries and staged metadata,
- validates the shipped licenses, third-party notice, CycloneDX inventory, and exact vendored Reflaxe base/patch record,
- runs the existing Haxelib install, Haxe compile, and Cargo build smoke against that exact ZIP,
- writes its SHA-256 sidecar,
- verifies local and remote tag identity before upload,
- records the approved archive/checksum names, lengths, and digests in a process-local receipt that cannot be replaced by another mutable repository file,
- lets the reviewed project plugin—not a general publisher—create the draft and upload only copies that still match that receipt,
- verifies hosted asset names, states, sizes, and SHA-256 digests against the captured receipt after publication.
See docs/release-licensing-review.md for the factual package inventory and
the questions that still require professional legal review before 1.0.
The local paths are fixed (dist/reflaxe.rust.zip and .zip.sha256) to prevent stale globs. The
reviewed publication plugin gives them versioned hosted names. No third-party publisher receives the
mutable local artifact paths after approval.
GitHub Release notes generated from Conventional Commits are canonical beginning after v0.81.3.
CHANGELOG.md is preserved as historical material through that predecessor release; it is no
longer mutated during publication. Durable policy docs and the dynamic latest-release badge also do
not change on every patch release.
Known immutable-history note: v0.81.4 through v0.85.0 were published with correct tags and
artifacts but heading-only release bodies because an incompatible explicit writer preset was not
covered by an end-to-end notes assertion. Published releases remain immutable, so those bodies are
not rewritten. Their tag comparisons still expose the exact commit history. The configured notes
generator is now exercised by npm run test:release-notes, including feature, fix, performance,
scoped, bang-header, and breaking-footer cases. Live recovery was proven by immutable v0.85.1,
whose hosted body includes both release-relevant fixes from the corrected tag range.
After removing the release commit, only one expected external partial state remains: a valid remote tag exists while its GitHub Release is absent or still draft.
Run the protected Repair Existing Release workflow with that exact tag. Its command:
- checks out and verifies the supplied local/remote tag identity,
- re-derives no version and creates no tag,
- rebuilds the deterministic package twice from the tag,
- runs the complete exact-artifact contract and smoke,
- captures a fresh approval receipt after smoke and checks the versioned upload copies against it,
- creates or cleans only the associated draft Release,
- uploads the approved ZIP/checksum, publishes the draft, and verifies immutable hosted digests against that receipt rather than recomputing approval from mutable local files.
If the Release is already complete and immutable, repair is a non-mutating verification. If a published release or remote tag contains invalid content, never move/delete the remote tag or reuse the version; treat it as an incident and issue a corrective version.
Future releases must use GitHub release immutability so a published tag and assets cannot change.
Version-tag rules should prevent updates/deletions and restrict creation to the release authority.
These host settings are part of the release contract, not facts that source tests can enforce by
themselves. A maintainer with repository-administration read access can audit them with
node scripts/release/verify-host-controls.js OWNER/REPOSITORY; the short-lived publication token
cannot read the repository-administration endpoint. Normal release and repair therefore run
node scripts/release/verify-host-tag-controls.js OWNER/REPOSITORY immediately before publication,
using the public ruleset API to prove that version tags cannot be updated or deleted. The
post-publication verifier separately requires the hosted Release itself to report immutable. This
split keeps both checks fail-closed within the authority GitHub actually gives each credential.
This personal repository currently enforces version-tag update/deletion protection and creates tags
with the same-run GITHUB_TOKEN; it does not configure a separate long-lived release credential.
An adopter with multiple writers should add a dedicated GitHub App or equivalent release identity
and a tag-creation rule that allows only that identity. Do not weaken update/deletion protection to
make normal publication convenient.
Use the supported Node 22.14.x toolchain (CI pins 22.14.0). rust-toolchain.toml selects the
tested Rust minimum for ordinary repository checks; release and repair workflows explicitly
activate the exact release patch from Rust Toolchain Policy.
The compiler package does not ship one universal application Cargo.lock: generated applications
own and commit their reviewed lock, then use -D rust_cargo_locked for CI and release builds.
Resolver 3 guides first resolution toward the declared floor; the app lock makes that selection
reproducible.
npm run guard:release-policy
npm run test:release
npm run test:package-smoke
GITHUB_TOKEN="$(gh auth token)" npx semantic-release --dry-runFor reusable invariants and sibling adaptation guidance, see Release And SemVer Reference Architecture.