如何让GitHub Actions在特定条件下跳过后续job的执行?
GitHub Action 多Job按需跳过的优雅解决方案
问题根因
你当前Job级if条件不生效的核心原因是表达式语法错误:你将相等判断逻辑== 'true'放在了${{ }}表达式外部,GitHub Actions无法识别这部分判断规则,会默认将if条件判定为真,因此Job始终会执行。
修正方案
只需要调整两处配置,即可实现无需主动失败、无需逐step加if,不符合条件时直接跳过整个release、deploy Job的效果:
- 把Job级if的所有判断逻辑都包裹到
${{ }}内部,让GitHub Actions可以正确解析条件 - 修复check脚本里的笔误:原脚本最后一行
echo "REPO_ACTIVITY=$days" >> $漏写了目标文件,改为echo "REPO_ACTIVITY=$days" >> $GITHUB_ENV避免运行报错
修正后的完整配置如下:
name: Nightly script on: workflow_dispatch: schedule: - cron: "0 1 * * *" jobs: check-if-there-are-commits: runs-on: ubuntu-latest outputs: alive: ${{ steps.check.outputs.alive }} days: ${{ steps.check.outputs.days }} steps: ### Activity check ### uses GitHub API to check last non-automagic commit in repository ### if it's older than a week, all other steps are skipped - name: Activity check id: "check" run: | curl -sL -H "Authorization: bearer ${{secrets.REPO_BEARER_TOKEN}}" https://api.github.com/repos/$GITHUB_REPOSITORY/commits?sha=dev | jq -r '[.[] | select(.author.type != "Bot")][0]' > $HOME/commit.json echo $GITHUB_REPOSITORY echo $HOME echo $(cat $HOME/commit.json) date="$(jq -r '.commit.author.date' $HOME/commit.json)" echo "Date: $date" timestamp=$(date --utc -d "$date" +%s) echo "Timestamp: $timestamp" echo "Current date: $(date --utc +%s)" echo "Difference between the current date and time of the last commit: $(( ( $(date --utc +%s) - $timestamp ) ))" days=$(( ( $(date --utc +%s) - $timestamp ) / 86400 )) echo "Days: $days" alive=0 echo "Date: $date" echo "timestamp: $timestamp" echo "days: $days" if [ $days -lt 1 ]; then echo Repository active : $days days alive=1 else echo "[WARNING] Repository not updated : event<${{ github.event_name }}> not allowed to modify stale repository" fi echo "Alive? $alive" if [ $alive -eq 1 ]; then echo "REPO_ALIVE=true" >> $GITHUB_ENV echo "::set-output name=alive::true" else echo "REPO_ALIVE=false" >> $GITHUB_ENV echo "::set-output name=alive::false" fi echo "REPO_ACTIVITY=$days" >> $GITHUB_ENV echo "::set-output name=days::$days" release: needs: check-if-there-are-commits # 此处调整了if表达式的包裹范围 if: ${{ needs.check-if-there-are-commits.outputs.alive == 'true' }} runs-on: ubuntu-latest steps: # 所有step都不需要再加if条件,Job不满足条件时会直接跳过所有step - name: "Verify" run: | echo "Alive? ${{needs.check-if-there-are-commits.outputs.alive}}" alive=${{needs.check-if-there-are-commits.outputs.alive}} if [ $alive == "true" ]; then echo "Alive" else echo "Dead" exit 1; fi - name: Next step run: | ... #- other steps... deploy: needs: [check-if-there-are-commits, release] # 此处调整了if表达式的包裹范围 if: ${{ needs.check-if-there-are-commits.outputs.alive == 'true' }} runs-on: ubuntu-latest steps: #- other steps
效果说明
当check job输出的alive为false时,release和deploy job会被直接标记为跳过状态,不会运行任何内部step,也不会产生失败记录,完全符合统一判断、优雅中断的需求。
内容的提问来源于stack exchange,提问作者Patlatus
相关产品推荐
相关产品推荐

