- Published on
GitHub Actions 分支條件判斷踩雷記錄
- Authors
- Name
在使用 GitHub Actions 時,一直 skip job,直到多寫一個 debug 的 job 才釐清,本文記錄了一次實際遇到的問題和解決過程。
問題場景:Job 被 Skip
在 GitHub Actions 工作流程中,我想要在特定分支 feat/fix-prod-e2e
上完整跑完 workflow
修正前的 yaml 檔案:
# main.yml
test-dev-site:
runs-on: ubuntu-latest
container:
image: ghcr.io/puppeteer/puppeteer:24.3.0
env:
TO_TEST_SITE: DEV_SITE
steps:
- uses: actions/checkout@v4
- name: Install
run: |
npm install
- name: Test
run: |
npm test
- name: Rsync jest html reports
if: github.ref == 'refs/heads/feat/fix-prod-e2e'
uses: ./.github/rsync-action
新增 Debug ref Job
因爲修改的過程中 CI 一直 fail,為了釐清問題,多寫了一個 Debug ref 的 job
- name: Debug ref
run: |
echo "github.ref: ${{ github.ref }}"
echo "github.ref_name: ${{ github.ref_name }}"
echo "github.head_ref: ${{ github.head_ref }}"
印出結果
github.ref: refs/pull/58/merge
github.ref_name: 58/merge
github.head_ref: feat/fix-prod-e2e
意外的發現
印出結果顯示:github.ref
的值是 'refs/pull/58/merge'
,而不是預期的 'refs/heads/feat/fix-prod-e2e'
當在 Pull Request 中觸發 GitHub Actions 時,GitHub 會建立一個虛擬的合併參考:
github.ref
=refs/pull/{PR編號}/merge
(PR #58 的合併參考)
只能說自己對 PR 中的 GitHub Actions 的運作跟語法還不夠熟,但這是個蠻不錯的經驗。
驗證前一個 job fail 會導致後續 job 無法執行嗎?
現在有正確的 github.ref: refs/pull/58/merge
,所以故意讓 e2e test case fail,也就是讓 Test job fail,來檢查 Rsync jest html reports
這個 job 會不會被跳過?
驗證結果:只要沒有相依性,前一個 job fail,不會導致後一個 job 跳過,之前一直跳過的原因是 github.ref
寫錯。
cancelled() 函數說明
在修改成需求所要求的 yaml 前,先解釋一下條件中的 cancelled()
函數:
功能說明
- 回傳值: Boolean (true/false)
- true: 當工作流程被手動取消或因為其他原因被中止時
- false: 當工作流程正常執行時
常見的條件組合
# 總是執行(除非被取消)
if: !cancelled()
# 只在成功時執行
if: success()
# 只在失敗時執行
if: failure()
# 成功或失敗都執行,但不包括取消的情況
if: !cancelled()
# 總是執行(包括取消的情況)
if: always()
在範例中使用 !cancelled()
只要工作流程沒被取消,無論測試是否通過,都會跑 Rsync jest html reports
上傳 test report。
修正結果
feat/fix-prod-e2e (PR 編號 58)
if: (!cancelled()) && github.head_ref == ''refs/pull/58/merge''
Production
if: (!cancelled()) && github.head_ref == 'ref/head/main'
總結 & 要注意的小地方
- 找問題時可以新增一個 Debug job,印出變數值,快速釐清問題點。
- 只要沒有相依性,前一個 job fail,不會導致後一個 job 跳過。
github.ref
會指向 merge ref,並非發 PR 的分支 (github.ref: refs/pull/58/merge
)。github.head_ref
才是分支名稱 (github.head_ref: feat/fix-prod-e2e
)。!cancelled()
:只要不是「取消」,無論成功或失敗都執行。- Github Action 的介面,外層顯示執行時間為 0 秒,但實際上點開看詳細資料,表示有跑該 job,所以要注意並不是 0 秒就沒有執行。