一键导入
publish-rust
Verify and release a Rust crate or workspace. Bumps version, commits, tags, pushes. CI-driven by default; --local publishes directly.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Verify and release a Rust crate or workspace. Bumps version, commits, tags, pushes. CI-driven by default; --local publishes directly.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Prepares and triggers a new Python package release: runs cleanup, validates semantic versioning, updates pyproject.toml and docs, builds with uv, creates a GitHub release, and monitors the publishing workflow. Supports patch/minor/major auto-increment. Use when the user wants to cut a release, bump the version, or publish a new Python package version.
Interactive lesson-based teaching skill. Researches a topic via the web, builds a structured curriculum of up to 10 lessons, and delivers them one at a time with comprehension questions. Supports difficulty flags (--beginner, --advanced, --expert) and lesson count (--lessons N). Use when the user wants to learn about any topic in a guided, incremental way.
Run a comprehensive multi-agent QA audit of any project. Auto-detects language and framework, then launches parallel agents to audit code quality, architecture, error handling, test coverage, CI/CD, documentation, and security. Use for pre-release validation, periodic quality reviews, or when the user asks for a full project audit.
Runs a quick project health check covering git status, recent commits, GitHub Actions workflow runs, and package build verification. Use when starting a session, before a release, or to get a fast overview of project state.
Runs a complete code quality pipeline: ruff linting and formatting, mypy type checking, and pytest test suite. Use for end-of-session quality checks, pre-release validation, or when the user asks to lint, format, or clean up code.
Loads all markdown files from the current directory or a specified directory into context for analysis and reference. Non-recursive, loads only top-level .md files. Use when the user wants to read all docs in a folder, review documentation, or bring markdown content into the conversation.
| name | publish-rust |
| description | Verify and release a Rust crate or workspace. Bumps version, commits, tags, pushes. CI-driven by default; --local publishes directly. |
| argument-hint | major|minor|hotfix [--rc] [--local] [--no-watch] |
| allowed-tools | Bash, Read, Edit, Write, Glob, Grep |
Generic Rust release skill. Runs a full verification suite locally, bumps the version, commits, creates a signed semver tag, and pushes to trigger the project's release CI. With --local, publishes to crates.io directly instead of relying on CI.
$ARGUMENTS is one of:
major — bump first digit (X.0.0)minor — bump middle digit (0.X.0)hotfix — bump last digit (0.0.X)Optional flags:
--rc — tag a pre-release (X.Y.Z-rc.N). Increments N if already on an RC; drops the suffix if --rc is omitted. Pre-releases can be cut from any branch.--local — skip CI path; run cargo publish directly for each crate. Requires CARGO_REGISTRY_TOKEN in the environment.--no-watch — push the tag and exit without streaming the CI workflow (CI-driven mode only).If $ARGUMENTS is empty or doesn't match major|minor|hotfix, print usage and stop.
If .claude/publish-rust.toml exists in the project root, read it. Supported keys (all optional):
# Branch required for stable releases (not --rc). Default: "main".
release_branch = "main"
# Tag format. Default: "v{version}".
tag_format = "v{version}"
# Override the default verification gates. If present, these REPLACE the defaults.
# Each entry is a shell command; all must pass. Env vars via "env =".
[[verify]]
name = "fmt"
cmd = "cargo fmt --all -- --check"
[[verify]]
name = "clippy"
cmd = "cargo clippy --workspace --all-features --exclude mycrate-foo -- -D warnings"
env = { RUSTFLAGS = "-D warnings" }
[[verify]]
name = "test"
cmd = "cargo test --workspace --all-features --exclude mycrate-foo"
[[verify]]
name = "doc"
cmd = "cargo doc --workspace --no-deps"
env = { RUSTDOCFLAGS = "-D warnings" }
# --local only: crates to publish, in topological order. Default: auto-detect from
# workspace Cargo.toml, skipping members with publish = false.
[local]
publish_order = ["mycrate-core", "mycrate-adapters", "mycrate-cli"]
inter_publish_sleep_secs = 20
Defaults if no config:
release_branch = "main"tag_format = "v{version}"cargo fmt --all -- --checkcargo clippy --workspace --all-targets -- -D warningscargo test --workspacecargo doc --workspace --no-deps with RUSTDOCFLAGS=-D warningscargo publish --dry-run -p <crate> --allow-dirty. For publish = false members: skip. If a dry-run fails because an upstream workspace crate isn't on crates.io, fall back to cargo package --list -p <crate> --allow-dirty >/dev/null and print a warning.Emit short status lines (one sentence each) between steps. On any abort, print why and stop — never auto-fix, never proceed on warnings treated as errors.
Parse the bump kind (major/minor/hotfix), --rc, --local, --no-watch. If invalid, print usage and stop.
Read the workspace Cargo.toml:
[package] version = "X.Y.Z" directly. Bump this.[workspace.package] version = "X.Y.Z". Bump this; member crates use version.workspace = true.[package] version. Bump every member (fail if they're not all identical — the skill requires workspace-wide version parity).Read optional .claude/publish-rust.toml for overrides.
Let current = X.Y.Z[-rc.N] and bump = major|minor|hotfix.
-rc.N suffix and --rc is passed:
X.Y.Z), increment N.-rc.1.-rc.N suffix and --rc is NOT passed, and bump position matches the RC'd base: drop the suffix, tag the stable version as-is. (E.g. 0.8.0-rc.2 + minor → 0.8.0.)--rc is passed: bump + append -rc.1.--rc is not passed: plain bump.New tag = tag_format.replace("{version}", new_version).
Run these checks in order. Print each as "→ checking X ... OK" or "→ checking X ... FAIL: " and stop on the first failure.
git rev-parse --is-inside-work-tree).git status --porcelain empty).git branch --show-current == release_branch), unless --rc is passed (RCs allowed from any branch).git fetch origin <branch>, then compare HEAD with origin/<branch>. Must be equal (neither ahead nor behind).git rev-parse <new_tag> fails locally AND git ls-remote --tags origin <new_tag> is empty.^## \[v?<new_version>\] in CHANGELOG.md. If the file exists and has no such heading, abort with the exact heading the user needs to add..github/workflows/*.yml with on: push: tags: matching v*. If none, print a warning but continue. Skip this check entirely with --local.cargo available: command -v cargo.--local: CARGO_REGISTRY_TOKEN set in the environment. If not, abort.Run each gate from config (or the defaults listed above) in order. Stream stdout/stderr to the user. On the first failure, abort and print:
Verify gate failed: <name>
Command: <cmd>
Exit: <code>
Fix the underlying issue and re-run /publish-rust <args>. The skill has not modified any files.
Do not catch or retry. Do not continue on failure.
Edit the version in the right location(s) per step 2. Leave every other line untouched.
Stage only the edited Cargo.toml files plus Cargo.lock (run cargo check --workspace first to update the lockfile, then stage it). Do not git add -A.
Commit with:
chore: release <new_tag>
Respect the user's git config for commit.gpgsign (don't pass flags either way).
Create an annotated tag:
git tag -a <new_tag> -m "Release <new_tag>"
If git config tag.gpgsign is true, use -s instead of -a. Otherwise -a. Never force-overwrite an existing tag — preconditions already verified it doesn't exist.
Push the bump commit and tag:
git push origin <release_branch>
git push origin <new_tag>
On push failure (e.g., branch protection rejects direct push), abort. Do not bypass. Print the remote's error message verbatim.
Unless --no-watch is passed:
gh run list --event=push --branch=<new_tag> --limit=1 (or poll gh run list --workflow=release.yml --limit=1 if the workflow file was found in step 4). Wait up to 60s for the run to appear.gh run watch <run_id> --exit-status.gh run view <run_id> --log-failed | tail -80. Stop.With --no-watch: print the workflow run URL and the gh run watch <id> command the user can run, then stop.
Topologically sort the workspace members to publish:
config.local.publish_order if set.cargo metadata --format-version 1 --no-deps and do a topological sort of workspace members by their dependency graph (package.dependencies filtered to workspace-local crates). Skip members with publish = false (read from cargo metadata or Cargo.toml directly).For each crate in order:
cargo publish -p <crate> (no --dry-run; dry-run was step 5).config.local.inter_publish_sleep_secs seconds (default 20). Skip sleep after the last crate.For each published crate (CI-driven and --local both):
Poll https://crates.io/api/v1/crates/<crate>/versions (with reqwest/curl) up to 10 times, 10s apart (100s max per crate). Stop polling when the new version appears in the returned list.
If polling times out for any crate, print a warning (not an error) — indexing occasionally takes longer than 100s. The release is done; the index just hasn't caught up yet.
Print a final summary:
Released <new_tag>
Commit: <short_sha>
Tag: <new_tag>
Pushed: <branch> + tag to origin
CI: <success/skipped/--no-watch>
crates.io: <list of indexed crates, or "check manually">
GitHub release: <https URL if gh release view succeeds, else "pending">
Then stop.
Any abort should print in this shape:
[publish-rust] aborted: <one-line summary>
Reason: <specific details>
State: <what changed so far, e.g. "no changes made" / "commit created but tag not pushed">
Next: <what the user should do, e.g. "fix X and re-run" / "manually revert commit with `git reset --hard HEAD~1`">
Never leave the repo in a weird state silently.
git reset --hard HEAD~1 + git tag -d <tag> or retry the push.--force on any push. Never bypass git hooks. If the push is rejected, the skill's job is to tell the user why — not to work around it.--exclude swink-agent-local-llm on --all-features), use .claude/publish-rust.toml.