# Releasing

Publishing is tag-triggered by `.gitea/workflows/publish.yml`. The workflow
runs clean install, unit/integration tests, typecheck, validates that the `v*`
tag exactly matches `package.json`, and inspects the packed contents before
publishing with the pinned pnpm version. Versions containing `-` publish to
the registry's `next` dist-tag; stable versions publish to `latest`.

## Registry credentials

Do not put a registry token in Git config, the project `.npmrc`, source files,
or this repository. For local publishing, `pnpm login --registry=https://registry.npmjs.org/`
stores authentication in your user-level pnpm config.

For Gitea Actions, create an npm granular access token with package read/write
permission and **Bypass 2FA** enabled. npm rejects CI publishing with a 403
without that permission, even when the token authenticates successfully. Add
or replace the repository Actions secret named `NPM_TOKEN`:

1. Open repository **Settings → Actions → Secrets** and add/edit `NPM_TOKEN`; or
2. For initial creation, pipe an environment variable to the configured `tea`
   CLI without placing the token in shell history:

   ```sh
   printf '%s' "$NPM_TOKEN" | tea actions secrets create --stdin NPM_TOKEN --repo james/pi-work-modes
   ```

The publish workflow exposes the secret only to the `pnpm publish` step. Do not
paste tokens into chat or commit them. Tests, tarball inspection, and local
Pi installation do not need an npm token.

## Release sequence

1. Update `package.json` and `pnpm-lock.yaml` to the release version and
   move the relevant `CHANGELOG.md` entry out of `Unreleased`.
2. Run the Linux/Node 22.19 and 24 CI matrix and complete
   [`SMOKE-TEST.md`](SMOKE-TEST.md). Windows/macOS are not advertised until
   matching runners and platform smoke checks are available.
3. For a candidate, use a prerelease version (for example `0.1.0-rc.1`),
   commit the version/changelog, and push the matching `v0.1.0-rc.1` tag. The
   workflow publishes it under `next`; validate installation/removal from the registry.
4. After approval, use the stable version and matching tag. The workflow
   publishes it under `latest`. Keep the previous tarball/version available
   for rollback.

`PLAN.md` is local task input and is intentionally not included in the
published package or release commits.
