You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何让GitHub Action在find调用protoc失败时终止并标记为失败?

解决GitHub Action中protoc失败不终止的问题

问题根源

你当前的命令里,find工具的-exec选项默认不会把protoc的非零退出码传递给自己——哪怕某个.proto文件编译失败,find本身依然会返回成功状态码(0),导致整个命令链的退出码为0,GitHub Action因此会标记为执行成功,忽略protoc的错误。

解决方案

下面提供两种可靠的修改方式,既能保留错误输出,又能在protoc失败时立即终止Action并标记为失败:

方法一:让find检测protoc的退出码并终止执行

通过sh -c包裹protoc命令,让子shell返回protoc的真实退出码,同时用find的-quit选项在命令失败时停止遍历并返回错误:

echo "Compiling..." && find $GEN_PROTO_DIR -type f -name "*.proto" -exec sh -c '
  protoc \
    --go_out=$GEN_OUT_DIR --go_opt=module=github.com/xefino \
    --go-grpc_out=$GEN_OUT_DIR --go-grpc_opt=module=github.com/xefino \
    --grpc-gateway_out=$GEN_OUT_DIR --grpc-gateway_opt logtostderr=true \
    --grpc-gateway_opt paths=source_relative --grpc-gateway_opt generate_unbound_methods=true "$1"
  exit $?
' sh {} \; -quit
  • sh -c创建子shell执行protoc,执行完成后返回protoc的退出码
  • -quit让find在-exec命令返回非零码时立即停止遍历,同时find本身会返回非零状态码,触发GitHub Action失败

方法二:改用while循环遍历文件(更直观的错误控制)

用find输出文件列表,通过while循环逐个编译,直接检测每个protoc的执行状态,失败时立即退出:

echo "Compiling..." && while IFS= read -r -d '' proto_file; do
  protoc \
    --go_out=$GEN_OUT_DIR --go_opt=module=github.com/xefino \
    --go-grpc_out=$GEN_OUT_DIR --go-grpc_opt=module=github.com/xefino \
    --grpc-gateway_out=$GEN_OUT_DIR --grpc-gateway_opt logtostderr=true \
    --grpc-gateway_opt paths=source_relative --grpc-gateway_opt generate_unbound_methods=true "$proto_file"
  
  # 检测protoc是否执行失败
  if [ $? -ne 0 ]; then
    echo "编译失败:$proto_file"
    exit 1
  fi
done < <(find $GEN_PROTO_DIR -type f -name "*.proto" -print0)
  • -print0和read -d ''组合用于处理包含空格、特殊字符的文件名,避免遍历出错
  • 每次编译后检测退出码,失败时打印错误信息并立即退出,确保GitHub Action捕获到失败状态

内容的提问来源于stack exchange,提问作者Woody1193

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.03 17:56:06