MacOS环境下GitHub Action执行curl/grep命令报错(退出码1)求助
解决GitHub Action在MacOS环境下获取标签失败的问题
问题背景
我正在编写自定义GitHub Workflow,通过curl和grep命令获取指定仓库的标签,目标仓库为MathieuSoysal/Hiden-dependancy-updater。
核心action.yml代码
- name: get new tag id: get_new_tag shell: bash run: | temp_result=$(curl -s https://api.github.com/repos/${{inputs.github_repository}}/tags | grep -h "name" | grep -h "${{inputs.selector}}" | head -1 | grep -ho "${{inputs.regex}}") echo "new-tag=${temp_result}" >> $GITHUB_OUTPUT
测试Workflow配置
uses: ./ with: files: tests/test1.txt tests/test2.txt github_repository: MathieuSoysal/file-updater-for-release prefix: MathieuSoysal/file-updater-for-release@
MacOS环境下的错误信息
temp_result=$(curl -s https://api.github.com/repos/MathieuSoysal/file-updater-for-release/tags | grep -h "name" | grep -h "" | head -1 | grep -ho "v\?[0-9.]*") echo "new-tag=${temp_result}" >> $GITHUB_OUTPUT shell: /bin/bash --noprofile --norc -e -o pipefail {0} Error: Process completed with exit code 1.
问题原因
MacOS自带的是BSD版本grep,与Linux环境下的GNU grep参数行为存在差异:
grep -h ""空匹配在BSD grep中会返回非零退出码,而GNU grep会匹配所有行-o参数的匹配逻辑细节不同,可能导致预期外的结果- 开启
pipefail后,管道中任意一步出错都会导致整个命令返回退出码1,直接触发Action失败
解决方案
方案1:改用jq解析JSON(推荐)
GitHub API返回标准JSON结构,用jq提取标签比grep更稳定可靠,彻底避免跨平台grep差异问题:
- name: get new tag id: get_new_tag shell: bash run: | # 根据selector是否存在,过滤并提取第一个匹配的标签 if [ -n "${{inputs.selector}}" ]; then tag_name=$(curl -s https://api.github.com/repos/${{inputs.github_repository}}/tags | jq -r --arg sel "${{inputs.selector}}" '.[] | select(.name | contains($sel)) | .name' | head -1) else tag_name=$(curl -s https://api.github.com/repos/${{inputs.github_repository}}/tags | jq -r '.[0].name') fi # 用正则提取版本号部分 temp_result=$(echo "$tag_name" | grep -Eo "${{inputs.regex}}") echo "new-tag=${temp_result}" >> $GITHUB_OUTPUT
注:GitHub托管的MacOS Runner默认已安装jq,无需额外配置。
方案2:替换为GNU grep
在MacOS环境中安装GNU grep(别名ggrep),统一使用GNU版本的命令:
- name: Install GNU grep (MacOS) if: runner.os == 'macOS' run: brew install grep - name: get new tag id: get_new_tag shell: bash run: | # 根据系统选择grep或ggrep GREP_CMD=$(if [ "$RUNNER_OS" = "macOS" ]; then echo "ggrep"; else echo "grep"; fi) temp_result=$(curl -s https://api.github.com/repos/${{inputs.github_repository}}/tags | $GREP_CMD -h "name" | $GREP_CMD -h "${{inputs.selector}}" | head -1 | $GREP_CMD -ho "${{inputs.regex}}") echo "new-tag=${temp_result}" >> $GITHUB_OUTPUT
方案3:处理空selector的情况
避免执行grep -h ""这种可能出错的命令,先判断selector是否为空:
- name: get new tag id: get_new_tag shell: bash run: | curl_result=$(curl -s https://api.github.com/repos/${{inputs.github_repository}}/tags) if [ -n "${{inputs.selector}}" ]; then filtered=$(echo "$curl_result" | grep -h "name" | grep -h "${{inputs.selector}}" | head -1) else filtered=$(echo "$curl_result" | grep -h "name" | head -1) fi temp_result=$(echo "$filtered" | grep -ho "${{inputs.regex}}") echo "new-tag=${temp_result}" >> $GITHUB_OUTPUT
内容的提问来源于stack exchange,提问作者ThrowsError
相关产品推荐
相关产品推荐

