如何配置GitHub Workflow,无变更推送时避免执行失败?
问题描述
我想自动化一个流程:把指定文件夹里的所有文件列表写入一个文件,用ls ./path/to/mydir > ./path/to/myfile.txt实现了这个功能,对应的GitHub Actions Workflow配置如下:
name: push on: [push] jobs: list-contents: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: ls ./src/content/ > ./src/_content.txt - run: | git config --local user.email "antboehler@gmail.com" git config --local user.name "AntVil" git add ./src/_content.txt git commit -m "update _content.txt" - uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} force: true
这个配置能正常运行,但有个问题:当待提交的文件没有变更时,Workflow会执行失败。我希望在错误发生前终止Workflow,或者跳过后续操作避免报错。我本来想用git diff --exit-code ./src/_content.txt检测是否有变更,再决定是否执行后续Git命令,但作为GitHub Actions新手不知道怎么实现。
编辑:
我自己实现了功能,但想知道有没有更优方案,当前配置如下:
name: push on: [push] jobs: list-contents: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: ls ./src/content/ > ./src/_content.txt - run: if [[ "$(git diff --exit-code src/_content.txt)" =~ 'diff' ]]; then echo "IS_VALID=true" >> $GITHUB_ENV; else echo "IS_VALID=false" >> $GITHUB_ENV ;fi - if: ${{ env.IS_VALID == 'true' }} run: | git config --local user.email "antboehler@gmail.com" git config --local user.name "AntVil" git add ./src/_content.txt git commit -m "update _content.txt" - if: ${{ env.IS_VALID == 'true' }} uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} force: true
优化方案
你的实现思路没问题,但可以简化逻辑,不用正则匹配diff字符串,直接利用git diff --exit-code的退出状态码判断会更可靠:
方案1:简化环境变量设置
git diff --exit-code在文件有变更时返回非0值,无变更时返回0。直接用命令的退出状态设置环境变量,避免正则匹配的潜在问题:
name: push on: [push] jobs: list-contents: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: ls ./src/content/ > ./src/_content.txt # 有变更时才设置HAS_CHANGES为true - run: git diff --exit-code src/_content.txt || echo "HAS_CHANGES=true" >> $GITHUB_ENV - if: ${{ env.HAS_CHANGES == 'true' }} run: | git config --local user.email "antboehler@gmail.com" git config --local user.name "AntVil" git add ./src/_content.txt git commit -m "update _content.txt" - if: ${{ env.HAS_CHANGES == 'true' }} uses: ad-m/github-push-action@master with: github_token: ${{ secrets.GITHUB_TOKEN }} force: true
方案2:合并步骤,减少冗余
把判断和Git操作合并到同一个步骤里,省去环境变量传递,流程更简洁:
name: push on: [push] jobs: list-contents: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - run: ls ./src/content/ > ./src/_content.txt - run: | # 检测文件是否有变更,无变更则跳过后续操作 if git diff --exit-code src/_content.txt; then echo "No changes to _content.txt, skipping commit and push" else git config --local user.email "antboehler@gmail.com" git config --local user.name "AntVil" git add ./src/_content.txt git commit -m "update _content.txt" # 直接执行推送 git push https://x-access-token:${{ secrets.GITHUB_TOKEN }}@github.com/${{ github.repository }}.git fi
补充说明
- 用
git diff --exit-code比正则匹配更稳定,不会因为输出格式变化或特殊字符导致判断失误。 - 方案2里的推送地址是为了避免手动输入凭据,直接用
GITHUB_TOKEN授权推送。
内容的提问来源于stack exchange,提问作者Anton
相关产品推荐
相关产品推荐

