发布 crate 到 crates.io,发布前自动检查测试、增量覆盖率和工作区状态
git status --porcelain
如果工作区不干净(有未提交的变更或未跟踪文件):
git status 给用户看AskUserQuestion 询问:
从 Cargo.toml 读取当前版本号,检查对应的 git tag 是否已存在。
# 读取 Cargo.toml 中的版本号
VERSION=$(grep '^version' Cargo.toml | head -1 | sed 's/.*"\(.*\)"/\1/')
echo "当前版本:$VERSION"
# 检查 tag 是否已存在
git tag -l "v$VERSION"
如果 tag v<version> 已存在:
tag v<version> 已存在,请先 bump 版本号再发布如果 tag 不存在:继续下一步。
cargo test 2>&1
如果测试失败:
cargo clippy -- -D warnings 2>&1
如果 clippy 有警告:
检查相对于上一个 tag(或上一次发布版本)的增量代码覆盖率。
# 获取最近的 tag 作为基线
git describe --tags --abbrev=0 2>/dev/null || echo "NO_TAG"
如果没有 tag,以最近 10 次提交的 diff 作为增量范围。
# 获取相对于基线的变更文件(仅 src/ 下的 .rs 文件)
git diff <baseline>..HEAD --name-only -- 'src/**/*.rs'
# 获取具体变更行
git diff <baseline>..HEAD --unified=0 -- 'src/**/*.rs'
从 diff 中提取每个文件的新增行号范围(以 + 开头的行,排除文件头)。
cargo tarpaulin --out json --output-dir /tmp/xone-cov --skip-clean 2>&1
如果 tarpaulin 未安装,提示用户:
cargo-tarpaulin 未安装,无法检查覆盖率。
安装命令:cargo install cargo-tarpaulin
然后使用 AskUserQuestion 询问:
从 tarpaulin JSON 报告中,只统计增量行(步骤 4.2 提取的新增行)的覆盖情况:
增量覆盖率 = 增量行中被覆盖的行数 / 增量行总数 × 100%
输出格式:
增量覆盖率报告:
变更文件数:N
增量代码行:M
已覆盖行:K
增量覆盖率:XX.X%
如果增量覆盖率 < 60%:
# 检查 Cargo.toml 必填字段
cargo package --list 2>&1 | head -5
确认以下字段存在且非空:
nameversiondescriptionlicense 或 license-filerepositorycargo publish --dry-run 2>&1
如果 dry-run 失败:
使用 AskUserQuestion 最终确认:
显示以下信息并询问:
即将发布到 crates.io:
包名:<name>
版本:<version>
描述:<description>
注意:发布后版本号不可重用,确认发布?
cargo publish 2>&1
如果发布成功:
git tag v<version>git push origin v<version>如果发布失败:
403:运行 cargo login 重新登录verified email:到 crates.io/settings/profile 验证邮箱already uploaded:版本号已存在,需要 bump 版本发布成功!
包名:x-one
版本:v<version>
地址:https://crates.io/crates/x-one
/publish # 执行完整发布流程