將你的 CI/CD Components 公開發佈至 GitLab CI/CD Catalog

獨樂樂不如眾樂樂,都辛苦做好 CI/CD Components 了,不如就開源給全世界的人使用吧!

前言

繼續延續前兩篇關於 GitLab CI/CD Components 的文章。

  1. Reuse CI Job 的新方法:GitLab CI/CD Components
  2. 為什麼你應該改用 GitLab CI/CD Components?

這次要介紹的是如何將你做好的 GitLab CI/CD Components 發佈到 GitLab CI/CD Catalog,將你精心做好的 CI/CD Components 貢獻成為 CI/CD 界的開源專案,讓大家都能使用你開源出來的成果。

操作步驟

完成你的 CI/CD Component

首先第一步,請先完成你的 CI/CD Component,但這個「完成」需要做到什麼程度呢?我認為需要達成以下幾個條件:

  1. 按照 GitLab 原廠文件,正確的規劃與撰寫 CI/CD Component 的內容。請注意自己的 Project 結構是否正確、spec: 與 CI Job 內容是否撰寫正確、inputs: 的規劃是否合適。
  2. 不只是建立 Tag,還要為每一次的版本釋出建立 Release Page,讓使用者可以知道每一次的 Release 差異,讓使用者更容易知道 CI/CD Component 的版本更新歷程。(特別提醒:原廠文件有提到,目前要將 CI/CD Component 發佈至 CI/CD Catalog 時,建立 Release 是其中一項必備動作!本文後面會有更多說明。 )
  3. 為你的 CI/CD Component 撰寫正確、易讀的 README.md,記得要撰寫讓別人看得懂的內容,讓使用者們可以清楚知道該如何使用你的 CI/CD Component。
  4. 為你的 CI/CD Component 撰寫測試與 CI Pipeline。如果你做出來的 CI/CD Component 有一些相依性需求,可以寫個測試 + CI Pipeline 確保它們都能正常運作。
  5. 如果你的 CI/CD Component 會用到你自己 Build 的 Container image,那設置一條 CI Pipeline 做好 Auto build。
  6. 另外你也可以比照其他的開源專案,為你的 CI/CD Component 建立「如何參與貢獻」的流程、Merge request 的審查流程⋯⋯,記得這些流程的說明,都會需要記載在某個地方(例如:README.md 或 Wiki 中),讓使用者與貢獻者可以看到這些資訊。

配合這篇文章,我也將之前當作範例的 CI/CD Component - OSV Scanner 做了一些整修,下面稍微說明我做了哪些整修:

首先,我調整了 spec: 的內容,以便讓使用者可以更容易的使用它。

spec:
  inputs:
    # 方便使用者可以將 Job 換到不同的 Stage
    stage:
      default: test
    # 方便使用者將 Job name 更換成自己想要的名稱
    job-name:
      default: "osv scanner"
    # 方便使用者更換想要使用的 osv-scanner 版本
    osv-version:
      default: 1.6.2
    # 提供一個彈性,讓使用者可以輸入特別的 osv-scanner options
    custom-arguments:
      default: ""
    # 控制 CI Job,是直接將掃描成果顯示在 CI Log 中,還是 Output 後存為 Artifacts
    save-report:
      default: "false"
    # 續上,讓使用者可以控制 output 的內容格式
    report-format:
      default: table
    # 續上,讓使用者可以控制 output 的檔名與存放路徑
    report-desc:
      default: osv-report.txt

對應 spec: 也調整了 CI Job 的內容。

---
$[[ inputs.job-name ]]:
  image: 
    # 這次改用別人做好的 image
    name: anmalkov/osv-scanner:$[[ inputs.osv-version ]]
    entrypoint: [""]
  stage: $[[ inputs.stage ]]
  script:
    - cd $CI_PROJECT_DIR
    # 利用 inputs.save-report 控制是否要將掃描的結果 output 並存入 Artifacts
    - |
      if [ "$[[ inputs.save-report ]]" == "false" ]; then
        /root/osv-scanner $[[ inputs.custom-arguments ]] -r .
      else
        set +e
        /root/osv-scanner $[[ inputs.custom-arguments ]] -r -f $[[ inputs.report-format ]] --output $[[ inputs.report-desc ]] .
        cat $[[ inputs.report-desc ]]
      fi      
  artifacts:
    paths:
    - $[[ inputs.report-desc ]]
  rules:
    - if: $CI_PIPELINE_SOURCE == "merge_request_event"
    

