refactor(cli): improve publish-cli script reliability#441
Conversation
- Move version computation and pre-flight checks before build-and-test to fail fast on conflicts (existing branch/tag) instead of wasting minutes on lint/test/build - Add INT/TERM signal handlers to cleanup trap so Ctrl+C during build properly restores working tree state - Update Makefile help text to reflect PR-based workflow
There was a problem hiding this comment.
Code Review
This pull request transitions the CLI release process from a direct tag-and-push model to a more controlled pull-request-based workflow. The scripts/publish-cli.sh script has been significantly overhauled to include local validation steps (lint, typecheck, test, and build), automated version calculation, and PR creation via the GitHub CLI. Additionally, a state-machine-based cleanup mechanism was introduced to handle interruptions. Feedback suggested enhancing the reliability of this cleanup logic by using forced checkouts to ensure the working directory is correctly restored if the script fails after files have been staged.
| git -C "$REPO_ROOT" checkout -- "$PACKAGE_JSON" "$CLI_DIR/src/generated/pkg-info.ts" 2>/dev/null | ||
| git -C "$REPO_ROOT" checkout "$ORIGINAL_BRANCH" 2>/dev/null | ||
| git -C "$REPO_ROOT" branch -D "$RELEASE_BRANCH" 2>/dev/null |
There was a problem hiding this comment.
在 on-release 阶段的清理逻辑存在健壮性问题。如果脚本在 git add 之后但在 git commit 之前失败(例如在 generate-pkg-info.ts 阶段被中断或用户按下 Ctrl+C),git checkout -- <file> 仅会从索引(index)恢复文件。由于更改已被 add 到索引,工作区的更改将不会被撤销。这会导致随后的 git checkout "$ORIGINAL_BRANCH" 因为存在未提交的冲突更改而失败,最终导致脚本无法切回原分支并删除临时分支。建议使用 git checkout -f "$ORIGINAL_BRANCH" 强制切换并丢弃所有本地更改。
| git -C "$REPO_ROOT" checkout -- "$PACKAGE_JSON" "$CLI_DIR/src/generated/pkg-info.ts" 2>/dev/null | |
| git -C "$REPO_ROOT" checkout "$ORIGINAL_BRANCH" 2>/dev/null | |
| git -C "$REPO_ROOT" branch -D "$RELEASE_BRANCH" 2>/dev/null | |
| echo "" >&2 | |
| echo "[publish-cli] error before commit — rolling back release branch" >&2 | |
| git -C "$REPO_ROOT" checkout -f "$ORIGINAL_BRANCH" 2>/dev/null | |
| git -C "$REPO_ROOT" branch -D "$RELEASE_BRANCH" 2>/dev/null |
There was a problem hiding this comment.
已采纳建议并修复。使用 git checkout -f 强制切换分支,移除了冗余的 git checkout -- <file> 操作。这样即使文件已被 git add 到索引但未提交,也能可靠地清理并切回原分支。
修复已提交:4c7285b3
| git -C "$REPO_ROOT" checkout "$ORIGINAL_BRANCH" 2>/dev/null | ||
| git -C "$REPO_ROOT" branch -D "$RELEASE_BRANCH" 2>/dev/null |
There was a problem hiding this comment.
在 committed 阶段同样建议使用 git checkout -f。虽然此时更改已提交,工作区通常是干净的,但使用强制切换可以确保在任何意外情况下(如某些工具在后台修改了文件)都能可靠地返回原始分支并完成清理。
| git -C "$REPO_ROOT" checkout "$ORIGINAL_BRANCH" 2>/dev/null | |
| git -C "$REPO_ROOT" branch -D "$RELEASE_BRANCH" 2>/dev/null | |
| git -C "$REPO_ROOT" checkout -f "$ORIGINAL_BRANCH" 2>/dev/null | |
| git -C "$REPO_ROOT" branch -D "$RELEASE_BRANCH" 2>/dev/null |
There was a problem hiding this comment.
已采纳建议。使用 git checkout -f 增强健壮性,确保在任何意外情况下都能可靠地返回原始分支并完成清理。
修复已提交:4c7285b3
Address code review feedback from gemini-code-assist bot: - Use `git checkout -f` in on-release and committed cleanup stages to ensure reliable branch switching even when files are staged but not committed (e.g., interrupted after `git add` but before `git commit`) - Remove redundant `git checkout -- <file>` in on-release stage since `-f` already discards all local changes This prevents cleanup failures when the script is interrupted between staging and committing.
- Fix ERR trap bypass: remove `if !` wrapper around `gh pr create` so set -e triggers the trap and prints pushed-stage recovery instructions - Fix command injection: all node -e/-p calls now use process.env instead of interpolating shell variables into JS string literals - Rewrite cli/RELEASE.md to document the new PR-based release flow - Rewrite scripts/tests/publish-cli-test.sh with 10 tests covering the new flow (stubs for bun/gh, pre-flight checks, happy path, cleanup state machine stages)
Review findings addressed in efcf0ee
Minor items 5/6/9 (EXIT trap, stderr suppression, trap cleanup inconsistency) are deferred — current code is safe because Tests run: |
Summary
优化
publish-cli.sh脚本的可靠性和用户体验:INT/TERM信号(Ctrl+C),确保中断时正确清理工作树状态改进细节
1. 预检查前移(fail-fast)
之前:
git pull→bun install / lint / typecheck / test / build(几分钟)→ 计算版本 → 检查 tag/branch 是否存在现在:
git pull→ 计算版本 → 检查 tag/branch 是否存在 →bun install / lint / typecheck / test / build如果
release/cli-vX.Y.Z分支或 tag 已存在(比如上次 PR 已合并但还没打 tag),现在会在几秒内报错退出,而不是白跑几分钟构建。2. 信号处理增强
之前:
trap cleanup_on_error ERR— 只捕获命令失败现在:
trap cleanup_on_error ERR INT TERM— 同时捕获 Ctrl+C 和 kill 信号用户在
bun test或bun build阶段按 Ctrl+C 时,cleanup 函数会:cli/src/generated/pkg-info.tsTest plan
bash -n scripts/publish-cli.sh)release/cli-vX.Y.Z分支,验证脚本在 build 前就报错bun test阶段按 Ctrl+C,验证工作树被正确恢复make publish-cli patch(或在测试环境)相关 PR
这是 #422 的后续优化,基于 code review 反馈改进脚本健壮性。