--- name: release description: Bump VibeFrame versions, regenerate release artifacts, run verification, and prepare a version commit. --- # Release Use this skill when the user asks Codex to cut a VibeFrame release. The bump is one of `patch`, `minor`, or `major`. **Default to `patch`** when no bump is specified or when there is any doubt. ## When Bumps Happen **Once per release, not once per PR.** Ordinary `feat:` / `fix:` PRs merge to `main` without a version bump. This skill runs when you decide to release, and the single bump it produces must cover *every* commit since the last tag - `git-cliff` handles that automatically in step 7. Check what the release will cover before starting: ```bash bash scripts/release-status.sh ``` That script is the single source of truth for release state. The push gate, the tag workflow, and the daily drift check all call it, so its answer is the same one CI will give. ## Version Policy VibeFrame is still in `0.x`. **`patch` is the default and by far the most common bump.** `minor` is rare and must be explicitly justified — the shared push gate (`scripts/pre-push-validate.sh`) blocks a non-patch bump that lacks a `Release-Type:` trailer (see step 10). - `patch`: bug fixes, docs/tooling, UX polish, internal refactors, and most ordinary `feat:` / `fix:` commits. **Use this unless a rule below clearly applies.** - `minor`: new public CLI command namespace, new MCP tool family, public API contract additions, or a large product milestone. - `major`: breaking changes or an intentional 1.0 milestone. When unsure, use `patch`. ## Steps 1. Read the current root version: ```bash jq -r '.version' package.json ``` 2. Bump the root package: ```bash npm version --no-git-tag-version ``` 3. Read the exact new version: ```bash NEW_VERSION=$(jq -r '.version' package.json) ``` 4. Set every workspace package to that exact version. Do not use `pnpm -r exec npm version` for this step because recursive pnpm includes the root package. ```bash for dir in packages/cli packages/core packages/ai-providers packages/mcp-server packages/ui apps/web; do (cd "$dir" && npm version "$NEW_VERSION" --no-git-tag-version) done ``` 5. Verify all package versions match: ```bash for f in package.json packages/*/package.json apps/*/package.json; do jq -r '.version' "$f" done | sort -u ``` The output must contain exactly one version. 6. Build, regenerate references, lint, and test: ```bash pnpm build pnpm gen:reference pnpm lint pnpm -F @vibeframe/cli exec vitest run --bail 1 ``` 7. Generate the changelog for the new version: ```bash git-cliff --tag v$NEW_VERSION -o CHANGELOG.md ``` 8. Run the shared push gate: ```bash bash scripts/pre-push-validate.sh ``` 9. Stage the release files: ```bash git add package.json packages/*/package.json apps/*/package.json CHANGELOG.md docs/cli-reference.md ``` 10. Commit. For a `patch` bump, a plain message: ```bash git commit -m "chore: bump version to $NEW_VERSION" ``` For a `minor` or `major` bump, the push gate requires a justification trailer in the commit body, or it blocks the push: ```bash git commit -m "chore: bump version to $NEW_VERSION" -m "Release-Type: minor: " ``` Do not create a local tag. Do not push unless the user explicitly asks. 11. The version commit reaches `main` **via a PR**, never a direct push (even though `main` allows admin bypass). Put it on a `chore/release-$NEW_VERSION` branch, open a PR, let CI go green, and merge: ```bash git switch -c chore/release-$NEW_VERSION git push -u origin chore/release-$NEW_VERSION gh pr create --fill --base main ``` 12. Tagging is automatic. Once the version commit lands on `main` and CI passes, the `Create release tag` workflow creates `vX.Y.Z` on its own. Before tagging it re-runs `scripts/release-status.sh` and **refuses** if `feat:` / `fix:` commits landed after the bump, or if `CHANGELOG.md` has no `## [X.Y.Z]` entry. Do not create the tag by hand. 13. Publishing stays manual. Run the `Publish to npm` workflow with the new tag. Tags pushed by a workflow cannot trigger another workflow, so the automatic tag never dispatches `publish.yml` - that is what keeps the "CI never publishes" policy intact. A human-created `git push origin vX.Y.Z` *does* trigger `publish.yml`, so do not push release tags manually. If publishing is forgotten, the daily `Release drift check` workflow opens an issue comparing `main`, the latest tag, and the published npm versions.