Releasing
How a new version of @koed_jang/apyx-sdk ends up on npm.
# 1. bump
pnpm version 0.1.0-prototype.1 --no-git-tag-version
git commit -am "release: 0.1.0-prototype.1"
# 2. tag and push
git tag v0.1.0-prototype.1
git push --follow-tags
GitHub Actions (.github/workflows/release.yml) does the rest.
- Versioning policy
- Tag format
- What CI does on tag push
- Why no
--provenance - Pre-flight checklist
- After publishing
- First-publish gotcha — spurious
latesttag - Cadence
- Related
Versioning policy
| Stage | Version pattern | npm dist-tag |
|---|---|---|
| Prototype (current) | 0.1.0-prototype.N | prototype |
| Stable (future) | 0.X.Y (no suffix) | latest |
| Future pre-releases | -rc.N / -beta.N / -alpha.N | rc / beta / alpha |
The release workflow derives the dist-tag from the version itself:
if [[ "$VERSION" == *-prototype* ]]; then TAG=prototype
elif [[ "$VERSION" == *-rc* ]]; then TAG=rc
elif [[ "$VERSION" == *-beta* ]]; then TAG=beta
elif [[ "$VERSION" == *-alpha* ]]; then TAG=alpha
else TAG=latest
fi
So the rule is simple: pick the right -suffix.N and CI picks the
right tag. Never publish a prototype to latest and consumers can’t
accidentally pin to it via pnpm add @koed_jang/apyx-sdk (no suffix).
Tag format
Tags are v<version> — v0.1.0-prototype.0, v0.1.0, etc. The
release workflow triggers on v*, so any pushed tag matching that
pattern publishes.
What CI does on tag push
release.yml (linked):
actions/checkout@v4at the tag’s commit.pnpm/action-setup@v4(pnpm 9),actions/setup-node@v4(Node 20) withregistry-url: https://registry.npmjs.org.pnpm install --frozen-lockfile.pnpm build— Rollup bundles + tsc declarations.- Derive the dist-tag (script above).
pnpm publish --no-git-checks --tag <derived>withNODE_AUTH_TOKEN = secrets.NPM_TOKEN.
The --no-git-checks flag is required because the GitHub Actions
checkout is a detached HEAD with no remote tracking branch — pnpm
otherwise refuses to publish.
Why no --provenance
npm’s sigstore-backed --provenance flag requires a public source
repo so the resulting attestation can be verified back to the
build. The current dev repo is private, so --provenance would
fail at publish time. Once the source forks back to a public
apyx-labs/sdk, re-add --provenance to release.yml.
Pre-flight checklist
Before pushing the tag:
-
pnpm test— unit suite green. -
pnpm typecheck— no errors. -
pnpm build— bundles emit cleanly. -
pnpm test:e2eor wait for CI to run the equivalent on the release commit before tagging. -
pnpm pack --dry-run— inspect what’s about to ship. - Bump in
package.json,pnpm installto refresh the lockfile, commit. - Tag and push:
git tag v<version> && git push --follow-tags.
CI runs the same checks on the tag commit, so a green local run is a strong predictor that the publish will succeed.
After publishing
Verify on npm:
pnpm view @koed_jang/apyx-sdk versions
pnpm view @koed_jang/apyx-sdk dist-tags
Smoke-test from a fresh directory:
mkdir /tmp/apyx-smoke && cd /tmp/apyx-smoke
pnpm init -y
pnpm add @koed_jang/apyx-sdk@prototype viem
pnpm exec apyx --version
A successful apyx --version with the version you just published
confirms the install + bin paths end-to-end.
First-publish gotcha — spurious latest tag
The very first pnpm publish --tag prototype for a brand-new package
also seeds latest to the same version (npm’s default behavior — the
package needs a latest to be installable). On a prototype-first
workflow, this is wrong — consumers should be forced to opt in
via the prototype tag.
Once-per-package fix, run by a maintainer locally:
npm dist-tag rm @koed_jang/apyx-sdk latest
After this, pnpm add @koed_jang/apyx-sdk (no tag) fails with
No matching version found for @koed_jang/apyx-sdk@* — exactly what
we want until a stable release.
Cadence
- Prototype releases — as needed; expected weekly during active dev.
- Stable
0.1.0— gated on the protocol team confirming the public API surface. No date.
Related
- Repo layout — where the publish artifacts come from.
- Build and test — what
pnpm buildproduces. - Install — how consumers install whatever you just published.