在前面的兩篇提到了 when
、only
及 except
來設定工作的執行條件,在這一篇裡,將要提到 rules
這個在 GitLab 12.3 之後提供的條件設定功能。這是一個可以說結合了 when
、only
及 except
三者功能的參數,那麼它可以做些什麼呢?
rules
可以作些什麼?在 rules
參數裡,可以搭配 when
、allow_failure
、if
、changes
及 exists
等等的參數,舉手冊上的例子來說:
docker build:
script: docker build -t my-image:$CI_COMMIT_REF_SLUG .
rules:
- if: '$CI_COMMIT_BRANCH == "master"'
when: delayed
start_in: '3 hours'
allow_failure: true
這個範例提供了「如果 GIT commit 的分支為 master
時,那就在 3 小時之後執行這個工作,且允許執行失敗」。可以發現,寫 rules
的條件判斷,相對使用 when
、only
及 except
多了一些「邏輯感」,因此,我個人在使用上如遇到比較複雜的條件時,我會傾向使用 rules
來完成。但必須注意,「不能」把 rules
與 only
及 except
同時使用,且就算透過 CI Lint 檢測語法,可能也不會顯示錯誤。
rules
的參數目前 rules
主要提供了三個參數:
if
:透過 if
這個參數可以設定或排除某些條件,其功能與 only:variables
提供的相似。changes
:當 GIT Commit 的檔案內容包含設定的檔案變更時執行,其效果與 only:changes
的功能相似。exist
:當 GIT Commit 裡的檔案存在某些檔案時執行。在同一個 rules
裡頭,條件之間是以「且 AND」的型態呈現,但參數裡頭則是以「或 OR」的型態描述,舉底下的例子來說:
build:docker:
script:
- echo 'build docker image'
rules:
- if: '$VAR == "string value"'
changes:
- Dockerfile
- docker/scripts/*
when: manual
上面的例子成立的條件是:
$VAR
的內容為 “string value”Dockerfile
「或」docker/scripts/*
資料夾底下的檔案。另外 rules:if
自 GitLab 13.3 開始,條件還可以搭配括弧(Parentheses)來描述,如官方手冊的範例,透過括弧可以搭配出更「多元」的條件:
job1:
script:
- echo This rule uses parentheses.
rules:
if: ($CI_COMMIT_BRANCH == "master" || $CI_COMMIT_BRANCH == "develop") && $MY_VARIABLE
rules
下的 allow_failure
另外,如果在 job
與 rules
中都使用了 allow_failure
,則 rules
階層的 allow_failure
可以覆寫掉 job
階層的。如底下的範例,當 if
條件成立時,則 allow_failure
為 true
。
job:
script: "echo Hello, Rules!"
rules:
- if: '$CI_MERGE_REQUEST_TARGET_BRANCH_NAME == "master"'
when: manual
allow_failure: true
rules
的條件流程GitLab CI 的 rules
可以同時設定多個條件式,其聯合在一起的效果就如邏輯判斷中的「if...elseif...elseif...」類似,因此,使用上也必須要注意,當其中一個「條件」成立了,則該工作以這個條件設定的內容為主。
job:
script: "echo Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
allow_failure: true
- if: '$CI_PIPELINE_SOURCE == "schedule"'
以上面的這個例子來說,總共有兩個條件式,其一是「當流水線的啟動來自 Merge 請求,且手動觸發時,則允許這個工作失敗」,其二「當流水線的啟動來自排程」,這代表著,當成立條件為第一項時「允許工作失敗」,當成立條件為第二項時,則「不允許」工作失敗(allow_failure: false
為預設值),當兩個條件都不成立時,則這個工作不執行。
那麼,如果要設定反向邏輯呢?如手冊上提出的範例:
job:
script: "echo Hello, Rules!"
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: never
- if: '$CI_PIPELINE_SOURCE == "schedule"'
when: never
- when: on_success
條件是如下:
在 rules
的使用裡,我們可以透過更豐富多元的條件來設定工作該不該作,但也必須要特別注意這些條件是否能真正描述到想要達成的條件,另外也要特別注意條件成立時內額外設定的參數,是否是預期的。
接下來要繼續談工作與工作之間的互動。我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。