Releases are cut from main by a maintainer via GitHub Actions. Canary builds ship automatically.
ci.yml+publish.ymlrun in parallel.publish.yml → qualityruns lint / typecheck / build / test.publish.yml → canarypacks the library and publishes as@vllnt/ui@{version}-canary.{short-sha}to the public npm registry with signed provenance.
Consume the latest canary locally:
pnpm add @vllnt/ui@canaryThe release workflow does not push commits to main. Version bumps land via normal PRs so branch protection stays in effect and no PAT / bypass is required.
Open a PR that:
- Updates
packages/ui/package.json"version"to the new target (follow SemVer — see below). - Updates
apps/registry/package.json"version"to match. - Moves the matching entry in root
CHANGELOG.mdandpackages/ui/CHANGELOG.mdfrom[Unreleased]to a dated[x.y.z]section. RootCHANGELOG.mdis the source used for the website, feeds, and GitHub Release notes. - Syncs docs that name a count or version: component count in
README.md+packages/ui/README.md, thepackages/ui/package.json"description",docs/ARCHITECTURE.md, and the ROADMAP status line. The count isregistry.items.length;apps/registry/lib/component-count.test.tsguards the enforced surfaces (changelog snapshot, home copy, PWA manifest).
Do not touch PUBLISHED_VERSION in apps/registry/scripts/inline-component-source.ts here — that pins the shadcn install target and must only advance after the new version is live on npm latest (see step 3). Bumping it before publish makes the deployed registry advertise @vllnt/ui@^{x.y.z} while npm latest is still the previous version, breaking npx shadcn add.
Merge the PR normally. The canary workflow on main will immediately publish @vllnt/ui@{x.y.z}-canary.{sha} — a dress-rehearsal of the release tarball.
Go to Actions → Publish → Run workflow on main. No inputs.
CI will:
- Run quality gates (lint / typecheck / build / test).
- Read the version from
packages/ui/package.json. Fails fast if a matchingv{x.y.z}tag already exists — catches dispatches against stale main. - Read the
CHANGELOG.mdsection for the package version and use it as the GitHub Release notes. - Push an annotated tag
v{x.y.z}(tags are not blocked by branch protection;GITHUB_TOKENis sufficient). pnpm packandnpx --yes npm@latest publish --tag latest --provenance --access public. OIDC trusted publishing signs the provenance attestation.- Create the GitHub Release for the new tag.
Once @vllnt/ui@{x.y.z} is live on npm latest, open a small follow-up PR that:
- Sets
PUBLISHED_VERSIONinapps/registry/scripts/inline-component-source.tsto{x.y.z}. - Runs
pnpm -F @vllnt/ui-registry registry:buildand commits the regeneratedregistry.json+registry/defaultshims (the install target becomes@vllnt/ui@^{x.y.z}and item versions update).
The registry:check and registry:integrity CI guards confirm the regenerated registry is in sync and pins a real (non-prerelease) published version. Until this lands, npx shadcn add keeps resolving to the previous published version — harmless, just one release behind.
- SemVer. Track API compatibility, not surface area — adding 50 new components is a minor bump if no existing exports break.
- A change is major only if any of the following break: exported component names, prop signatures of shipped components, CSS-variable contract, CVA variant keys.
CHANGELOG.mdhas an[Unreleased]section describing user-facing changes. Usecliff.tomlwith git-cliff if you need to regenerate it from Conventional Commits.- The canary built from the same commit passes and lists the expected components (check logs for the tarball manifest).
- Docs are in sync: component count in
README.md, family tables inpackages/ui/README.md, domain references (ui.vllnt.com/storybook.vllnt.ai).
- The new version appears on https://www.npmjs.com/package/@vllnt/ui.
- The GitHub Release page exists under https://github.com/vllnt/ui/releases.
- The sigstore provenance entry is visible in the "Provenance" tab on npmjs and via the transparency log URL in the workflow output.
pnpm add @vllnt/ui@latestin a fresh scratch repo resolves to the new version.
If a release needs to be withdrawn:
npm deprecate @vllnt/ui@{bad-version} "reason"— leaves the version installed for existing users but hides it fromlatest.- Publish a patch bump with the fix. Do not unpublish unless legally required; unpublishing 72h+ after publish is disallowed by npm and breaks downstream users.