Releasing
Every release pins one exact version everywhere: the packages, the plugin manifest, core’s VERSION (which homeostat init writes into CI files), and each homeostat@x.y.z in the skills and docs. packages/cli/test/versions.test.ts fails if any of them drift or a floating range such as homeostat@0 comes back.
A team adopts a release by moving the homeostat@x.y.z pin in its KB’s CI file. Developers’ plugins read that pin from their clone and run the same version from their next sync, so nobody has to update the plugin itself; claude plugin update homeostat@homeostat is needed only when the plugin’s own files (hooks, skills) change.
Cutting a release
Section titled “Cutting a release”node scripts/version.mjs 0.2.0pnpm installpnpm checkgit commit -am "chore: release 0.2.0"git tag v0.2.0git push && git push --tagsThe tag starts .github/workflows/release.yml, which:
- checks that the tag matches the version, then runs the full check and
pnpm audit - packs
@homeostat/core,@homeostat/mcp,@homeostat/dashboardandhomeostat; the published packages run the compileddist/, because Node does not strip types insidenode_modules - builds a CycloneDX SBOM from a clean install of those tarballs
- publishes each one with
npm publish --provenancethrough npm trusted publishing (OIDC), so no npm token is stored anywhere - creates a GitHub release with the tarballs and the SBOM attached
One-time setup
Section titled “One-time setup”- Make the repository public. npm only issues provenance for packages built from public repositories.
- Reserve the names: the
homeostatpackage and the@homeostatscope on npm. Turn on 2FA for the npm and GitHub owner accounts. - A brand-new package’s first release cannot use trusted publishing: npm attaches a publisher only to a package that exists. 0.1.0 went out with a one-day granular token that could bypass 2FA, stored as
NPM_TOKENand passed asNODE_AUTH_TOKENto the publish step. That token and secret are gone. Do the same for any new package added later, then remove both again. - Add a trusted publisher for each of the four packages on npmjs.com (package settings → Trusted publisher → GitHub Actions): repository
ysugarmen/homeostat, workflowrelease.yml, environmentnpm. Then delete theNPM_TOKENsecret and revoke the token: from now on releases need no stored credential. - Create the
npmenvironment in the GitHub repository settings, with a required reviewer, so a pushed tag alone cannot publish. - Install Renovate on the repository.
renovate.jsonwaits three days before proposing a new version, andpnpm-workspace.yamlrefuses to install anything newer than three days (minimumReleaseAge).
Checking a release
Section titled “Checking a release”npm view homeostat@<version> --json | jq .dist.attestationsshows the provenance attestation, and the npm package page shows a “Built and signed on GitHub Actions” badge.npm audit signaturesin any project that installs it verifies the registry signatures and attestations.