From 853e16bccf3d8ad9417dd200d398f5dee6ef5a41 Mon Sep 17 00:00:00 2001 From: "MK (fengmk2)" Date: Fri, 23 Oct 2026 15:27:26 +0900 Subject: [PATCH 1/2] docs(skill): refine release-manager guidance from the v1.4.0 release Co-Authored-By: Claude Opus 5.5 --- .claude/skills/release-manager/SKILL.md | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/.claude/skills/release-manager/SKILL.md b/.claude/skills/release-manager/SKILL.md index 61a19ddeda..3365c66b2a 100644 --- a/.claude/skills/release-manager/SKILL.md +++ b/.claude/skills/release-manager/SKILL.md @@ -145,18 +145,18 @@ Merging this PR will trigger the release workflow. ### Categorization rules - Every PR from `generate-notes` appears exactly once, except fully reverted changes described below and bot-authored PRs that carry nothing for a user to read or act on (a docs stats refresh, a badge update). Keep bot PRs that do change what users get, such as the upstream dependency upgrades. Record each omitted PR and its reason when reporting validation counts. -- **Breaking Changes goes first, above Features, and only when the release has one.** A rename is breaking only when the old name stops working; if a deprecated alias is retained it is not breaking, so keep the two in different sections rather than merging them into one entry. Give each breaking entry an old -> new table when several names change, plus one line telling readers where to update (shell profile, CI job, Dockerfile). Do not editorialize about the version number. +- **Breaking Changes goes first, above Features, and only when the release has one.** A rename is breaking only when the old name stops working; if a deprecated alias is retained it is not breaking, so keep the two in different sections rather than merging them into one entry. A behavior that exists only inside a new feature (a new bin, command, or mode) is part of that feature's entry, not a breaking change, even when it differs from an older code path. Give each breaking entry an old -> new table when several names change, plus one line telling readers where to update (shell profile, CI job, Dockerfile). Do not editorialize about the version number. - When several breaking changes affect different workflows, group them under short `####` headings. Explain the changed behavior and required action before each table; keep automatic migration steps separate from changes users must make manually. - **Describe the net change between the two released versions, not intra-cycle churn.** When several PRs touch the same area within one release (one narrows a behavior, a later one broadens it back), the reader only sees the delta from `v` to `v`; describe that once, listing every PR number, and do not narrate a regression that was introduced and then fixed inside the cycle. Apply this to the intro/theme sentence too. - If a change and its complete revert are both unreleased, omit both when they leave no net change. Remove sections with no remaining entries. A revert of behavior in the previous release still needs an entry. -- `feat` -> Features, `fix` -> Fixes & Enhancements, `refactor` and `revert` -> Refactor (never Chore), `docs` -> Docs, `test` / `ci` / `chore` -> Chore. +- `feat` -> Features, `fix` -> Fixes & Enhancements, `refactor` and `revert` -> Refactor (never Chore), `perf` -> Fixes & Enhancements (also when it adds an option or environment variable), `docs` -> Docs, `test` / `ci` / `chore` -> Chore. - **Place an entry by its user impact when the prefix disagrees.** A `fix` that gives an existing command new observable behavior (for example, starting to set environment variables for child processes) belongs in Features. A fix that makes a command reject input it used to drop silently stays in Fixes & Enhancements, not Breaking Changes. - `feat(docs)` goes in Docs when the user-facing surface is the docs site. - **Docs means the published docs site, not contributor files.** A `docs` commit that changes an RFC, `AGENTS.md`, the repo map, or a skill under `.claude/` belongs in Chore: a vite-plus user never reads those. Docs should hold only entries a reader could go and look at on the site or in the README. - **Describe behaviour, not resolution logic.** An entry states what a user now observes. Rules the implementation follows internally (target-selection signals, config precedence, detection order) belong in the RFC or the PR, not the changelog. If an entry needs a nested list to explain how a decision is reached, cut it down to the outcome. - **A breaking change needs its migration path.** State what existing installs or projects do by default, then how to move to the new behaviour deliberately, then what that costs. Link the guide rather than restating it, and say plainly when doing nothing is a valid choice. - There is no separate Highlights section. Lead Features with up to 5 new capabilities a vite-plus user will notice, plus security fixes, then the remaining features; the upstream upgrade entry stays last. Bug fixes go in Fixes & Enhancements even when they are prominent. Skip developer-tooling-only conveniences. -- Entry format: `Description ([#N](https://github.com/voidzero-dev/vite-plus/pull/N)), by @author`. Describe the user-visible behavior, not the implementation. Group supporting implementation PRs under the user-visible change they enable instead of giving them separate entries. Never include defensive edge cases or internal mechanics unless users need them to use or understand the feature; use concrete behavior instead of internal UI taxonomy that needs extra context. For a fix to an intermittent failure, say that it was rare and when it happened, so the entry does not read as if it always failed. When a PR carries over a superseded PR from another author (its body says so, or `gh pr view N --json commits` lists their commits), credit both authors. +- Entry format: `Description ([#N](https://github.com/voidzero-dev/vite-plus/pull/N)), by @author`. Describe the user-visible behavior, not the implementation. Group supporting implementation PRs under the user-visible change they enable instead of giving them separate entries, and fold a new feature's sub-mode (such as its `--watch` flag) into the feature's entry. In Refactor and Chore, keep one contributor's related refactors together in their own entry, and give a notable maintenance change (such as a security-release runtime bump) its own entry. Never include defensive edge cases or internal mechanics unless users need them to use or understand the feature; use concrete behavior instead of internal UI taxonomy that needs extra context. For a fix to an intermittent failure, say that it was rare and when it happened, so the entry does not read as if it always failed. When a PR carries over a superseded PR from another author (its body says so, or `gh pr view N --json commits` lists their commits), credit both authors. Credit only substantive commits: a `Merge branch 'main'` commit on a bot or contributor PR does not make its author a co-author. - **Upstream dependency upgrade PRs** (`feat(deps): upgrade upstream dependencies`): consolidate all of them into one Features entry with net oldest-to-latest version changes (e.g. `vite 8.0.16 -> 8.1.2`), listing every PR number. Check the upgraded range for security fixes (search the upstream changelog for CVE/GHSA); if present, add a dedicated security entry quoting severity and linking the advisory. Cite only published advisories: a draft advisory that maintainer access lets you see is still embargoed, so keep it and its fix's security framing out of the notes and the announcement. When oxfmt or oxlint changed version, add one clause telling users the new versions can flag code that passed before, so they should run `vp fmt` after upgrading if their CI runs `vp check`; in ecosystem testing this is reliably the largest single class of post-upgrade CI failures. Put this entry last in Features as a parent bullet carrying the PR links and credits, with one sub-item per upgraded tool and one per user-facing consequence (new formatting or lint behavior, migration changes, compatibility notes); a single long line is hard to read. - **vite-task bumps** (`bump vite-task to `): expand the full rev range (compare `Cargo.toml` at `v` vs the release branch), run `git log ..` in the local vite-task checkout, and read vite-task's `CHANGELOG.md` at the new commit for wording. Promote user-visible upstream changes into Features / Fixes with `[vite-task#N](https://github.com/voidzero-dev/vite-task/pull/N)` links, crediting the upstream PR author (`gh pr view N --repo voidzero-dev/vite-task --json author`). Cross-repo link format is `[vite-task#N]` / `[vite#N]`, not `[owner/repo#N]`. - New Contributors: copy from `generate-notes`, exclude bots (`renovate[bot]`, `voidzero-guard[bot]`, `github-actions[bot]`), list as inline `@mentions`. `generate-notes` only covers vite-plus, so also add first-time contributors from the expanded vite-task range: an author is new when `gh api -X GET search/issues -f q='repo:voidzero-dev/vite-task is:pr is:merged author: merged:<' -q .total_count` is 0. List them with the others, without a repository label, in the release notes and the Discord thanks line. @@ -179,6 +179,8 @@ vite and rolldown are built from pinned commits, so link the commit. The npm-ins - No em dashes or en dashes anywhere in the title or body. Use commas, colons, or parentheses. - Keep the PR title plain (`release: vX.Y.Z`) and the GitHub release title plain (`vite-plus vX.Y.Z`); the theme goes in the opening sentence. Lead the opening theme with the most important user-visible behavior. Avoid vague benefit-only wording that the body must explain. +- Say what a feature does. Do not compare it to the tool it replaces, and do not say it works "without" a dependency it never needed. +- Round performance and size numbers measured on one machine (for example `30%+ smaller`); leave per-platform byte counts and exact benchmark percentages to the PR. - When naming a package version in prose or a heading, use one inline literal, `package@version`. Keep separate version columns in tables. - Link unfamiliar technical abbreviations to the relevant documentation section; keep the short abbreviation as the link text. - The Upgrade section is a `vp upgrade` code block. @@ -224,7 +226,7 @@ If the release manager says yes: gh pr edit --repo voidzero-dev/vite-plus --add-label "preview-build" ``` -2. Wait for the `Publish preview build` workflow run on the release branch to succeed (it packs the built package directories and registers the commit with the registry bridge, then comments the build info on the PR). +2. Wait for the `Publish preview build` workflow run on the release branch to succeed (it packs the built package directories), then for the `publish-preview-register.yml` run that it triggers. The register run publishes the local CLI packages, generates the installation lockfile, publishes the global CLI packages (`@voidzero-dev/vite-plus-cli-`), updates the PR tag, and comments the build info on the PR. Until its last publish job finishes, resolving the build by PR number returns 404 from the bridge and the global install fails; confirm a `@voidzero-dev/vite-plus-cli-` packument lists the commit version before you start. 3. Verify the build against every runnable project in the catalog with the `test-pkg-pr-new-migrate` skill: it runs `vp migrate` from the preview commit against each local checkout, with dependencies resolved through the registry bridge. Report the outcome to the release manager before moving on. **The catalog.** The smoke-test catalog and the local-setup rules live in the ecosystem-ci org: [`vite-plus-ecosystem-ci/.github/TESTING.md`](https://github.com/vite-plus-ecosystem-ci/.github/blob/main/TESTING.md), with the machine-readable list in [`ecosystem.json`](https://github.com/vite-plus-ecosystem-ci/.github/blob/main/ecosystem.json) (each fork's upstream, tracked branch, and package manager). Run every runnable fork; filter `ecosystem.json` with `jq` to skip non-JS `other` repos and any the release manager says to ignore. Forks pinned to the immediately previous release exercise a real upgrade rather than a no-op. @@ -364,11 +366,13 @@ git checkout release/vX.Y.Z && git merge origin/main --no-edit && git push origi Do not assume the merge brought in only the fix PR: `main` may have accumulated several. Before merging, list everything that will come in with `git log origin/release/vX.Y.Z..origin/main --oneline`, then add a changelog entry for **every** newly included PR and rerun the step 3 validation (its missing/extra diff against `generate-notes` catches any entry you missed). When the merged commits change bundled tool versions or `vp migrate` behavior, rebuild the preview (step 4) and repeat the smoke test on the new build: start each fork from its current test branch so earlier fixes carry over, open new fork PRs, close the superseded ones, and report results per build. +When several fix PRs merge back to back, the required `done` check must pass again on each later PR after `main` moves: update that PR's branch and let CI rerun before merging it. + Known release-branch-only failure modes: - **Binding version drift**: CI's no-unexpected-changes guard reports a diff flipping version strings in `binding/index.cjs`. Fix: step 2. - **Registry flakes**: registry-bound fixtures can time out (about 50s) and look like regressions. Rerun before diagnosing, and never commit a `[timeout]` snapshot. -- **New RustSec advisories**: Security Analysis runs cargo-deny only when `Cargo.lock` changes, and the version bump always changes it. An advisory published since `main` last touched `Cargo.lock` therefore fails first on the release PR. The check is not required; trace which dependency pulls the crate in and let the release manager decide whether to fix it before or after the release. Before opening a fix PR, check open dependency-update PRs (Renovate): one may already bump the crate and clear the check. +- **New RustSec advisories**: Security Analysis runs cargo-deny only when `Cargo.lock` changes, and the version bump always changes it. An advisory published since `main` last touched `Cargo.lock` therefore fails first on the release PR. The check is not required; trace which dependency pulls the crate in and let the release manager decide whether to fix it before or after the release. Before opening a fix PR, check open dependency-update PRs (Renovate): one may already bump the crate and clear the check. If `cargo update -p --precise ` also re-resolves unrelated entries (for example `windows-sys` versions), edit only that crate's `version` and `checksum` in `Cargo.lock` and confirm with `cargo metadata --locked`. ## 6. Merge From 5bcf9ddc306f5e99331dc989206525f754fd7fd9 Mon Sep 17 00:00:00 2001 From: "MK (fengmk2)" Date: Fri, 23 Oct 2026 16:30:54 +0900 Subject: [PATCH 2/2] docs(skill): drop the rounding rule Co-Authored-By: Claude Opus 5.5 --- .claude/skills/release-manager/SKILL.md | 1 - 1 file changed, 1 deletion(-) diff --git a/.claude/skills/release-manager/SKILL.md b/.claude/skills/release-manager/SKILL.md index 3365c66b2a..57212d2079 100644 --- a/.claude/skills/release-manager/SKILL.md +++ b/.claude/skills/release-manager/SKILL.md @@ -180,7 +180,6 @@ vite and rolldown are built from pinned commits, so link the commit. The npm-ins - No em dashes or en dashes anywhere in the title or body. Use commas, colons, or parentheses. - Keep the PR title plain (`release: vX.Y.Z`) and the GitHub release title plain (`vite-plus vX.Y.Z`); the theme goes in the opening sentence. Lead the opening theme with the most important user-visible behavior. Avoid vague benefit-only wording that the body must explain. - Say what a feature does. Do not compare it to the tool it replaces, and do not say it works "without" a dependency it never needed. -- Round performance and size numbers measured on one machine (for example `30%+ smaller`); leave per-platform byte counts and exact benchmark percentages to the PR. - When naming a package version in prose or a heading, use one inline literal, `package@version`. Keep separate version columns in tables. - Link unfamiliar technical abbreviations to the relevant documentation section; keep the short abbreviation as the link text. - The Upgrade section is a `vp upgrade` code block.