Release, provenance, and rollback

Lycato releases are built only by the protected release workflow. It runs the repository's canonical ci:release plan once, seals the compiled packages and public Hosting tree as a commit-addressed artifact, and allows publication or deployment only after that job passes. Local commands are useful rehearsals, not an alternate production release path.

One-time environment setup

Create two protected GitHub environments with required reviewers and deployment-branch/tag rules:

Both workflows default to contents: read, use commit-pinned actions, disable checkout credential persistence, pin pnpm 11.1.1, bound every job with a timeout, and serialize releases by Git ref.

Cut a release

  1. Add a changeset for every publishable package whose behavior changed.
  2. On a release branch, run pnpm exec changeset version, then pnpm install --lockfile-only so package versions, internal dependency ranges, changelogs, and the lockfile move together.
  3. Run pnpm run ci:release. Review the package manifests and generated changelogs, then merge the version commit to main.
  4. Create and push a new signed v* tag at that exact commit. Never move or reuse a release tag.
  5. Approve the npm-production and firebase-production jobs after the verification job is green.

The npm job downloads the compiled outputs from the verified job and runs Changesets with NPM_CONFIG_PROVENANCE=true. The Firebase job downloads the same verified artifact, reruns the public tree allowlist/link check, authenticates with short-lived Workload Identity Federation credentials, and deploys Auth providers, Firestore/Storage rules, and Hosting without rebuilding. firebase.json intentionally has no predeploy build hook: a build at deployment time would replace the artifact that passed the release gate.

After publication, confirm the npm registry shows provenance for each new version and that package metadata links to https://github.com/axysar/lycato. Confirm the Firebase release points at the expected Git commit and run the public Hosting smoke check against production before announcing it.

Roll back safely

Published npm versions are immutable. Do not unpublish a normal bad release and never overwrite its tag. Instead:

  1. deprecate each affected version with a precise warning;
  2. move the latest dist-tag back to the last known-good version if new installs are unsafe;
  3. fix forward, add changesets, and publish a new patch version through the protected workflow.

For Hosting, select the last known-good release in Firebase Hosting's release history and use its rollback control, then rerun the production smoke check. Keep the failed GitHub artifact and CI summary for diagnosis. Correct the source and deploy a newly verified artifact; do not rebuild or edit the rolled-back artifact in place.

If package and Hosting behavior must remain coupled, roll back Hosting first (the reversible edge), restore safe npm dist-tags second, and then ship a coordinated forward fix. Record the affected versions, artifact SHA, operator, timestamps, and verification result in the incident or release log.