Skip to content

Package Tag Release Process

Cursor Agent edited this page Jun 16, 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-v34-v0.0.2
  • Prefix: configured package from scripts/packages.ts (ocpOpenCapTable-v34 today).
  • Suffix -v<semver> must match OpenCapTable-v34/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-v34-v0.0.2).

Concurrency is per tag; overlapping runs for the same tag are serialized.

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 — root package.json version must not already exist on npm.
  5. Validate tag at origin/main — release tag commit must equal current origin/main (refuses stale tags).
  6. Build and validate:
    • npm run build
    • npm run backup-dar -- --package <key> --version <version>
    • 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 — devnet, then mainnet (npm run upload-dar).
  8. Detect factory statescripts/detect-factory-need.ts (reads generated/ocp-factory-contract-id.json).
  9. Create missing factoriesscripts/create-ocp-factory.ts per network that lacks a factory for the current DAR package ID.
  10. Verify DAR backupsnpm run verify-dars.
  11. Prepare npm artifactsnpm run package:manifest.
  12. Publish npmnpm publish.
  13. Commit artifacts to main[skip ci] commit when origin/main is still the tag commit.

Artifacts committed back to main

When changed, the workflow commits:

  • dars/ (and dars.lock via backup step)
  • 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

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-v34-v0.0.2
npm run build && npm run test

After the workflow: confirm dars/dars.lock, any new dars/ rows, and generated/ocp-factory-contract-id.json were committed when expected.

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