fix(deploy): AC11 reject unknown args + add --help/--dry-run (no side effects on error paths)
This commit is contained in:
+58
-6
@@ -16,7 +16,28 @@ set -euo pipefail
|
||||
REPO_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
|
||||
BIN_DIR="${BIN_DIR:-/home/muc/bin}"
|
||||
|
||||
# --allow-dirty:显式承担「把在途改动编进生产二进制」的风险(默认拒绝)
|
||||
# 用法/帮助(t_debe2002 AC11):--help 打印用法后 exit 0,不构建不停止服务;
|
||||
# 未知参数(--help2/--foo/空串)打印用法 + exit 2,绝不进入部署流程。
|
||||
# 背景:AC11 由验收在评审时亲自踩到 —— 原先未知参数被静默忽略后走完整部署
|
||||
# (一个手滑的 --help 就触发一次「构建+停服务+重启+7分钟CPU尖峰」)。
|
||||
# 本脚本的主题正是「错误路径上不应有副作用」,未知参数是被忽略后触发完整部署
|
||||
# = 同类缺陷的入口版,故必须拒绝。
|
||||
usage() {
|
||||
cat <<'EOF'
|
||||
用法:
|
||||
./scripts/deploy.sh 完整部署: 构建两+装两+停两+启两+校验
|
||||
./scripts/deploy.sh --help 打印本用法后退出(不构建/不停止/不启动)
|
||||
./scripts/deploy.sh --dry-run 跑前置闸门 + 打印将执行的动作后退出(不写/不停/不启)
|
||||
./scripts/deploy.sh --verify 只校验「运行二进制 sha ∈ 部署清单」的自证版本(独立动作,不构建)
|
||||
./scripts/deploy.sh --verify-only 只跑全量校验(不构建/不安装/不重启)—— 反例测试/人工体检用
|
||||
./scripts/deploy.sh --mark-approved 评审通过后把当前 HEAD 追加进已批准部署清单(独立动作)
|
||||
./scripts/deploy.sh --allow-unreviewed 显式承担「构建范围含未评审提交」的风险(默认拒绝)
|
||||
./scripts/deploy.sh --allow-dirty 显式承担「把在途改动编进生产二进制」的风险(默认拒绝)
|
||||
make deploy = ./scripts/deploy.sh
|
||||
未知参数 → 打印本用法 + exit 2(t_debe2002 AC11:手滑的参数不得触发一次无人要的部署重启)。
|
||||
EOF
|
||||
}
|
||||
|
||||
ALLOW_DIRTY=0
|
||||
# --allow-unreviewed:显式承担「把未经评审的提交编进生产」的风险(默认拒绝)
|
||||
ALLOW_UNREVIEWED=0
|
||||
@@ -24,11 +45,23 @@ ALLOW_UNREVIEWED=0
|
||||
MARK_APPROVED=0
|
||||
# --verify:只校验「运行二进制 sha ∈ 部署清单」的自证版本(AC8 选项3,独立动作,不构建/不安装/不重启)
|
||||
VERIFY_MANIFEST=0
|
||||
# --verify-only:只跑全量校验(AC1-AC10 时代即有的独立动作,不构建/不安装/不重启)
|
||||
VERIFY_ONLY=0
|
||||
# --dry-run:跑前置闸门 + 打印将执行的动作,不写/不停/不启(AC11)
|
||||
DRY_RUN=0
|
||||
for _a in "$@"; do
|
||||
[ "$_a" = "--allow-dirty" ] && ALLOW_DIRTY=1
|
||||
[ "$_a" = "--allow-unreviewed" ] && ALLOW_UNREVIEWED=1
|
||||
[ "$_a" = "--mark-approved" ] && MARK_APPROVED=1
|
||||
[ "$_a" = "--verify" ] && VERIFY_MANIFEST=1
|
||||
case "$_a" in
|
||||
--help) usage; exit 0 ;;
|
||||
--dry-run) DRY_RUN=1 ;;
|
||||
--allow-dirty) ALLOW_DIRTY=1 ;;
|
||||
--allow-unreviewed) ALLOW_UNREVIEWED=1 ;;
|
||||
--mark-approved) MARK_APPROVED=1 ;;
|
||||
--verify) VERIFY_MANIFEST=1 ;;
|
||||
--verify-only) VERIFY_ONLY=1 ;;
|
||||
# t_debe2002 AC11:未知参数(含 --help2/--foo/空串)→ 打印用法 + exit 2,绝不进入部署流程。
|
||||
# 用独立的 unknown() 而非 die(),因为 die 固定 exit 1,而 AC11 要求未知参数 exit 2。
|
||||
*) printf '\033[1;31m[deploy:FAIL]\033[0m 未知参数: %s\n' "$_a" >&2; usage >&2; exit 2 ;;
|
||||
esac
|
||||
done
|
||||
|
||||
# 构建产物(持久路径,均已 gitignore)
|
||||
@@ -305,7 +338,8 @@ if [ "$VERIFY_MANIFEST" = "1" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
if [ "${1:-}" = "--verify-only" ]; then
|
||||
# --verify-only:只跑全量校验(不构建/不安装/不重启)—— 反例测试/人工体检用
|
||||
if [ "$VERIFY_ONLY" = "1" ]; then
|
||||
do_verify
|
||||
exit 0
|
||||
fi
|
||||
@@ -324,6 +358,24 @@ if [ "$MARK_APPROVED" = "1" ]; then
|
||||
exit 0
|
||||
fi
|
||||
|
||||
# --dry-run(t_debe2002 AC11):跑前置闸门 + 打印将执行的动作后退出 —— 不写文件/不停止/不启动。
|
||||
# 先跑 preflight_reviewed_commits + preflight_clean_tree(纯只读检查):若部署会被闸门拦下,
|
||||
# 这里就真实报出(die exit=1),让 dry-run 成为「这次部署能否通过」的预览;
|
||||
# 通过则打印完整动作清单后 exit 0,绝不触碰生产。
|
||||
if [ "$DRY_RUN" = "1" ]; then
|
||||
preflight_reviewed_commits
|
||||
preflight_clean_tree
|
||||
log "dry-run:以下为完整部署将执行的动作(本次不写/不停/不启)——"
|
||||
log " · 构建: go build → $BUILD_GO"
|
||||
log " · 构建: cargo build --release → $BUILD_RUST"
|
||||
log " · 停止: $SVC_GO + $SVC_RUST"
|
||||
log " · install: → $INSTALL_GO + $INSTALL_RUST"
|
||||
log " · daemon-reload + 启动: $SVC_GO + $SVC_RUST"
|
||||
log " · 校验: 服务 active / 无(deleted) inode / 运行sha=构建sha / /health=200 / bi-temporal e2e / 自证版本"
|
||||
log "dry-run 结束(未执行任何部署动作)"
|
||||
exit 0
|
||||
fi
|
||||
|
||||
do_build
|
||||
do_install
|
||||
do_verify
|
||||
Reference in New Issue
Block a user