Skip to content

Release Checklist ​

A successful package build is not enough. The release is healthy only when every surface agrees on workbook behavior and the compatibility claims still line up with reality.

Glossary: same-revision release

A core release whose WASM, Native Node, Python wheel, and CLI binaries are built from the same Git revision. This keeps a fix consistent across the core bindings. MCP and formulon-cell are separate packages; verify their supported engine dependencies before upgrading them.

Before a release ​

  • [ ] Run core tests (make test-all).
  • [ ] Run primary Oracle verification (make oracle-verify). If a supported variant changed, also configure FORMULON_ORACLE_VARIANTS=ON, build formulon_oracle_variant_tests and formulon_workbook_oracle_variant_tests, and run ctest -L VARIANT.
  • [ ] Check the divergence registry (tools/oracle/.venv/bin/python tools/oracle/divergence_check.py --strict must exit 0). The release bar is zero oracle failures; read the per-cause skip tally it prints before quoting a pass rate.
  • [ ] Require active workbook captures (tools/oracle/.venv/bin/python tools/oracle/workbook_closure_check.py --require-active). The ordinary closure check allows pending captures, so it is not the release gate.
  • [ ] Verify WASM size budgets (make size-check).
  • [ ] Build JavaScript, Python, CLI, and native artifacts from the same revision.
  • [ ] Smoke-test each package surface.
  • [ ] Run make parity-test after staging available package surfaces.
  • [ ] Refresh the homepage demo snapshots with yarn demos:prepare after staging the current core WASM and cell packages from their sibling checkouts; review vendor/manifest.json source commits, source-diff SHA-256 values, and archive SHA-256 values, then run yarn check:demos and a normal homepage build without sibling checkouts.
  • [ ] Run RegistryCatalog.CoverageReport (ctest -R RegistryCatalog.CoverageReport -V from the build directory — diagnostic-only, always passes, reads the coverage percentage from stdout) and update Formula coverage if it changed.
  • [ ] Check Compatibility for stale status claims.
  • [ ] Update changelog and docs version.
  • [ ] After updating docsVersion, regenerate API tables from that core commit with yarn gen:api --ref <core-commit> and run yarn check:api. Keep package dependencies on published versions during preparation.

Why each step ​

StepCatches
make test-allEngine-internal regressions
make oracle-verifyDrift between Formulon and captured Excel values
divergence_check.py --strictAccepted divergences resting on an unverified or stale Excel observation
make size-checkWASM bloat that would slow page loads
Same-revision buildCross-surface drift caused by partial rebuilds
Smoke-test each surfacePackaging or binding-only regressions
make parity-testSurfaces that compute different values for the same input
RegistryCatalog.CoverageReportStale function-count claims in docs
Compatibility audit"Excel-compatible" claims that no longer hold
Changelog and docsUser-facing surprises after upgrade

Package builds do not prove cross-surface agreement

Run the parity check and binding smoke tests before release. They cover agreement between the available channels and host-side translation and lifetime behavior.

Publish and verify ​

  • [ ] After develop CI passes, fast-forward main and wait for main CI to pass. Create an annotated tag (git tag -a vX.Y.Z -m "Release vX.Y.Z"), then push it with git push origin vX.Y.Z. The tag triggers release.yml, which publishes npm and PyPI through trusted publishing and creates the GitHub Release and CLI assets with GitHub workflow credentials.
  • [ ] Check the separate prebuild.yml workflow on the same tag. Its release-bundle job collects the prebuilt addons into a formulon-native-bundle artifact; publishing @libraz/formulon-native to npm is a manual step.
  • [ ] Once the tag exists, rebase the released C ABI baseline onto it (python3 tools/dev/gen_c_abi_baseline.py vX.Y.Z). Later ABI changes are then checked against this release.
  • [ ] Update the homepage's docsVersion to the documented source version. Verify unreleased features with the ignored local snapshots (yarn test:local and yarn build:local). After the core, formulon-cell, and formulon-cell-vue packages are published, update the registry dependency pins, regenerate the lockfile, and rerun tests and the build without local aliases. Confirm the displayed runtime versions and the language-switching demo against the published packages before deploying.
  • [ ] Watch for incoming compatibility issues and route them to the right oracle / profile.
01Work on developRun the pre-releasechecklist02Develop CI passesRequired before main moves03Fast-forward mainPromote develop to main04Main CI passesGate before tagging05Push annotated taggit tag -a vX.Y.Z06release.yml + prebuild.ymlBoth start from the sametag07Verify artifactsPackages, Release, CLI,addons01Work on developRun the pre-release checklist02Develop CI passesRequired before main moves03Fast-forward mainPromote develop to main04Main CI passesGate before tagging05Push annotated taggit tag -a vX.Y.Z06release.yml + prebuild.ymlBoth start from the same tag07Verify artifactsPackages, Release, CLI, addons
The tag is pushed last, after develop and main CI have both passed.
release.yml (tag-triggered)prebuild.yml (same tag)Resultpublish-npmTrusted publishingbuild-cliBuilds CLI binariespython-wheelBuilds Python wheelspublish-pypiTrusted publishingattach-cliAdds CLI to the ReleaseNative Node matrixPrebuilt addons per platformrelease-bundleformulon-native-bundle artifactnpm and PyPI packagesPublished by release.ymlGitHub ReleaseCLI binaries attachedNative Node bundlenpm publish is manualrelease.yml (tag-triggered)prebuild.yml (same tag)Resultpublish-npmTrusted publishingbuild-cliBuilds CLI binariespython-wheelBuilds Python wheelspublish-pypiTrusted publishingattach-cliAdds CLI to the ReleaseNative Node matrixPrebuilt addons per platformrelease-bundleformulon-native-bundle artifactnpm and PyPI packagesPublished by release.ymlGitHub ReleaseCLI binaries attachedNative Node bundlenpm publish is manual
One tag starts both workflows, but publishing the Native Node package to npm remains a manual step.