Reuse CI Job 的新方法:GitLab CI/CD Components

GitLab 從 16.0 開始實驗名為 CI/CD Components 的新功能,讓我們一起來嚐鮮試用吧!

前言

隨著軟體開發的生命週期,除了程式碼,CI/CD Pipeline 也有可能會隨之變得越來越複雜。在過去 GitLab CI 提供了像是 include:template:extends: 等多種 Keywords 來幫助我們重構、規劃及管理我們的 CI/CD Pipeline,透過這些 Keywords,我們可以設計出屬於自己團隊及跨 Projects 共用的 CI / CD Templates,避免團隊重複造輪子,讓 Pipeline 及 CI Job 可以被重複利用。

筆者認為 GitLab CI 現有的這些 Keywords 已經足夠豐富,可以有效幫助團隊用一種有規劃及架構的方式來管理 CI/CD Pipeline。但問題是在這樣的規劃及架構背後,也代表著有一份屬於這個團隊的「GitLab CI/CD 知識與經驗」需要被記錄與傳承,這些知識與經驗,將會是團隊需要面對的另一項議題。

上述有關 CI/CD Pipeline 規劃及管理的議題,其實各種 CI Tools 的供應商都有注意到,隨著 CI/CD 工具鍊的整合越來越容易,其實可以發現供應商們不約而同都在思考著類似的議題——如何讓使用者可以更輕省的創建所需的 CI/CD Pipeline、如何減輕使用者在創建 CI/CD Pipeline 時需要擁有的先備知識量、如何更好的讓眾人一同維護 CI/CD Pipeline。

針對這些議題,GitLab 在版本 16.0 做出了一項新回應,從 16.0 開始實驗名為 CI/CD Components 的新功能,並且在 16.6 進入 Beta 開放大家試用。

在這篇文章,我們就來快速建立一個 CI/CD Component,試用一下這個值得我們期待的 GitLab CI 新功能吧!

操作步驟

建立 CI/CD Component Project

讓我們從建立自己的 CI/CD Component 開始。這裡我一樣選擇前幾則貼文使用過的 OSV Scanner 當作範例。

首先建立先一個乾淨的 Project,為它取一個合適的名稱。因為只是試用,所以 Visibility Level 就先設定為 private

在 Project 內,要按著 GitLab 規定的標準格式建立必備的資料夾及檔案。最低限度你會需要一個名為 templates 資料夾,以及與 Component 同名的 .yml 檔案。

.yml 檔案中,利用 --- 作為分隔線,分別撰寫 Component 的「規格」及「內容」,下面我就用之前分享過的 CI Job: OSV Scanner 做一個範例。

spec:
  inputs:
    stage:
      default: test
    osv-version:
      default: 1.4.3
    default-arguments:
      default: -r --format=table --output=osv-report.txt .
---
osv scanner:
  image: chengweisdocker/osv-scanner-for-ci:$[[ inputs.osv-version ]]
  stage: $[[ inputs.stage ]]
  script:
  - set +e
  - cd $CI_PROJECT_DIR
  - /root/osv-scanner $[[ inputs.default-arguments ]]
  - cat osv-report.txt
  artifacts:
    paths:
    - osv-report.txt
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"

如上面的範例,很清楚的可以看見 --- 作為分隔線擋在中間,上半部撰寫的是「規格 spec」,下半部則是我們向來熟悉的 CI Job 內容。

先來解說「規格 spec」。就如其字義,你可以將它想成你打算讓做出來的 CI/CD Component,未來有哪些「變數」或「參數」可供其他人彈性使用。以我上面的範例來說,我提供了三個參數:

  1. stage:假如有人不想把 osv-scanner 放在 stage:test,那他可以自行設定。
  2. osv-version:讓使用者可以決定自己要用哪一版的 OSV Scanner。(當然前提是如果我有做出多個版本的 docker image。)
  3. default-arguments:如果有人想要輸入 osv-scanner 的其他參數,提供彈性讓他可以組合自己的參數。

接著就是 CI Job 的內容,讓我直接用圖片做一個簡單的對照。

如上圖,我將原本寫死的 CI Job 部分內容,抽換成前面在 spec: 中定義的 inputs:。要注意的是這邊的撰寫方式,就不是過往在 .gitlab-ci.yml 常用的 Variables 格式,而是要改成用 $[[ ]] 包住你要取用的內容。

