Publishing
This page is for maintainers who release a package from packages/** to npm. A release bumps the version, commits,
tags <package>@<version>, pushes, creates the GitHub release and publishes to npm. Each package's .release-it.json
drives it.
@frigear-nu/base (a Nuxt layer) and
@frigear-nu/eslint-config (plain ESM).Requirements
- Node.js and pnpm as in Local development.
- Push access to the repository, and a clean working tree (
requireCleanWorkingDiris on). - A package registered for npm trusted publishing.
- From your own machine only:
npm login, since trusted publishing works only in CI, and aGITHUB_TOKENfor release-it's GitHub release.
Release from GitHub Actions
The Release workflow (.github/workflows/release.yml) runs from the Actions tab. It takes three inputs:
| Input | Values | Purpose |
|---|---|---|
package | all or a folder under packages/ | What to release. all releases every package in the workflow's list. |
packages | folders, comma or space separated | Optional. A set such as cli, create-frigear-app. It overrides package. |
increment | major, minor, patch (default), premajor, preminor, prepatch, prerelease | Passed to release-it. |
Every package gets the same increment, in the workflow's dependency order. An unknown name fails the run before anything is versioned.
The jobs run in this order:
- verify builds each package's workspace dependencies and runs its tests, one runner per package, in parallel. Nothing is pushed or published.
- release versions the packages that passed, one at a time, with
scripts/release-package.shand release-it's hooks off. Each pushes a commit and a tag. It then builds them once and publishes up to four at a time withscripts/publish-released.sh.
A failing package does not stop the others, but it fails the run. A version that was tagged but never reached npm is published by the next run, without a new version. Only one release runs at a time.
Release from your machine
Run from the repository root. pnpm exec runs in the package folder, where release-it finds .release-it.json:
pnpm install
pnpm --filter ./packages/<your-package> exec release-it <patch|minor|major|premajor|preminor|prepatch|prerelease>
The config builds after the bump (after:bump). Once the GitHub release exists, it runs scripts/npm-publish.sh
(after:release).
If the release fails on authentication, the version commit and tag are already pushed. Resume only the npm publish:
pnpm --filter ./packages/<your-package> exec bash ../../scripts/npm-publish.sh
release npm script. It is left over from the module starter (changelogen and npm publish).Trusted publishing
Publishing uses npm trusted publishing (OIDC, OpenID Connect), so no npm
token is stored. The workflow's release job has id-token: write to mint the token. Each package registers the
repository and the release.yml workflow as its trusted publisher on npmjs.com.
scripts/npm-publish.sh packs the package with pnpm pack, which turns workspace:^ dependencies into caret ranges
such as ^0.2.1. Exact versions would make consumers install two copies of a shared package. It then publishes the
tarball with npm publish --access public. It uses npm because pnpm does not implement trusted publishing yet.
Add a new package
Give it a release config
Copy a sibling's .release-it.json and change the package name and tag.
Add it to the workflow
Add the folder to the package choices and to the ALL list in the prepare job of release.yml. Keep the two in
sync.
Publish it once by hand
npm allows trusted publishing only on a package that exists. After merging, a maintainer publishes it once from an up
to date main, with npm login and two-factor authentication in the browser:
bash scripts/first-publish.sh <package>
It publishes the current version unless npm already has it, then runs npm trust github for release.yml. From then
on, the Release workflow publishes it.
Next steps
- Starters – a starter that waits for this release can now be merged.
Access control
Declare a module's permissions, scopes and roles with defineAccess, register them with registerAccess, add role requirements and policies, and test them with a role provider in a fixture.
Starters
Maintain the starters in .starters/, keep their shared files identical and regenerate their migrations.