一键导入
opi-release
Orchestrates the full release process for the opi Rust workspace — publishes to GitHub Releases and crates.io with phased safety gates
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
菜单
Orchestrates the full release process for the opi Rust workspace — publishes to GitHub Releases and crates.io with phased safety gates
用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
基于 SOC 职业分类
Update opi documentation so it stays truthful to the shipped code and the English/Chinese mirrors stay in sync. Use this skill whenever the user mentions "update the docs/README", "refresh the README", "sync EN/ZH", "translate the README", "fix doc drift", "文档更新", "文档同步", "更新 README", "翻译 README", or asks to bring docs in line after a change. Also use at Phase 6 of the opi workflow (after implementation/remediation, before release), and whenever a version bump needs the doc version-strings resynced.
Use when executing opi-spec.md tasks or reviewed supplemental opi phase tasks, checking implementation status, reinitializing the task ledger, resuming interrupted implementation, clearing task blockers, or auto-selecting the next unblocked task. Triggers on implement, resume, verify, or progress requests for spec tasks; not on merely reading or discussing specs.
Perform an independent code audit of a specific opi implementation phase. Given a phase number, automatically extract the task graph, design spec, and commit range from impl-state.json, then systematically compare spec against actual implementation. Use this skill whenever the user mentions "audit", "code review", "审计", "审查", "review phase N", "compare spec and implementation", or asks to verify whether a phase was implemented correctly. Also use when the user wants to check spec compliance, find implementation gaps, or produce a structured audit report for any phase.
Use when the user wants to confirm, verify, or fix issues from audit reports for a specific opi implementation phase. Triggers on "remediate phase N", "verify audit findings", "fix audit issues", "confirm audit", "修复审计", "验证审计发现", "审计修复", or any request to cross-reference multiple audit reports and produce a verified remediation plan. Also use when the user asks to act on findings from docs/snapshots/phase<N>/audit.*.md files.
Compare a current implementation with a target/reference project and produce an architecture, feature, design-philosophy, package-boundary, and roadmap realignment review. Use when the user asks to realign, audit drift, compare a port/reimplementation, check whether planned phases match an upstream project, or evaluate cross-language architecture against a target project path.
| name | opi-release |
| description | Orchestrates the full release process for the opi Rust workspace — publishes to GitHub Releases and crates.io with phased safety gates |
| arguments | <version> [--fix] [--skip-cross] |
Release the opi Rust workspace to GitHub Releases and crates.io.
<version> — target semver version (e.g., 0.2.0)--fix — auto-fix fmt/clippy issues during pre-flight--skip-cross — skip cross-compilation (source-only release)Each phase reports status and requires user confirmation before proceeding.
Phase 1: Pre-flight checks
Phase 2: Version bump + dry-run validation
Phase 3: Changelog generation
Phase 4: Build, cross-compile & artifact self-check
Phase 5: Commit, tag, push & GitHub Draft Release (PARTIALLY reversible)
Phase 6: Publish to crates.io (IRREVERSIBLE)
Phase 7: Finalize & post-release verification
git revert.Release pre-flight gates are deterministic and must not depend on live provider or dogfood runs. If a release candidate cites a dogfood report as evidence, that report must already have passed the opi-implement Artifact Truthfulness Gate; opi-release does not run live model checks.
Create a TaskCreate for Phase 1. Run ALL checks below and report a summary table.
test -f LICENSE && test -f README.md && test -f Cargo.lock
# Each crate must have README.md or readme field in Cargo.toml
git status --porcelain # must be empty
git branch --show-current # must be "main"
git fetch origin && git diff origin/main..HEAD --stat # must be empty
git tag -l "v$VERSION" # must NOT exist
git ls-remote --tags origin "refs/tags/v$VERSION" # must NOT exist
HEAD_SHA=$(git rev-parse HEAD)
gh api repos/OdradekAI/opi/commits/$HEAD_SHA/check-runs \
--jq '.check_runs[] | {name, conclusion}'
ALL required checks must be success for the exact HEAD SHA. If any failure or pending: BLOCKED.
cargo fmt --check --all
cargo clippy --workspace --all-targets -- -D warnings
cargo test --workspace --all-targets
RUSTDOCFLAGS="-D warnings" cargo doc --workspace --no-deps
If --fix flag: run cargo fmt --all and cargo clippy --fix --workspace --allow-dirty first, then re-verify.
cargo audit # if installed
# Verify no git/patch deps, no path deps outside workspace
grep -r '\[patch\]' Cargo.toml # must be empty
# Check internal deps have version field
cargo metadata --format-version 1 --no-deps | jq '.packages[].dependencies[] | select(.path != null) | .req'
# No secrets in tracked files
git ls-files '*.env' '*.key' '*.pem' '*.p12' '*.pfx' # must be empty
grep -rn 'AKIA\|sk-\|ghp_\|glpat-' --include='*.rs' --include='*.toml'
If rust-version is set in workspace, verify: cargo +<msrv> check --workspace. If not set, emit WARN.
# Each crate has description, license, repository
cargo metadata --format-version 1 --no-deps | jq '.packages[] | {name, description, license, repository}'
# Verify auth
test -f ~/.cargo/credentials.toml || test -n "$CARGO_REGISTRY_TOKEN"
# Verify ownership (will fail for first-time publish — handle gracefully)
for crate in opi-ai opi-tui opi-agent opi-coding-agent; do
cargo owner --list $crate 2>/dev/null || echo "NEW_CRATE:$crate"
done
# Version not already published
cargo search opi-ai --limit 1 | grep -v "$VERSION"
for crate in opi-ai opi-tui opi-agent opi-coding-agent; do
cargo package -p $crate --list 2>/dev/null
done
Verify: no files >1MB, no .env/IDE configs, total <5MB per crate.
LAST_TAG=$(git describe --tags --abbrev=0 --match='v*' 2>/dev/null || echo "")
if [ -n "$LAST_TAG" ]; then
git log "$LAST_TAG"..HEAD --pretty=format:'%s' | grep -E '^(feat!|BREAKING)'
fi
Warn if version bump doesn't match commit types (breaking→major, feat→minor, fix→patch).
cargo run -p opi-coding-agent -- --version 2>/dev/null
If no --version flag exists: BLOCKED — prerequisite not met.
After auto-fix, commit changes and re-verify clean state:
git add -A && git commit -m "chore: pre-release auto-fix"
git status --porcelain # must be empty
Output a summary table:
Check | Status | Details
--------------------|----------|--------
File Presence | PASS |
Git State | PASS |
CI Status | PASS | All checks passed for <sha>
Code Quality | PASS/FAIL|
Tests | PASS |
Security | PASS |
Dependencies | PASS |
MSRV | WARN |
Package Content | PASS |
Release Metadata | PASS |
Crate Ownership | PASS |
Version Semantics | WARN |
CLI --version | PASS |
If any critical check FAIL: BLOCKED. If all critical pass: ask user to proceed to Phase 2.
Create a TaskCreate for Phase 2.
VERSION="$1" # from skill argument
# Update workspace.package.version
sed -i "s/^version = \".*\"/version = \"$VERSION\"/" Cargo.toml
# Update ALL internal [workspace.dependencies] version fields
# e.g., opi-ai = { path = "crates/opi-ai", version = "=0.1.0" } → version = "=$VERSION"
cargo check --workspace # verify update is valid
Show diff of changed lines to user.
After version bump, validate each crate can be packaged:
# Compute publish order from cargo metadata
ORDER=$(cargo metadata --format-version 1 --no-deps | \
jq -r '.packages[] | select(.publish == null or .publish != []) | .name')
for crate in $ORDER; do
cargo publish --dry-run -p $crate
done
If dry-run fails: BLOCKED — revert with git checkout -- Cargo.toml.
Create a TaskCreate for Phase 3.
LAST_TAG=$(git describe --tags --abbrev=0 --match='v*' 2>/dev/null || echo "")
if [ -n "$LAST_TAG" ]; then
git log "$LAST_TAG"..HEAD --pretty=format:'%H|%s|%an'
else
git log --pretty=format:'%H|%s|%an'
fi
Parse and group:
feat: → Addedfix: → Fixedperf: → Performancedocs: → Documentationrefactor: → ChangedBREAKING CHANGE / feat!: → Breaking Changeschore: → omit from changelogGenerate CHANGELOG.md entry (Keep a Changelog format):
## [<version>] - YYYY-MM-DD
### Breaking Changes
- Description ([#N](https://github.com/OdradekAI/opi/issues/N))
### Added
- Description
### Fixed
- Description
Extract #<number> from commits and link to GitHub issues/PRs.
Prepend new entry to CHANGELOG.md (create file if missing).
Also generate GitHub Release notes (same content, for --notes-file).
Create a TaskCreate for Phase 4.
Ask user which build strategy to use:
release.yml workflow builds all 6 targets in CI and uploads them to the GitHub Release automatically.cross. Use when CI is unavailable or for pre-CI verification.--skip-cross) — Source-only release, no binary artifacts.cargo build --release --workspace
cargo test --release --workspace
HOST=$(rustc -vV | grep host | awk '{print $2}')
cross --version 2>/dev/null # check if cross is available
Determine buildable targets based on host:
| Target | Buildable when |
|---|---|
x86_64-unknown-linux-gnu | Linux host OR cross available |
aarch64-unknown-linux-gnu | cross available |
x86_64-apple-darwin | macOS host only |
aarch64-apple-darwin | macOS host only |
x86_64-pc-windows-msvc | Windows host OR cargo-xwin |
aarch64-pc-windows-msvc | Windows arm64 host or CI |
Report which targets will be built and which are skipped.
If --skip-cross: only build native platform.
For each buildable target:
# Native target
cargo build --release --target $TARGET -p opi-coding-agent
# Cross target (using cross)
cross build --release --target $TARGET -p opi-coding-agent
All build artifacts go into release-artifacts/v$VERSION/.
mkdir -p release-artifacts/v$VERSION
# Linux/macOS: tar.gz
tar -czf release-artifacts/v$VERSION/opi-$PLATFORM.tar.gz -C target/$TARGET/release opi README.md LICENSE
# Windows: zip
zip release-artifacts/v$VERSION/opi-$PLATFORM.zip target/$TARGET/release/opi.exe README.md LICENSE
# Checksums (local integrity verification, NOT uploaded to GitHub Release)
cd release-artifacts/v$VERSION && sha256sum opi-*.tar.gz opi-*.zip > SHA256SUMS.txt
For each archive in release-artifacts/v$VERSION/:
./opi --version, confirm output = target versionfile commandcd release-artifacts/v$VERSION && sha256sum -c SHA256SUMS.txtCreate a TaskCreate for Phase 5.
"Phase 5 will push a release commit and tag to origin/main. This is publicly visible immediately. The draft release itself is private, but the commit and tag are not. Proceed?"
Wait for explicit user confirmation.
git add Cargo.toml Cargo.lock CHANGELOG.md
git commit -m "chore: release v$VERSION"
git tag -a "v$VERSION" -m "Release v$VERSION"
git push origin main --follow-tags
gh release create "v$VERSION" \
--draft \
--title "v$VERSION" \
--notes-file release-notes.md \
release-artifacts/v$VERSION/opi-*.tar.gz \
release-artifacts/v$VERSION/opi-*.zip
Only upload archive files (tar.gz/zip). Do NOT upload SHA256SUMS.txt to GitHub Release. Only include archives that were actually built (skip unavailable targets).
CI-driven strategy: If using CI-driven builds, create the draft release with only the release notes (no local artifacts). After the tag push triggers release.yml, CI builds all 6 targets and uploads them via gh release upload --clobber. Wait for the workflow to complete before proceeding to Phase 7:
gh run list --workflow=release.yml --branch="v$VERSION" --limit=1 --json status
Show draft release URL and ask:
"Draft GitHub Release v created at . Please review. If correct, I'll proceed with the IRREVERSIBLE crates.io publish. Continue?"
Do NOT proceed to Phase 6 without explicit user approval.
Create a TaskCreate for Phase 6.
cargo metadata --format-version 1 --no-deps | \
jq '[.packages[] | select(.manifest_path | startswith("'$(pwd)'")) | {name, deps: [.dependencies[] | select(.path != null) | .name]}]'
Build dependency graph → topological sort → publish in batches.
Exclude crates with publish = false.
Expected order (computed dynamically, not hardcoded):
opi-ai, opi-tui (no internal deps)opi-agent (depends on Batch 1)opi-coding-agent (depends on Batch 1 & 2)for crate in $BATCH; do
cargo publish -p $crate
done
# Wait 30s between batches for crates.io index propagation
sleep 30
cargo search $crate --limit 1 | grep "$VERSION"
Auto-retryable (up to 3 attempts, exponential backoff):
NOT auto-retryable (require user decision):
cargo publish explicit error (missing field, dep not found)If publish fails mid-batch, present options to user:
"cargo publish -p failed: . Already published: . Options:
- Retry — fix the issue and retry this crate
- Wait & retry — wait 60s for index propagation then retry
- Yank & abort — yank all published crates, abort release
- Continue later — save progress, exit skill
Choose:"
Do NOT auto-retry on explicit errors. Use AskUserQuestion for this gate.
Create a TaskCreate for Phase 7.
gh release edit "v$VERSION" --draft=false
crates.io install test:
cargo install opi-coding-agent --version $VERSION
opi --version # must output $VERSION
GitHub Release asset check:
gh release download "v$VERSION" -D /tmp/opi-verify
# Verify against local checksums
cd /tmp/opi-verify && sha256sum -c ../../../release-artifacts/v$VERSION/SHA256SUMS.txt
# Run binary if native platform
# (unpack native archive, run ./opi --version)
docs.rs build status (all crates):
for crate in opi-ai opi-tui opi-agent opi-coding-agent; do
STATUS=$(curl -s -o /dev/null -w "%{http_code}" "https://docs.rs/$crate/$VERSION")
echo "$crate: $STATUS"
done
Release v<version> complete!
Published crates:
- opi-ai v<version> https://crates.io/crates/opi-ai
- opi-tui v<version> https://crates.io/crates/opi-tui
- opi-agent v<version> https://crates.io/crates/opi-agent
- opi-coding-agent v<version> https://crates.io/crates/opi-coding-agent
GitHub Release: https://github.com/OdradekAI/opi/releases/tag/v<version>
Install: cargo install opi-coding-agent
No side effects. Fix issue and re-run skill.
Clean build artifacts: cargo clean. Fix and retry.
If commit/tag pushed but draft release creation failed:
gh release create --draft (idempotent with same tag)If user rejects the draft release:
gh release delete "v$VERSION" --yes
git push origin :refs/tags/v$VERSION
git tag -d "v$VERSION"
git revert HEAD --no-edit && git push origin main
NEVER use git reset --hard + git push --force automatically.
Already-published crates cannot be unpublished (only yanked). Use the Failure Decision Gate (section 6.5) to let user choose action.
If user chooses "Continue later":
.opi-release-state.json:
{"version": "<version>", "published": ["opi-ai", "opi-tui"], "pending": ["opi-agent"]}
If user chooses "Yank & abort":
for crate in $PUBLISHED; do
cargo yank -p $crate --version $VERSION
done
# Then Phase 5 rollback
On skill invocation, check for .opi-release-state.json:
test -f .opi-release-state.json && cat .opi-release-state.json
If found and version matches argument, ask user:
"Found incomplete release state for v. crates already published. Resume from where it left off?"
If yes, skip to Phase 6 and only publish remaining crates.
cargo (Rust toolchain)cross (optional, for local cross-compilation: cargo install cross)gh (GitHub CLI, authenticated)gitcargo-audit (optional, for security checks).github/workflows/ci.yml — Runs on push/PR to main: fmt, clippy, test, doc. Makes Phase 1.3 meaningful..github/workflows/release.yml — Triggered by v* tags or manual dispatch. Builds all 6 platform targets (linux-x64, linux-arm64, darwin-x64, darwin-arm64, windows-x64, windows-arm64) and uploads to the GitHub Release.After Phase 7 completes (or on abort), remove transient release artifacts:
rm -f release-notes.md
The release-artifacts/v$VERSION/ directory is retained for local reference (checksums, archives). It is in .gitignore and does not pollute the repo.