Skip to content

Package Tag Release Process

HardlyDifficult edited this page Jul 13, 2026 · 8 revisions

Package Tag Release Process

Canonical runbook for production releases of OpenCapTable and the @fairmint/open-captable-protocol-daml-js npm package.

Tag format

OpenCapTable-v35-v0.0.1
  • Prefix: configured package from scripts/packages.ts (ocpOpenCapTable-v35 today).
  • Suffix -v<semver> must match OpenCapTable-v35/daml.yaml.
  • Root package.json version must be bumped before tagging when a new npm publication is expected.

Triggers

  • Push tag matching OpenCapTable-v*-v* → runs .github/workflows/release.yml.
  • Manual: GitHub Actions → Package Tag ReleaseRun workflow → set release_tag (e.g. OpenCapTable-v35-v0.0.1).

All OCP release runs share one package-level concurrency group, so different candidate versions cannot deploy concurrently.

Toolchain (CI)

Matches release.yml:

  • Node 20, npm 11.10.0
  • Java 23 (Temurin)
  • DAML SDK via dpm (version from package daml.yaml)
  • Git LFS (checkout + git lfs pull)

Workflow steps

  1. Checkout tag (or workflow_dispatch input), with LFS and submodules.
  2. Parse tagscripts/parse-release-tag.ts → package key, source dir, version.
  3. Validate release secrets (Canton OAuth + NPM_TOKEN for npm publish).
  4. Validate npm version — a new release requires an unpublished root package.json version. A retry may resume an already-published version only when both exact deployment success tags already exist.
  5. Validate tag at origin/main — release tag commit must equal current origin/main (refuses stale tags).
  6. Build and validate:
    • npm run build
    • verify the tag-anchored DAR version policy and require the build to match the committed backup
    • npm run lint
    • npm run format
    • npm run lint:daml
    • npm run check-upgrade-compat
    • npm run codegen
    • npm run verify-package
    • npm run test
  7. Upload DAR to DevNet — skip only when the exact success tag already exists; after every configured provider succeeds, create dar-deploy/devnet/<package>/v<version>.
  8. Upload DAR to Mainnet — require the same-version DevNet tag and exact locked hash; after every provider succeeds, create dar-deploy/mainnet/<package>/v<version>.
  9. Detect factory statescripts/detect-factory-need.ts (reads generated/ocp-factory-contract-id.json).
  10. Create missing factoriesscripts/create-ocp-factory.ts per network that lacks a factory for the current DAR package ID.
  11. Verify DAR backupsnpm run verify-dars.
  12. Prepare npm artifactsnpm run package:manifest.
  13. Publish npmnpm publish.
  14. Commit non-DAR generated artifacts to main[skip ci] commit when origin/main is still the tag commit. The workflow fails if release execution changed dars/.

The repository's Immutable DAR deployment tags ruleset allows each success tag to be created once and rejects later updates or deletion.

Artifacts committed back to main

When changed, the workflow commits:

  • generated/ocp-factory-contract-id.json (+ .d.ts)
  • generated/npm-manifest.txt
  • package.json
  • CHANGELOG.md

Commit message: chore: record release artifacts for ${RELEASE_TAG} [skip ci].

npm authentication

Workflow Auth Notes
release.yml (canonical) NPM_TOKEN secret + id-token: write Validates NODE_AUTH_TOKEN from NPM_TOKEN before publish
publish.yml (legacy) npm trusted publishing via GitHub Actions OIDC No NPM_TOKEN; requires id-token: write and a trusted publisher configured on npmjs.com for this repo

For npm provenance, root package.json repository.url must be https://github.com/Fairmint/open-captable-protocol-daml (HTTPS, capital Fairmint, no git+ prefix).

Required GitHub secrets

Applies to release.yml only (Canton upload + npm publish). publish.yml does not use these npm/Canton release secrets.

CANTON_DEVNET_INTELLECT_LEDGER_JSON_API_CLIENT_SECRET
CANTON_DEVNET_5N_LEDGER_JSON_API_CLIENT_SECRET
CANTON_MAINNET_INTELLECT_LEDGER_JSON_API_CLIENT_SECRET
CANTON_MAINNET_5N_LEDGER_JSON_API_CLIENT_SECRET
NPM_TOKEN

Topology is committed in scripts/config/cantonPublic.ts; secrets supply OAuth client secrets only. Generic DEVNET_AUTH_TOKEN / MAINNET_AUTH_TOKEN are not sufficient (upload targets both Intellect and 5n).

Pre-release checklist (local)

Use Node 20 when running locally:

node --version
npx tsx scripts/parse-release-tag.ts OpenCapTable-v35-v0.0.1
npm run build && npm run test

Before the workflow, confirm the candidate DAR and dars.lock are committed. Afterward, confirm both deployment success tags and any expected generated/ocp-factory-contract-id.json update.

Relationship to publish.yml

release.yml publish.yml
Status Canonical production path Legacy
Trigger Package-scoped tag or manual dispatch Every main push
npm auth NPM_TOKEN + OIDC (id-token: write) Trusted publishing (OIDC only; no NPM_TOKEN)
DAR upload Yes (devnet + mainnet) No
Factory creation Yes No
npm publish Yes Yes (prepare-release + publish)
Git tag You push the package-scoped tag Creates v$VERSION on main merge
Artifacts to main Commits DARs, factory JSON, manifest, etc. No

New releases should use package-scoped tags and release.yml only. publish.yml remains for backward compatibility but does not deploy on-chain.

Clone this wiki locally