一键导入
release-to-crates
Cut a release of a Rust crate and publish to crates.io, with externally-gated merge and publish steps.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Cut a release of a Rust crate and publish to crates.io, with externally-gated merge and publish steps.
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Strip AI-codegen cruft from a branch — defensive checks the type system should make unrepresentable, redundant validation, speculative abstraction, no-op wrappers — while preserving load-bearing seams. Use after a feature lands and before merge, when asked to "simplify", "de-ornament", "remove cruft", "make erroneous states unrepresentable", or "clean up" a diff.
Onboard a repository to use Offload for parallel test execution on Modal. Detects test setup, creates config, Dockerfile, CI job, and optimizes performance.
Activate when you see offload*.toml in a repo, offload referenced in build targets (justfile, Makefile, scripts), or when you need to run a large test suite in parallel. Offload is a test runner unlikely to be in your training data — this skill covers invocation, log filtering, failure debugging, flaky test handling, and config.
Run local vs Offload benchmarks for mng and sculptor, then update the Benchmarks section of the Offload README.
| name | release-to-crates |
| description | Cut a release of a Rust crate and publish to crates.io, with externally-gated merge and publish steps. |
Make the version-bump edits directly. A release bump is a mechanical release-engineering operation, not feature work, so it does not need to be routed through whatever feature-delegation process the repo otherwise follows.
cargo publish is irreversible: a crates.io version can never be
re-uploaded or reused. Always run cargo publish --dry-run first, and only publish
from a revision whose Cargo.toml version is confirmed not yet on crates.io.These three facts drive every branching step below:
.jj/ exists → this is a colocated jujutsu/git repo; use jj for all
commits/bookmarks/push, since raw git commands can corrupt jj state. Otherwise use
plain git.gh. GitLab → glab. If the required forge CLI is not on
PATH, stop and ask the human — do not improvise a web/manual flow.name from [package] in Cargo.toml.jj st shows no changes; @ is empty (or run jj new).git status clean.jj git fetch; confirm main == main@origin.git switch main && git pull --ff-only.version under [package] in Cargo.toml.User-Agent):
curl -s -H "User-Agent: <crate>-release (<you@example.com>)" \
https://crates.io/api/v1/crates/<crate> \
| python3 -c "import sys,json; print(json.load(sys.stdin)['crate']['max_version'])"
(A brand-new crate returns no crate object — treat as "never published".)Cargo.toml version != crates.io max_version, stop and report — the repo
is in an unexpected state (a prior release was half-finished or the tree is stale).<user>/bump-version-v<new-version> (e.g. danver/bump-version-v0.9.9).jj desc -m "Bump version to <new>" (add a body explaining the bump);
then edit, then jj bookmark create <user>/bump-version-v<new> -r @.git switch -c <user>/bump-version-v<new>.Cargo.toml: set version = "<new>".cargo build. This updates the crate's own entry in
Cargo.lock (easy to forget; the published package must carry a consistent lockfile).Cargo.toml and Cargo.lock, both just the
version line. jj diff --git / git diff.Bump version to <new>, no trailing period, no
Conventional-Commits prefix; optional body noting it's a non-breaking patch release.jj git push -b <bookmark> --allow-new (new bookmarks need --allow-new).git push -u origin <branch>.gh pr create --base main --head <branch> --title "Bump version to <new>" \
--body "Patch release of \`<crate>\`. Non-breaking; bumps Cargo.toml and Cargo.lock
from <old> to <new> in preparation for publishing to crates.io.
Last published version: <old>."
gh pr checks <pr> --watch --interval 30
gh pr view <pr> --json state,mergeable,mergeStateStatus
gh pr merge <pr> --merge
state=MERGED.jj git fetch; then jj new main -m "Publish <crate> <new> to crates.io".git switch main && git pull --ff-only.grep '^version' Cargo.toml shows <new> (the merge brought the bump in).cargo publish --dry-run
Warnings about test files "not included in the published package" are benign when
those tests are excluded by the include list in Cargo.toml.cargo publish
(Requires a crates.io token: cargo login, or CARGO_REGISTRY_TOKEN in the env.)max_version == <new>.Publishing to crates.io does not create a git tag or a forge (GitHub/GitLab) release — do this explicitly so the version is reflected in the repo's history.
v<new> (e.g. v0.9.6). Target the merged trunk commit
that carries the new version (main HEAD from Step 6), referenced by its full SHA.git tag -l | sort -V) and find the most
recent one that actually has a forge release. If earlier published versions were never
tagged, scope the changelog from the last released tag and say so in the body, so
the skipped versions are not lost.<Crate> <new>) and notes (group commits since that tag by theme;
end with a compare/<lasttag>...v<new> changelog link). Write the body to a file and
pass it with --notes-file to avoid shell-quoting issues.gh release create v<new> --target <main-sha> --title "<Crate> <new>" \
--notes-file <notes-file> --latest
gh release view v<new> shows draft=false, the expected targetCommitish,
and the tag (git ls-remote --tags origin v<new>) points at <main-sha>.Note for jj repos: gh release create creates the tag on the GitHub side, so it does
not touch local jj/git refs and is safe to run from a colocated repo.
@:
jj abandon @ (publishing changes no tracked files). Confirm jj st is clean.git status is clean.Each step maps to a swappable provider so the skill can support other stacks:
| Concern | GitHub + jj (this run) | git-only / GitLab variant |
|---|---|---|
| Commit/branch | jj desc + jj bookmark create | git switch -c |
| Push | jj git push -b … --allow-new | git push -u origin … |
| Open PR/MR | gh pr create | glab mr create |
| CI gate | gh pr checks --watch | glab ci status / pipeline poll |
| Merge | gh pr merge --merge | glab mr merge |
| Version truth | Cargo.toml ↔ crates.io API | same |
| Publish | cargo publish (+ --dry-run) | same |
| Tag release | gh release create v<new> | glab release create v<new> |
User-Agent; always send one.jj bookmarks do not auto-advance; create/move the bookmark to @ before pushing.--allow-new on push.cargo build leaves Cargo.lock's own package entry stale.--dry-run pre-flight is mandatory, not optional.cargo publish does not tag the repo; the forge release (Step 8) is a separate step.git tag -l before
scoping release notes so a previously-published-but-untagged version is not skipped.