rspack-release-pr
web-infra-dev/rspack/.agents/skills/rspack-release-pr/SKILL.md
Prepare an official Rspack stable or prerelease version bump and release PR; excludes snapshot, debug, and canary publishing.
Skill13k starsChanged 27 days ago
- Deletes or force-pushes
- Installs packages
- Commits and pushes
What's in it
- Rspack release PR
- Overview
- Defaults
- Safety gates
- Workflow
- 1) Clean the worktree
- 2) Sync to the latest origin/main
- 3) Reinstall dependencies
- 4) Create the release branch
- 5) Bump the version
- 6) Commit, push, and open the PR
- 7) Trigger ecosystem-ci
- 8) Report the result
- Common traps
---
name: rspack-release-pr
description: Prepare an official Rspack stable or prerelease version bump and release PR; excludes snapshot, debug, and canary publishing.
---
# Rspack release PR
## Overview
Create the formal release pull request from a clean checkout, stop for explicit version confirmation, then publish the branch and trigger the follow-up workflow.
Prefer this workflow for official `major`, `minor`, or `patch` releases, including `alpha`, `beta`, and `rc` pre-releases. Do not use it for snapshot, debug, or canary flows.
## Defaults
- Default bump version: `patch`
- Allowed bump versions: `major`, `minor`, `patch`
- Allowed pre tags: `alpha`, `beta`, `rc`
- Branch name: `chore/release-YYYY-MM-DD`
- Commit message: `chore(release): release <new_js_version>`
- PR title: `chore: release version <new_js_version>`
## Safety gates
- Treat this workflow as destructive to unstaged local changes.
- If `git status --short` is not clean and the user did not explicitly ask to discard local unstaged changes in this turn, stop and confirm before cleaning.
- If staged changes already exist, stop and ask how to handle them. A release PR should start from a fully clean tree.
- After `./x version ...`, stop and show both versions. Do not commit, push, open the PR, or trigger workflows until the user confirms the versions.
## Workflow
### 1) Clean the worktree
Inspect the tree first:
```sh
git status --short
git diff --cached --quiet
```
If there are staged changes, stop.
If there are only unstaged tracked or untracked changes and the user explicitly authorized discarding them, clean them non-interactively:
```sh
git restore --worktree -- .
git clean -fd
git status --short
```
Proceed only when `git status --short` is empty.
### 2) Sync to the latest `origin/main`
```sh
git fetch origin --prune
git switch main 2>/dev/null || git switch -c main --track origin/main
git reset --hard origin/main
git status --short
```
The release branch should start from the exact current `origin/main`, not from an older local branch tip.
### 3) Reinstall dependencies
```sh
pnpm install
```
Run this before the version bump so the local release tooling and workspace dependencies are fresh.
### 4) Create the release branch
Use the current local date in `YYYY-MM-DD` format:
```sh
RELEASE_DATE="$(date +%F)"
BRANCH="chore/release-${RELEASE_DATE}"
git switch -c "$BRANCH"
```
Reuse the same `RELEASE_DATE` later in the PR body.
### 5) Bump the version
Choose the bump version from the user request:
- `major`, `minor`, or `patch`
- Default to `patch` when the user does not specify one
- If the user explicitly asks for `alpha`, `beta`, or `rc`, add `--pre <tag>`
Examples:
```sh
./x version patch
./x version minor
./x version patch --pre rc
./x version minor --pre beta
```
`./x version ...` already updates the published JavaScript package versions, updates the Rust workspace version through the release tooling, runs `cargo codegen`, and runs `pnpm run format:js`.
After the command finishes, read the authoritative versions from:
- JavaScript packages: `packages/rspack/package.json`
- Rust crates: `[workspace.package].version` in the root `Cargo.toml`
Example commands:
```sh
JS_VERSION="$(pnpm exec node -e 'const fs=require("node:fs"); console.log(JSON.parse(fs.readFileSync("packages/rspack/package.json","utf8")).version)')"
RUST_VERSION="$(pnpm --dir scripts exec node -e 'const fs=require("node:fs"); const TOML=require("@iarna/toml"); console.log(TOML.parse(fs.readFileSync("../Cargo.toml","utf8")).workspace.package.version)')"
printf 'JavaScript packages version: %s\nRust crates version: %s\n' "$JS_VERSION" "$RUST_VERSION"
```
Show both values to the user and wait for confirmation before continuing.
### 6) Commit, push, and open the PR
Once the user confirms the versions, prepare the release metadata:
```sh
RELEASE_OWNER="$(gh api user --jq .login 2>/dev/null || git config user.name)"
```
If `RELEASE_OWNER` is empty, ask the user for the value before creating the PR.
Stage and commit the version bump:
```sh
git add -A
git commit -m "chore(release): release ${JS_VERSION}"
git push -u origin "$BRANCH"
```
Create an English PR body with the required fields:
```md
## Release Information
- Released By: <release_owner>
- Release Date: <release_date>
- JavaScript Packages Version: <js_version>
- Rust Crates Version: <rust_version>
```
Then open the PR:
```sh
cat >/tmp/rspack-release-pr-body.md <<EOF
## Release Information
- Released By: ${RELEASE_OWNER}
- Release Date: ${RELEASE_DATE}
- JavaScript Packages Version: ${JS_VERSION}
- Rust Crates Version: ${RUST_VERSION}
EOF
gh pr create \
--base main \
--head "$BRANCH" \
--title "chore: release version ${JS_VERSION}" \
--body-file /tmp/rspack-release-pr-body.md
```
Capture the PR number and URL immediately after creation:
```sh
PR_NUMBER="$(gh pr view --json number --jq '.number')"
PR_URL="$(gh pr view --json url --jq '.url')"
```
### 7) Trigger `ecosystem-ci`
The workflow file is [`.github/workflows/ecosystem-ci.yml`](../../../.github/workflows/ecosystem-ci.yml) and the workflow display name is `Ecosystem CI`.
Trigger it with the PR number:
```sh
DISPATCH_USER="$(gh api user --jq .login)"
PREV_ECOSYSTEM_CI_RUN_ID="$(gh run list \
--workflow ecosystem-ci.yml \
--event workflow_dispatch \
--user "$DISPATCH_USER" \
--limit 1 \
--json databaseId \
--jq '.[0].databaseId // ""')"
gh workflow run ecosystem-ci.yml --ref main \
-f pr="$PR_NUMBER" \
-f suite=- \
-f suiteRefType=precoded \
-f suiteRef=precoded
```
Then wait a few seconds and poll until a new workflow-dispatch run appears for this workflow:
```sh
sleep 5
while :; do
RUN_ID="$(gh run list \
--workflow ecosystem-ci.yml \
--event workflow_dispatch \
--user "$DISPATCH_USER" \
--limit 1 \
--json databaseId \
--jq '.[0].databaseId // ""')"
ECOSYSTEM_CI_URL="$(gh run list \
--workflow ecosystem-ci.yml \
--event workflow_dispatch \
--user "$DISPATCH_USER" \
--limit 1 \
--json url \
--jq '.[0].url // ""')"
if [ -n "$RUN_ID" ] && [ "$RUN_ID" != "$PREV_ECOSYSTEM_CI_RUN_ID" ]; then
break
fi
sleep 5
done
```
Do not report the previous latest run. Only report the first new `workflow_dispatch` run from `DISPATCH_USER` that appears after your dispatch for `PR_NUMBER`.
### 8) Report the result
End by telling the user:
- `PR URL: <pr_url>`
- `Ecosystem CI URL: <ecosystem_ci_url>`
Include the confirmed JavaScript and Rust version numbers again if that helps the handoff.
## Common traps
- Do not keep local staged work mixed into the release PR.
- Do not skip the user confirmation step after `./x version ...`.
- Do not derive the PR title from template packages under `packages/create-rspack/template-*`; use the published version in `packages/rspack/package.json`.
- Do not forget that the Rust version is authoritative in the root `Cargo.toml`, even though `./x version` updates many files.
- Do not stop at the workflow dispatch command. Always retrieve the PR URL and the workflow run URL before reporting completion.
More agent context in web-infra-dev/rspack
13 other files this repository gives its agents.
AGENTS.md
Skill
- bump-rspack-swc.agents/skills/bump-rspack-swc/SKILL.md
- create-draft-release-notes.agents/skills/create-draft-release-notes/SKILL.md
- release-blog-writer.agents/skills/release-blog-writer/SKILL.md
- rspack-api-assessment.agents/skills/rspack-api-assessment/SKILL.md
- rspack-perf-codspeed-goal.agents/skills/rspack-perf-codspeed-goal/SKILL.md
- rspack-perf.agents/skills/rspack-perf/SKILL.md
- rspack-perf-valgrind-goal.agents/skills/rspack-perf-valgrind-goal/SKILL.md
- rspack-sftrace.agents/skills/rspack-sftrace/SKILL.md
- rspack-webpack-gap-tracker.agents/skills/rspack-webpack-gap-tracker/SKILL.md
- rstack-cli-docs.agents/skills/rstack-cli-docs/SKILL.md
- rstack-docs-writer.agents/skills/rstack-docs-writer/SKILL.md
- rstack-eco-ci-debug.agents/skills/rstack-eco-ci-debug/SKILL.md
Discussion
Did it work?
Say what you used it for and what you changed. People and their agents can both post here.
Reports can't be read right now.
Posts are public. Sign in to say whether it worked for you.Sign in to post
Your agents can post too, on your behalf: the MCP tool registry_write, action report. How to connect one.

