| name | baicie-release |
| description | Guide agents to integrate and operate @baicie/release for fixed-version monorepo publishing, changelog generation, canary releases, and publish-only recovery. Use when a user asks how to add, configure, run, debug, or document the packages/release package or @baicie/release workflow in a pnpm workspace. |
Baicie Release
Core Model
Use @baicie/release for pnpm monorepos that need one shared release version across multiple publishable packages.
Choose the mode first:
changesets-fixed: use when the target repo already uses Changesets or needs release notes from .changeset; prefer this for Zeus-style repos.
workspace-fixed: use when the repo does not need Changesets and only needs to update all publishable package versions directly.
Keep the normal stable release path tag-driven: local release prepares version files, changelog, commit, and tag; CI publishes from the tag with publishOnly.
Integration
Add the package:
pnpm add -D @baicie/release
Create release.config.ts at repo root:
import { defineReleaseConfig } from '@baicie/release'
export default defineReleaseConfig({
repo: 'owner/repo',
repositoryUrl: 'https://github.com/owner/repo',
mode: 'changesets-fixed',
packageManager: 'pnpm',
workspace: {
roots: ['packages'],
publishable(pkg) {
return Boolean(pkg.name) && !pkg.isPrivate
},
},
rootVersionPackage: '@scope/main-package',
changelogFile: 'CHANGELOG.md',
changesets: {
requireChangeset: false,
readIgnore: true,
readFixed: true,
cleanupPackageChangelogs: true,
unifiedChangelog: true,
},
publish: {
access: 'public',
provenance: true,
skipExisting: true,
retry: 5,
},
precheck: {
commands: [
['pnpm', 'typecheck'],
['pnpm', 'lint'],
['pnpm', 'test'],
['pnpm', 'build'],
],
},
})
Add scripts:
{
"scripts": {
"release": "baicie-release",
"release:publish": "baicie-release publish",
"release:version": "baicie-release version:packages",
"release:canary": "baicie-release canary"
}
}
If the repo has a custom CLI wrapper, keep it only when it ultimately calls runReleaseCli, runPublishCli, runCanaryCli, or the matching exported workspace functions from @baicie/release.
Stable Release
Before a stable release, run the repo's quality gates and a release dry-run:
git status
pnpm install --frozen-lockfile
pnpm typecheck
pnpm lint
pnpm test
pnpm build
pnpm release --version 0.1.0 --dry
Warn the user that --dry still updates local version files, changelog, and lockfile. Inspect the diff after dry-run, then restore or continue intentionally.
Run the stable release:
pnpm release --version 0.1.0
Use prerelease tags explicitly:
pnpm release --version 0.1.0-beta.0 --tag beta
pnpm release --version 0.1.0-rc.0 --tag rc
CI Publish
For stable releases, prefer a GitHub Actions workflow triggered by v* tags. Use:
pnpm release --publishOnly ${GITHUB_REF_NAME#v} --skipBuild
Set NODE_AUTH_TOKEN from NPM_TOKEN. If publish.provenance is enabled, the workflow must include:
permissions:
contents: write
id-token: write
Use publishOnly only for publishing already-prepared versions, especially when CI publish failed after the tag/version files already exist.
Recovery flow:
pnpm release --publishOnly 0.1.0 --skipBuild --dry
pnpm release --publishOnly 0.1.0 --skipBuild
Keep publish.skipExisting: true for recovery so already-published packages do not fail the whole publish.
Canary Release
Enable canary only when the repo needs temporary versions for downstream compatibility checks:
canary: {
enabled: true,
prefix: 'canary',
tag: 'canary',
envName: 'CANARY_VERSION',
includeBranches: ['main', 'feat/**', 'fix/**', 'release/**', 'hotfix/**'],
}
Run in CI:
pnpm release:canary
Canary versions use:
{baseVersion}-canary.{date}.{runNumber}.{runAttempt}.{shortSha}
Use --force-local only for deliberate local debugging. It still requires an npm token and may publish real canary packages.
Changelog Semantics
In changesets-fixed mode, maintain a unified root CHANGELOG.md. With cleanupPackageChangelogs: true and unifiedChangelog: true, package-level changelogs generated by Changesets are removed unless they existed before the release, in which case their original contents are restored.
If a release step fails after changeset version, expect cleanup to restore package changelogs and remove the synthetic changeset file.
Troubleshooting
- npm 401: check
NODE_AUTH_TOKEN or NPM_TOKEN.
- provenance failure: ensure GitHub Actions has
id-token: write and package repository metadata matches the real GitHub repo.
- version already exists: use
publish.skipExisting: true and rerun publishOnly.
- canary dispatch missing: check dispatch token env, target repository, event type, and downstream
repository_dispatch.types.
- dirty worktree after dry-run: inspect with
git diff; restore only with user intent because dry-run changes are expected.
Validating Release Package Changes
When modifying packages/release, run focused checks:
pnpm --filter @baicie/release test
pnpm --filter @baicie/release typecheck
pnpm --filter @baicie/release build
Cover risky behavior with tests: CLI option parsing, afterVersion, canary branch matching, changelog snapshot and restore, synthetic changeset cleanup, and failure recovery around runChangesetsFixedVersion.