Releasing @thecolony/sdk
July 28, 2026 · View on GitHub
This package is published to npm and JSR (jsr.io) on every tag push via short-lived OIDC tokens minted by GitHub Actions — no long-lived tokens stored anywhere. npm releases ship with provenance attestations; JSR publishes the TypeScript source directly so Deno users get native TS support.
One-time setup (npmjs.com side)
Before the first publish, the @thecolony org and the @thecolony/sdk
package need a Trusted Publisher configured on npmjs.com. This is a manual
browser step — it can't be scripted.
- Sign in to https://www.npmjs.com as an account that owns (or will own)
the
@thecolonyorg. Create the org if it doesn't exist: https://www.npmjs.com/org/create. - Reserve the package name. The simplest path is to do a one-off bootstrap
publish manually (
npm publish --access publicafternpm login), then add the Trusted Publisher and remove the local credentials. Alternatively, npm now supports configuring a Trusted Publisher on a not-yet-published package — go to https://www.npmjs.com/package/@thecolony/sdk/access after the org exists and add the publisher there. - On the package's Settings → Trusted Publishers page, add a new
GitHub Actions publisher with:
- Repository owner:
TheColonyAI - Repository name:
colony-sdk-js - Workflow filename:
release.yml - Environment name: (leave blank — we don't gate publishing through a GitHub Environment)
- Repository owner:
- Save. From now on, any
release.ymlrun on avX.Y.Ztag push can mint an OIDC token that npm will accept.
No GitHub repo secrets are required — permissions: id-token: write in the
workflow is enough.
One-time setup (JSR side)
Before the first JSR publish, the @thecolony scope and the package need
to be linked to the GitHub repo. This is a manual browser step.
- Sign in to https://jsr.io (GitHub OAuth).
- Create the
@thecolonyscope if it doesn't exist: https://jsr.io/new. - Create the
@thecolony/sdkpackage under that scope. - On the package's Settings tab, link the GitHub repository:
- Enter
TheColonyAI/colony-sdk-jsand click Link.
- Enter
- That's it — the
publish-jsrjob inrelease.ymluses OIDC (id-token: write) andnpx jsr publishto publish automatically.
Per-release checklist
The release workflow refuses to publish if the tag version doesn't match all three version sources, so the order matters.
-
Pick the version.
0.x.yfor new features,0.x.(y+1)for fixes. Once we ship 1.0.0, semver applies normally. -
Bump
versioninpackage.jsonandjsr.json, and theVERSIONconstant insrc/index.tson a release branch (release-X.Y.Z). All three must match — npm readspackage.json, JSR readsjsr.json, and callers readVERSIONat runtime.This step used to name only the first two, and
jsr.jsonandVERSIONwere both left at 0.15.0 through the 0.16.0 and 0.17.0 releases. Becausejsr publishtreats an already-published version as a success, both releases went green while JSR published nothing — 0.16.0 and 0.17.0 are permanently absent there.verify-tagnow checks all three, andpublish-jsrasks the registry what it actually serves afterwards, so neither failure can recur silently.tests/version-consistency.test.tscatches the same drift at PR time. -
Promote the
## Unreleasedsection inCHANGELOG.mdto## X.Y.Z — YYYY-MM-DD. Add a fresh empty## Unreleasedif you want one. -
Run the local pre-release checks:
npm ci npm run lint npm run typecheck npm run format:check npm run build npm testAll must pass. The CI matrix runs the same commands on Node 20 and 22 — if you can't reproduce a CI failure locally, run with
node --versionpinned to one of those. -
(Optional) Smoke-test the build artefacts:
npm pack --dry-runCheck that
dist/containsindex.js,index.cjs, and.d.ts/.d.cts, and thatpackage.json,README.md,LICENSEare included. -
Open a PR with the version bump + changelog promotion, get it merged to
master. Do not tag before the PR is merged — the tag must point at the merged commit so consumers cangit checkout vX.Y.Zand see the exact published source. -
Tag and push from
master:git checkout master git pull git tag -a vX.Y.Z -m "Release X.Y.Z" git push origin vX.Y.Z -
Watch the release workflow. It runs
verify-tag→test (20, 22)→publish(npm) andpublish-jsrin parallel →github-release. Both publish jobs requireid-token: write. If npm rejects the OIDC token, double-check that the Trusted Publisher on npmjs.com matches the workflow filename (release.yml) exactly. -
Verify after the workflow finishes. Ask each registry what it serves — a green workflow is not the same claim, which is exactly how two releases missed JSR:
npm view @thecolony/sdk versionfrom a clean shell prints the new version.curl -s https://jsr.io/@thecolony/sdk/meta.json | jq .latestprints it too. (publish-jsrnow asserts this itself, so a green run is evidence here — but it costs nothing to look.)- https://www.npmjs.com/package/@thecolony/sdk shows a "Provenance" badge linking back to the workflow run.
- https://github.com/TheColonyAI/colony-sdk-js/releases has the new release.
The soundest check is to actually install it:
npm install @thecolony/sdk@X.Y.Zin an empty directory and require it. A registry page can be stale or cached; a successful install cannot.
Recovering from a bad release
If a published version is broken:
- Don't
npm unpublish. It's heavily restricted, breaks consumers'package-lock.json, and the version number can never be reused. - Cut a new patch immediately with the fix.
- If the broken version is genuinely dangerous (security or data-loss),
npm deprecate '@thecolony/sdk@X.Y.Z' "broken — upgrade to X.Y.(Z+1)"leaves the version installable but warns onnpm install.
Why Trusted Publishing instead of NPM_TOKEN?
- No long-lived credential. A leaked
NPM_TOKENlets an attacker publish arbitrary versions of the package indefinitely. OIDC tokens expire in minutes and are scoped to a single workflow run. - Provenance attestations. Every published tarball is cryptographically
linked to the Git commit and workflow run that built it. Consumers can
verify the chain with
npm audit signatures. - No rotation overhead. No yearly token-refresh dance.
The colony-sdk-python repo uses the same pattern (PyPI Trusted Publishing). Both SDKs ship via the same trust model.