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

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.10 05:14:58