這一篇的內容,回到基礎的 GitLab CI/CD YAML 語法,這次要談關於 CI/CD YAML 的 workflow
,workflow
這個語法主要在控制整個 Pipeline 的行為,可以控制的部分分為三種類型,分別是:基本控制、條件控制以及自動取消條件三種。
workflow
的基本控制一般情況下,在 Pipelines 的列表下,其 Pipeline 的名稱會以當下的 commit message 來呈現,但有時候為了好分辨 Pipeline 來自什麼分支或 Pipeline 的功能,可能會需要讓 Pipeline 有一個好識別的名稱,這時候就可以使用 workflow:name
。
以底下第一個範例:
workflow:
name: 'Pipeline for branch: $CI_COMMIT_BRANCH'
當建立 Pipeline 之後,如此次的範例分支 day29_01_workflow_name
,在列表上會呈現 Pipeline for branch: day29_01_workf...
。如下圖上方的 Pipeline。
而稍微複雜一點的案例甚至可以依據後續會介紹的 workflow:rules
在 rules
中設定變數,並且在 workflow:name
中使用該變數,如此設定,pipeline 就可以依據不一樣的條件有不一樣的名稱。如 GitLab 官方手冊上的範例:
variables:
PROJECT1_PIPELINE_NAME: 'Default pipeline name' # A default is not required
workflow:
name: '$PROJECT1_PIPELINE_NAME'
rules:
- if: '$CI_MERGE_REQUEST_LABELS =~ /pipeline:run-in-ruby3/'
variables:
PROJECT1_PIPELINE_NAME: 'Ruby 3 pipeline'
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
variables:
PROJECT1_PIPELINE_NAME: 'MR pipeline: $CI_MERGE_REQUEST_SOURCE_BRANCH_NAME'
- if: $CI_COMMIT_BRANCH == $CI_DEFAULT_BRANCH # For default branch pipelines, use the default name
workflow:name
使用變數 $PROJECT1_PIPELINE_NAME
變數數值為什麼,Pipeline 名稱就是什麼。因此當 rules
的條件成立時,設定好變數,則 Pipeline 的名稱就會是什麼。 值得注意的,當變數名稱為空字串時,GitLab 會預設呈現預設值,最後一個 commit 的訊息名稱。
workflow:rules
條件控制CI/CD YAML 的 workflow:rules
其使用的方法與之前介紹的 Job 層級的 rules
是類似的,可以使用 if
、changes
、exists
、variables
及when
這些關鍵字。不過 when
目前只支援 always
、never
。
CI/CD YAML 的 workflow:rules:variables
語法,與 rules:variables
是一樣的,當 rules 條件成立時,則建立該對應的變數,不過這邊定義的變數,可以供 Pipeline 中的所有 Job 使用。另外,在定義變數時,也可以使用 GitLab 提供的 Pre-Defined 變數,但要注意,無法使用需要在 Job 建立之後才存在的變數,如之前使用過的 CI_JOB_ID
workflow:rules:auto_cancel
可以與後面要介紹的 workflow:auto_cancel
搭配,當特定條件下,自動取消的動作與預設自動取消的行為不同時,可以透過 workflow:rules:auto_cancel
重新複寫自動取消的宣告。其同樣支援 on_job_failure
當發生錯誤時及 on_new_commit
當 branch 有新的 commit 時,這兩個數值。
如 GitLab 官方手冊上的範例:
workflow:
auto_cancel:
on_new_commit: interruptible
on_job_failure: all
rules:
- if: $CI_COMMIT_REF_PROTECTED == 'true'
auto_cancel:
on_new_commit: none
on_job_failure: none
- when: always # Run the pipeline in other cases
test-job1:
script: sleep 10
interruptible: false
test-job2:
script: sleep 10
interruptible: true
在範例中為整個 Pipeline 設定預設值:
workflow:auto_cancel:on_new_commit
設定為 interruptible
workflow:auto_cancel:on_job_failure
設定為 all
CI_COMMIT_REF_PROTECTED
變數為 true
時則覆寫上面設定的預設值,變為:on_new_commit
為 none
on_job_failure
為none
test-job1
會繼續執行,但 test-job2
會自動取消。test-job1
和 test-job2
都會繼續執行。workflow:auto_cancel
自動取消條件在 auto_cancel
目前支援 on_new_commit
及 on_job_failure
其中,on_new_commit
支援以下數值:
interruptible
:中斷有標注 interruptible
為 true
的 Job。none
:不自動停止任何 Job。conservative
:在沒有任何 interruptible
為 false
的 Job 啟動前,停止整個 Pipeline。未設定時的預設值。workflow:auto_cancel:on_new_commit
workflow:
auto_cancel:
on_new_commit: interruptible
job1:
interruptible: true
script: sleep 60
job2:
interruptible: false # Default when not defined.
script: sleep 60
如上面的範例:
job1
和 job2
兩個 Job。job1
會被取消。workflow:auto_cancel:on_job_failure
on_job_failure
適用於當 Pipeline 執行的過程中,有 Job 失敗時對整個 Pipeline 的處置條件,支援以下兩個數值:
all
:一旦有 Job 失敗,立即取消 Pipeline 及所有正在執行的 Job。none
:不自動取消任何 Job。stages: [stage_a, stage_b]
workflow:
auto_cancel:
on_job_failure: all
job1:
stage: stage_a
script: sleep 60
job2:
stage: stage_a
script:
- sleep 30
- exit 1
job3:
stage: stage_b
script:
- sleep 30
如上面的範例,執行的過程中 job2
刻意 exit 1
造成 job 失敗,則如果 job1
還在執行中,將會被取消,且 job3
將不會啟動。
GitLab CI/CD YAML 的 workflow
主要是針對 Pipeline 相對全局性的控制,有些特性與 Job 底下的特性是一致的,像是 rules
與 variables
的部分,而相對比較不一樣的是 auto_cancel
的部分,這邊的特性對於一些場景,如「只要該分支上最終的成果」 ,則就可以考慮使用 on_new_commit
的特性,因為只要最後的結果,所以前面的 Job 就變得不重要,甚至多執行都是資源的浪費。
同樣的,當 Pipeline 上,任何一個 job 發生錯誤,就代表整個 Pipeline 有錯誤時,就可以考慮使用 on_job_failure
的特性,直接取消整個 Pipeline 的工作。因為有錯誤,所以其他的 job 有沒有成功就變得不重要。
我是墨嗓(陳佑竹),期待這次的內容能帶給你實用的啟發與幫助。