本文為系列文章《跟著 GitLab Auto DevOps 學習 CI/CD Pipeline》的第三篇,藉由逐一檢視並解析 GitLab Auto DevOps 背後的 Templates,讓我們一起跟著 GitLab Auto DevOps 學習 GitLab CI/CD Pipeline。
在上一篇文章,我們學習了善用 include:
並透過合適的層級規劃,讓我們可以建立出屬於自己的 CI/CD Pipeline Templates。接著在本篇文章,我們要來認識在規劃 GitLab CI Pipeline 時,一個重要的進階功能 workflow:
。
此系列文清單:
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(一)
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(二)
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(三)
- 跟著 GitLab Auto DevOps 學習 CI/CD Pipeline(四)
workflow
在本系列文的第一篇我們介紹 Auto-DevOps.gitlab-ci.yml 時,有稍微提到 workflow:
,但當時只有快速帶過,說明關於它的一個基本認識,在文章中我是這樣解釋的:
workflow:
類似程式語言中的if / else
,在 GitLab CI 我們可以利用workflow:
設置不同的條件,藉此控制 GitLab CI 判斷哪些情境之下,才需要產生 CI/CD Pipeline。
接下來我們就仔細的看一看 GitLab Auto DevOps 是怎麼運用它的,藉此學習 workflow:
的使用方式。
Auto DevOps 的 workflow 範例
首先讓我們看一下 Auto DevOps 是怎麼使用 workflow:
的,由於完整的內容有點長,下面就只截取其中 4 個相同類型的 rules:
作為範例。
workflow:
rules:
- exists:
- Dockerfile
- exists:
- package.json
- exists:
- composer.json
- index.php
- exists:
- Gemfile
既然 workflow:
是用來控制 GitLab CI 到底何時需要產生 CI/CD Pipeline,那上面我擷取的這 4 個 rules:exists
是什麼意思呢?答案很簡單,就是當你的 Project (Repository) 含有特定的檔案時,GitLab CI 就會產生 Pipeline。因此上面 4 個 rules:exists
可以解讀如下。
# 當 Project 的根路徑之下有 Dockerfile 時,就要產生 Pipeline
## 由於判斷條件是 Dockerfile,故合理推論 Auto DevOps
## 可以自動產生與 Docker image 相關的 Pipeline 或 CI Job
- exists:
- Dockerfile
# 當 Project 的根路徑之下有 package.json 時,就要產生 Pipeline
## 由於判斷條件是 package.json,這是 nodejs 的套件管理工具會參照的檔案,
## 故合理推論 Auto DevOps 可以自動產生與 nodejs 相關的 Pipeline 或 CI Job
- exists:
- package.json
# 當 Project 的根路徑之下有 composer.json 或 index.php 兩者其一時,就要產生 Pipeline
## 由於判斷條件是 index.php 明顯是程式語言 PHP,而 Composer 則是 PHP 的套件管理工具,
## 故可以推論 Auto DevOps 可以自動產生與 PHP 相關的 Pipeline 或 CI Job
- exists:
- composer.json
- index.php
# 當 Project 的根路徑之下有 Gemfile 時,就要產生 Pipeline
## 由於判斷條件是 Gemfile,這次輪到 ruby 這個程式語言啦,
## 顯然 Auto DevOps 有辦法自動產生與 ruby 相關的 Pipeline 或 CI Job
- exists:
- Gemfile
從上面這 4 個範例,我們就能稍微了解 GitLab Auto DevOps 是如何判斷何時要自動幫使用者產生 CI/CD Pipeline。原來其中並沒有什麼特別的「黑魔法」,所倚靠的即是事先寫好的眾多 rules:
,就好比寫了一堆 if
一樣,讓 GitLab CI 根據 Project 中是否有某些檔案,以此判斷到底 Project 是哪一種程式語言,並為其自動產生 Pipeline。
運用 workflow
上面的範例我們只有介紹 rules:exists
,實際上 workflow:
可以使用的 rules:
共有下面三種:
rules:if
可以做簡單的 if 判斷,一般來說會搭配 Variables 做條件判斷,例如
if: '$SKIP_NPM == true'
rules:changes
根據該次 Commit 中,特定檔案是否有被異動,判斷是否要產生 Pipeline。
rules:exists
如前面的範例,根據 Project 內是否含有特定檔案,判斷是否要產生 Piepline。
【補充】在
workflow:
中rules:
一樣也能搭配when:
做出更複雜的情境。
前面說了這麼多 workflow:
可用的判斷條件,但相信大家一定還是感到疑惑,到底何時會需要用到 workflow:
?官方顯然在 Auto DevOps 是為了讓各種不同類型的 Project 皆能自動產生 Pipeline 而使用它,但一般的使用者何時會用到它呢?
老實說⋯⋯⋯⋯我自己是認為一般使用者還真的不一定需要用到 workflow:
,如果你已經熟悉 GitLab CI,其實你會發現 workflow:
能做出的判斷條件是仰賴於 rules:
這個功能,只是它將層級提升至整條 Pipeline。
但實際上 rules:
是可以直接運用在 CI Job 層級的。因此如果你經手的是小型專案,或者你是一點一滴慢慢建構出你的整條 Pipeline,那麼你的 Pipeline 當中應該會有許多的 when:
、rules:
及 variables
,用這三者去組合出可以適用不同 branch 與 merge request 的 Pipeline。
# 例如:只有 Merge request 才需要執行特定的 CI Job
auto testing for MR:
script:
- run some testing
when: $CI_PIPELINE_SOURCE == 'merge_request_event'
# 例如:只有 Merge request 才需要產生特定需手動驅動的 CI Job
manual testing for MR:
script:
- run some testing
rules:
- if: '$CI_PIPELINE_SOURCE == "merge_request_event"'
when: manual
回到 workflow:
,我覺得這個功能最重要的意義不在於功能本身!(謎之音:繞口令?)
【補充】
workflow:
功能還是有其他用途啦!像是設置合適的條件,避免單一 Commit 產生重複的 Pipeline。(但要出現這種狀況,也只有你的 Pipeline 使用了大量的rules:
時才比較可能遇到。)
它的價值在於讓我們從 Pipeline 的角度來思考 Pipeline!(謎之音:繞口令 Again?)
沒有錯,單就功能來說,workflow:
只能幫我們控制在哪些條件之下,要產生 CI/CD Pipeline。但反之這也提醒了我們要去思考「哪些情境需要使用 CI/CD Pipeline?」以及「不同的情境之下 CI/CD Pipeline 需要執行哪些 CI Job?」
大家下次又要規劃 CI/CD Pipeline 時,先別急著從 CI Job 開始思考,不妨換個角度,改從 Pipeline 的高度來思考該如何規劃 CI/CD,也許會有不一樣的感受喔!
結語
老樣子,總結一下本文我們學習了哪些重點:
- 我們可以運用
workflow:
控制在特定條件之下,才需要產生 CI/CD Pipeline。 workflow:
能使用的條件只有rules:if
、rules:changes
與rules:exists
,但進階可以再搭配when:
。workflow:
的影響層級是整條 Pipeline。- 續上,如果想要控制的是單一 CI Job,則請直接對該 Job 使用
rules:
。 - 如你已經熟悉一個接一個 CI Job 的慢慢建構出 Pipeline,下一次不妨換個角度,試試看從 Pipeline 的高度來思考該如何規劃 CI/CD Pipeline。
關於 workflow:
與 rules:
還有其他可以說明的內容,但就讓我們留待後續再分享嘍!