有些時候,流水線(pipeline)上的系統部署、原始碼打包等工作,可能需要花費大量的時間或系統資源,因此,在這種資源或時間成本相對高的專案上,當流水線上還有工作還在進行時,同一 Git 分支又有新的 Commit 到來啟動流水線作業時,已經在線上的流水線作業,繼續執行與否?就是一個可以討論的議題了。
在系統預設的情境中,在一個分支上,已經有一個流水線工作正在進行了,這時候同一分支有新的 Git Commit 到來,啟動新的流水線工作,這時候 GitLab Server 預設會保持新舊兩個流水線上的工作均繼續執行。
如下圖,在 master 的分支上短時間內先後有兩個 Git Commit Push,則同一個分支上,兩個流水線工作同時進行。
在 GitLab CI 中,可以使用 interruptible
參數,這個參數可以用來控制,當有新的流水線工作建立時,目前的這工作是否繼續執行。一般沒有設定的情境,其預設為 false
,也就是不被中斷。舉例來說(以 GitLab 文件上的範例稍作修改):
stages:
- stage1
- stage2
step-1:
stage: stage1
script:
- echo "Can be canceled."
- sleep 30
interruptible: true
step-2:
stage: stage2
script:
- echo "Can be canceled."
- sleep 30
interruptible: true
以上面的這例子,因為 interruptible
參數設定為 true
因此,當同一分支上有新的 Git Commit 到來建立新的流水線工作時,會立即中斷已經存在流水線上的工作,且後續的工作也均不再執行。如下圖,工作預計至少執行 30秒,但因為有新的流水線建立,其在 16 秒就被中斷了:
當工作設定了 interruptible
參數為 true
時,新啟動的流水線工作會中斷已經存在的流水線工作,那麼,如不是所有的工作都設定了允許中斷,那流水線會怎麼進行?如底下的例子(取自 GitLab 官方文件,但增加 sleep,以方便操控新的流水線啟動),第二個工作未設定 interruptible
,也就是預設為 false
不可被中斷。
stages:
- stage1
- stage2
- stage3
step-1:
stage: stage1
script:
- echo "Can be canceled."
interruptible: true
step-2:
stage: stage2
script:
- echo "Can not be canceled."
- sleep 30
step-3:
stage: stage3
script:
- echo "Because step-2 can not be canceled, this step will never be canceled, even though set as interruptible."
- sleep 30
interruptible: true
以上面的例子來說,因為第二個關卡中的工作未設定 interruptible
因此預設為 false
,所以當工作執行到工作 step-2
時,如果有新的 commit 到來啟動流水線,將不再中斷目前的這條流水線。如下圖,舊的流水線將繼續執行。
而,在 step-3
有重新設定了 interruptible
為 true
,這時候如果又再次有新的流水線啟動,依照 GitLab CI 的設計,因為 step-2
無法被中斷,所以連帶著 step-3
也不再被中斷,即使有設定interruptible
。如下圖 step-3
已經執行了,此時啟動新的流水線工作,並不會中斷 step-3
的工作。
另外,當工作在 Pending
狀態時,其系統會將該工作設定為可被中斷,不管是否有設定 interruptible
參數。
是否允許新的流水線啟動中斷現行流水線工作,可能有幾個思考點:
接下來,即將進入玩轉 GitLab 系列的後半段,將會開始介紹關於 GitLab CI 設定的重構思考以及關於如何加速流水線的議題。我是墨嗓(陳佑竹),期待這系列的文章能夠讓人有些幫助。