Project 內所需的檔案到這裡告一個段落。

為你的 CI/CD Component 建立版號

在我們真正要開始使用 CI/CD Component 之前,還有一件一定要做的事情,那就是打 Tag!

請比照一般常見的開源專案或開源軟體的形式,為你做好的 CI/CD Component 設定 Tag。

如上圖,我將前述的 CI/CD Component 所需檔案 Commit 至 main branch 之後,接著就在 main branch 打了 0.0.1 的 Tag。

使用你的 CI/CD Component

最後,就讓我們試用一下自己做好的 CI/CD Component。

同樣的我建立一個乾淨的 Project,打開 Pipeline Editor 功能來建立 .gitlab-ci.yml,接著輸入下面的內容。

include:
  - component: gitlab.com/chengwei.chen/ci-cd-component-ocv-scanner/osv-scanner@0.0.1
  # 前面就是你的 Component Project URL,後面加上 Component 名稱與 Tag

如下圖,可以看見 Pipeline Editor 內建的檢查功能顯示為「Pipeline syntax is correct.」,代表它有正確的 include 我的 CI/CD Component。

這裡故意做一個錯誤的圖片,作為對照範例,我故意將 Tag 改成 0.0.2,因為根本沒有這個 Tag,所以可以發現 Pipeline Editor 就出現找不到這個 Component 的提醒。

下一步讓我做一個 Merge request,送出一些 Commits 來觸發 CI Pipeline。得到成果如下圖,確實在 CI Pipeline 的 Stage: test 出現了 CI Job osv scanner,吻合我所製作的 CI/CD Component。

第二個測試,我們要透過 inputs: 動態改變 Job 的內容,我將 .gitlab-ci.yml 修改如下。

# 設置一個新的 stage
stages:
- osv

include:
  - component: gitlab.com/chengwei.chen/ci-cd-component-ocv-scanner/osv-scanner@0.0.1
    inputs:
      # 改變 Job 的 Stage
      stage: osv
      # 改變欲使用的 osv version
      osv-version: 1.3.3
      # 配合 1.3.3 版的 osv 要改變指令與參數
      default-arguments: "-f json -r . > osv-report.txt"

再次觸發 CI Pipeline,得到下面數張圖片的成果。

首先,CI Job 的 Stage 確實變為 osv

使用的 image 也變成 1.3.3 的版本。

執行的指令,也確實如我設定的,變成 1.3.3 版本的語法

經過上面的實驗,我已成功做出我私人專用的 CI/CD Component!為什麼說是「私人專用」呢?還記得前面一開始建立 Project 時,在 Project Visibility Level 是設置為 private,因此當然只有我自己可以使用。

小結

呼應本文的前言,不知道大家對於 GitLab 新推出的 CI/CD Components 功能有些什麼樣的想法呢?你覺得它真的能幫助團隊更好的規劃及管理 CI/CD Template 或者真的能幫助使用者更輕鬆的組合出一條立即可用的 CI/CD Pipeline 嗎?

又或者你覺得 GitLab 背後在打的如意算盤是什麼呢?

在本文中,我們只有快速的帶著大家用最少的步驟、最少的檔案做出一個 GitLab CI/CD Component,但其實在 GitLab 原廠的建議中,它希望大家在創建 CI/CD Component 時,可以比照你是在做一個開源專案的方式與流程來進行。

也就是說,你所創作的每一個 CI/CD Component,都是一個完整的專案,它會有良好的架構、Spec 及 README.md 讓其他人知道如何使用你的 Component;你也會為 Component 撰寫必要的「測試」,並且有一個標準的 Release 流程,讓大家知道你維護的 Component 版本更新狀況。

透過將 CI/CD Job 轉化成 CI/CD Component,讓 CI/CD Pipeline 從一個本來是開發者隨著專案需求,自行用一個只有自己才懂的邏輯去規劃的狀況,變成打從一開始就要注意到 CI Job 標準化、易用性、維護性議題的狀況。

關於 GitLab CI/CD Component 本文就先聊到這裡了,其實還有更多進一步的技巧與內容尚未分享,這些就等未來有機會再繼續撰文介紹嘍!

參考資料

轉貼本文時禁止修改,禁止商業使用,並且必須註明來自「艦長,你有事嗎?」原創作者 Cheng Wei Chen,及附上原文連結。

工商服務

更多文章