我在 Github Actions 工作中有一个步骤:
- name: Check for changes
run: |
diff=$( git diff --name-only 'origin/main' )
changed_files=$( echo $diff | grep -c src/my_folder ) # this fails
# more script lines
# that are unrelated
仅当 grep 找不到任何内容时,才会失败并显示
Error: Process completed with exit code 1.
。
如果 $diff
中有匹配项,则此步骤按预期进行。但当然它也需要在没有匹配的情况下工作。我可以在本地或在脚本内运行它,没有问题,退出代码始终为
0
(在 Mac 上)。我不明白问题出在哪里。经过几个小时的反复试验和研究,我了解到,显然
grep
在 Github 操作中很棘手,但我没有找到任何提示或正确的文档,我应该如何解决这个确切的情况。如果我将失败的线路更改为
echo $( echo $diff | grep -c src/my_folder ) # this works and prints out the result
这可以毫无问题地执行。
但是即使没有发现结果,如何将 grep 输出放入我的变量中?
doc,默认情况下 Github Actions 允许 set -e
运行步骤的命令。这就是为什么中间命令失败可能导致整个步骤失败的原因。要完全控制步骤的命令,您可以这样做:
- name: Check for changes
shell: bash {0}
#^^^^^^^^^^^^^^
run: |
diff=$( git diff --name-only 'origin/main' )
changed_files=$( echo $diff | grep -c src/my_folder )
# ...
# ...
或者您可以在步骤脚本开头禁用默认的 set -e
:
- name: Check for changes
run: |
set +e
diff=$( git diff --name-only 'origin/main' )
changed_files=$( echo $diff | grep -c src/my_folder )
# ...
# ...
grep
在 Github 操作中存在什么问题,但你可以尝试以下操作:
...
changed_files=$( [ ! -e $diff ] && { echo $diff | grep -c src/my_folder } || echo 0 )
...
这样,如果 $diff 为空, grep 将不会运行。它只会将 0 存储在 $changed_files
dorny/paths-filter 操作,例如:
- uses: dorny/paths-filter@v2
id: changes
with:
filters: |
src:
- 'src/my_folder/**'
# run only if some file in 'src/my_folder' folder was changed
- if: steps.changes.outputs.src == 'true'
run: ...
检查