為什麼你應該改用 GitLab CI/CD Components?

在 GitLab 推出 CI/CD Components 之前,我們也是有辦法 Reuse CI Job,為何現在要改用 CI/CD Components 呢?我目前認為這麼做有三個好處⋯⋯

前言

在上一篇文章,我們試用了 GitLab 的新功能 CI/CD Components,接著讓我們聊一聊為何我們在 GitLab 應該要改用 CI/CD Components 來製作我們的 CI/CD Template。

截至 2024.1.20 為止,我認為改用 CI/CD Components 可以帶來三個好處。

好處 1:讓設計與規劃 Reuse CI Job 的方式更一致

首先,讓我們先做一個簡單的比較,大家想像一下,在過去沒有 CI/CD Components 的時代,我們是如何利用 include: 來設計 CI/CD Templates?如果你希望別人在使用你的 CI Templates 時,要依據需求填入一些 input,你會怎麼做?多半會使用 variables: 去定義一些 Variables 吧?

在那樣的狀況下,為了在 Templates 中提供 Variables 使用上的彈性,讓自定義的 Variables 有 default 值,又能讓使用者可以順利覆蓋,我們會利用 Variables 的各種特性,或使用多層 include: 來設計 CI/CD Templates。

因此最終會做出多層 include:.yml,並在其中撰寫 CI Job,然後搭配 CI Job,將需要填入的 input,都寫在 variables: 中,然後恐怕為了區別不同 CI Job 會用到的 Variables,經常還必須個別加上不同的前綴字,分別命名為 XXX_VAR1OOO_VAR1

而在 GitLab CI/CD Components 的時代,輸入 input 的問題,直接透過 spec: 的標準規範解決了。

讓我再次展示我在上一篇文章使用的 CI/CD Components 範例。

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"

如上範例,GitLab 在 CI/CD Components 功能做出了一個標準的 inputs: 撰寫與使用方式。

  1. 我們需要在 spec: 中清楚定義該 CI Job 可以接受哪些 input。
  2. input 可以像程式語言一樣,輕易的設定 default 值。
  3. 在使用 input 時,只會有一種標準的使用方式 $[[ inputs.your_input_name ]]

乍看之下,spec: 帶來了撰寫上的限制,但正是因為這些限制所形成的規範,讓不同的工程師都能用一致的方式去處理「該如何設計及使用 input」。

再舉另一個例子,同樣過去我們是如何引用其他人做好的 CI/CD Templates?我們在 .gitlab-ci.yml 中大概會撰寫類似下面的內容。

include:
  - project: 'my/ci-template'
    ref: python
    file: '/jobs/python_default.yml'

  - project: 'python/templates'
    ref: python3
    file: '/jobs/pytest.yml'

  - project: 'frontend/ci-template'
    ref: main
    file: '/jobs/ui-test.yml'

你覺得上面的範例有什麼問題嗎?

我覺得比較煩的地方是我必須要搞清楚每一個人是如何管理他的 Templates,到底我要 include: 的是哪一個 Project 的哪一個 branch 的哪一個「資料夾」中的哪一個 .yml

但如果換到 GitLab CI/CD Components,上面的範例可能會變成下面的模樣。

include:
  - component: my/ci-template/python_default@1.0.0
  - component: python/templates/pytest@3.0.0
  - component: frontend/ci-template/un-test@1.0.0

是不是簡潔有力多了?因為 GitLab CI/CD Components 限制了開發者一定要用 Tags 來釋出 CI/CD Component,想要知道怎麼 include:,我只需查看對方 GitLab Project 的 Release 或 tags 即可。

好處 2:提升 Reuse CI Job 的彈性

在說明第二個好處之前,讓我先出 2 個題目給各位

  1. 在同一條 GitLab CI/CD Pipeline 的 include: 中,可以多次引用同一個 .yml 來做出重複的 CI Job 嗎?
  2. include: 中引用 .yml 時,有辦法讓 Template 中的 CI Job 動態變更至其他的 Stage 嗎?

我們就不討論過去的狀況了,但上面這兩個題目在 GitLab CI/CD Components 出現後,答案都是可以的喔!讓我們直接用範例說明。

spec:
  inputs:
    stage:
      default: test
    job-name:
      default: pytest
---
$[[ inputs.job-name ]]:
  image: my-pytest
  stage: $[[ inputs.stage ]]
  script:
  - pytest

在上面的範例中,我撰寫了一個 CI/CD Component,並規範可以有兩個 input,分別是 stagejob-name

當我要使用這個 CI/CD Component 時,.gitlab-ci.yml 的內容可以如下範例

include:
  - component: my/ci-template/pytest@1.0.0
    inputs:
      stage: build
      job-name: pytest
  - component: my/ci-template/pytest@1.0.0
    inputs:
      stage: test
      job-name: pytest-again

我可以重複的引用同一個 CI/CD Component,並搭配修改 inputs:,做出如下圖的結果。

我確實用同一個 Component,在同一條 GitLab CI Pipeline 的不同 Stage 做出了重複的 CI Job,這彈性夠大了吧,在設計 CI Template 時,終於可以不再被 Job 的 Stage、Job name 給卡死啦!

好處 3:更容易為 CI Job 作好版控與測試

最後一個好處,其實我在上一篇文章的小結已經有提過了。

在 GitLab 原廠的建議中,它希望大家在創建 CI/CD Component 時,可以比照你是在做一個開源專案的方式與流程來進行。 也就是說,你所創作的每一個 CI/CD Component,都是一個完整的專案,它會有良好的架構、Spec 及 README.md 讓其他人知道如何使用你的 Component;你也會為 Component 撰寫必要的「測試」,並且有一個標準的 Release 流程,讓大家知道你維護的 Component 版本更新狀況。

以 GitLab CI/CD Component 目前的規範,很明顯的原廠希望大家將每一個想要被 Reuse 的 CI Job 都做成一個完整的 Project,每一個都變成獨立乾淨的 Component。

同樣我們比較一下過去時代做出來的 CI Templates,我們就以原廠做出來的 Auto DevOps Templates 為例。

如上圖,當我們在同一個 GitLab Project 用多層資料夾個別放了多個 .yml,然後這些 .yml 還以 A include B、B include C⋯⋯的狀況下去做出 CI/CD Templates,請問在這種結構中,你要如何個別的去「測試」其中單一項 CI Job 是否能正常運作?你又要如何做好其中單一項 CI Job 的「版本控制」?

如此看來,將 CI Job 轉化成結構獨立乾淨的 Component,確實是一個排除上述問題的好方法!

(如果你有稍微追過 GitLab 原廠的 Project,他們也曾出現類似用 old.ymlnew.yml 來管理與測試 Templates 的狀況。)

小結

在這篇文章中,我並沒有打算介紹更多 GitLab CI/CD Components 的功能與使用,文章主要的目標是想要說服與邀請大家一起來感受 CI/CD Components 的美好。有了 CI/CD Components,我們不但有機會解決過去規劃及撰寫 CI/CD Templates 遇到的一些痛苦,並且還產生了一個新的貢獻開源專案的機會!

因為我們撰寫好的 CI/CD Components,不但可以運用在自己的 Project,如果你是以開源專案的方式 Public 在 gitlab.com 上,那 gitlab.com 的其他 User 也能使用你所貢獻的 CI/CD Components。

本文就到此結束了,等到下一篇文章我們再來聊一聊 GitLab 對於 CI/CD Components 的下一步——CI/CD Catalog——GitLab 用來讓大家分享 CI/CD Components 的好地方!

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

工商服務

更多文章