GitHub Action中grep校验SemVer版本始终返回状态码1的解决方法
问题:GitHub Action中grep校验SemVer版本始终返回状态码1
我在GitHub工作流里用grep检查项目版本是否符合SemVer规范,本地Shell脚本能正常工作:当TAG_EXISTS是"v3.0.12"时返回1(不匹配),是"3.0.12"时返回0(匹配),但迁移到GitHub Action后不管怎样都返回状态码1,没法正常获取grep结果或判断退出码。
本地测试脚本
TAG_EXISTS="v3.0.12" SEMVER="^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$" grep -oE "$SEMVER" <<< "$TAG_EXISTS" ISSEMVER="$?" echo "$ISSEMVER"
迁移后的GitHub工作流代码
checkVersion: needs: tests runs-on: ubuntu-latest steps: - name: Checkout Repository uses: actions/checkout@v3 - name: Set up Python uses: actions/setup-python@v2 with: python-version: 3.x # 其他无关步骤省略 - name: Check for Existing Tag id: check_tag run: | set +x TAG_EXISTS=3.0.14 SEMVER="^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$" grep -oE "$SEMVER" <<< "$TAG_EXISTS" ISSEMVER="$?" echo "$ISSEMVER"
我需要实现的效果是:grep未匹配时GitHub Action失败,匹配时通过。试过用子shell方式RESULT=$( echo "$TAG_EXISTS" | grep -oE "$SEMVER"),但流水线还是一直失败返回状态码1,求解决办法。
解决办法
问题根源
GitHub Action的run步骤默认开启了errexit模式,脚本中任何命令返回非0状态码都会直接终止脚本并标记步骤失败。你的grep命令未匹配时返回1,会直接触发步骤失败,后续的退出码捕获逻辑根本无法执行。
方案1:用静默grep配合逻辑判断
使用grep -qE(静默模式,仅返回退出码),直接根据结果决定步骤状态:
TAG_EXISTS=3.0.14 SEMVER="^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$" if grep -qE "$SEMVER" <<< "$TAG_EXISTS"; then echo "版本符合SemVer规范" else echo "版本不符合SemVer规范" exit 1 # 主动抛出非0码,标记步骤失败 fi
方案2:临时关闭errexit捕获退出码
如果需要先获取退出码再做其他操作,可以暂时关闭errexit模式:
set +e # 关闭命令失败即终止脚本的模式 TAG_EXISTS=3.0.14 SEMVER="^(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$" grep -oE "$SEMVER" <<< "$TAG_EXISTS" ISSEMVER="$?" set -e # 恢复errexit模式 echo "$ISSEMVER" if [ "$ISSEMVER" -ne 0 ]; then exit 1 fi
额外优化:兼容带v前缀的版本
如果需要支持v3.0.12这种带前缀的版本,修改正则表达式允许开头的v即可:
SEMVER="^v?(0|[1-9]\d*)\.(0|[1-9]\d*)\.(0|[1-9]\d*)(?:-((?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*)(?:\.(?:0|[1-9]\d*|\d*[a-zA-Z-][0-9a-zA-Z-]*))*))?(?:\+([0-9a-zA-Z-]+(?:\.[0-9a-zA-Z-]+)*))?$"
内容的提问来源于stack exchange,提问作者Joe 010
相关产品推荐
相关产品推荐