並且加上了 CI Pipeline,做了一個簡單的測試,幫我確認 CI Job 會使用的 image 是否健在。

# .gitlab-ci.yml
check image tags:
  stage: test
  image: alpine:3.19.1
  script:
    - apk update
    - apk add curl jq
    # 取得 Docker hub 上 anmalkov/osv-scanner 所有的 image tags
    - curl -s "https://registry.hub.docker.com/v2/repositories/anmalkov/osv-scanner/tags/" | jq -r '.results[].name' > tags.txt
    # 然後用一個簡單的 .sh,確認 image tags 是否存在
    - sh check_image_tags.sh

續上,在 Project 內新增了一個簡單的 .sh,檢查 tags.txt 的字串內容。

#!/bin/sh

# 檢查是否有 1.6.2, 1.6.1 的 docker image tags
strings="1.6.2 1.6.1"
file="tags.txt"

for str in $strings; do
    if grep -q "$str" "$file"; then
        echo "Docker image exist: $str"
    else
        echo "Docker image does not exist: $str"
        # 如果 image tag 不存在,就讓 CI failed。
        exit 1
    fi
done

最後,撰寫 README.md 說明如何使用。

完成了上述的修改後,我已經將修改後的內容合併至 main branch。

如果你想要看完整的內容,可以直接上 GitLab 查看,我已經將它建立為 Public Project

下一步我要準備將 Project 發佈至 GitLab CI/CD Catalog。

將 CI/CD Component 發佈至 GitLab CI/CD Catalog

首先,我們要將 Project 設置為 CI/CD Catalog project

這個動作非常簡單,請前往 Settings > General

Visibility, project features, permissions 的最下方,找到設定 CI/CD Catalog project,將它打開即可。

接著再次修改 .gitlab-ci.yml,按著原廠文件的範本,補上一個 Release 專用的 CI Job。

這裡要特別注意,目前 GitLab 規定一定要透過 CI Job 搭配 Keyword - release: 才能將 CI/CD Component 發佈至 GitLab CI/CD Catalog,如果你直接在 GitLab UI 上操作,手動建立 Release page 是無效的喔!

create-release:
  stage: deploy
  image: registry.gitlab.com/gitlab-org/release-cli:latest
  script: echo "Creating release $CI_COMMIT_TAG"
  rules:
    - if: $CI_COMMIT_TAG
  release:
    tag_name: $CI_COMMIT_TAG
    description: "Release $CI_COMMIT_TAG of components in $CI_PROJECT_PATH"

有了上面的 CI Job,後續只要我們替 Project 新增 Tag,就會自動建立對應的 Release page,同時也將 CI/CD Component 發布至 CI/CD Catalog。

但在新增 Tag 之前,提醒一下大家,要先確認你的 Project description (optional) 有沒有填寫內容?

如果沒有填寫,那在 create-release 時,CI Job 可是會報錯的喔!

檢查完畢後,最後就讓我實際新增 Tag,正式將剛做好的 CI/CD Component 發佈至 GitLab CI/CD Catalog 吧!

CI Job create-release 順利執行完畢。

確實有自動產生 Release page。 (等我有空再補上更多的 Release note。)

最後,果真馬上就能在 GitLab CI/CD Catalog 中,搜尋到我前一刻發布的 CI/CD Component。

另外在我的 GitLab Project 上,也出現了一個特別的 Label CI/CD Catalog project

小結

我覺得要將自己做好的 GitLab CI/CD Components 發佈至 GitLab CI/CD Catalog 並不困難,真正困難的依然是如何設計與規劃一個適合他人 Reuse 的 CI/CD Component,以及長期的維護它。

畢竟,不只是程式碼,任何可以被 as Code 的東西,都需要被持續維護,當然也包含你的 CI/CD Pipeline、CI/CD Job 或各種自動化流程。

GitLab 原廠在文件中也花了相當長的篇幅,說明 CI/CD Components 的 Best practices,提醒大家在開發 CI/CD Components 時,要注意哪些要點。

GitLab CI/CD Components 的系列文章還有一些內容可以繼續聊,後續我們再來談更進階的議題吧!我們下次見!

參考資料

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

工商服務

更多文章