iT邦幫忙

2025 iThome 鐵人賽

DAY 20
2
DevOps

GitLab CI 2025:深入玩轉流水線與實戰紀錄系列 第 20

Day20 - 如何在 GitLab CI/CD YAML 裡像 function 一樣重複使用

  • 分享至 

  • xImage
  •  

今天的題目來源,同樣是 stack overflow,標題是:「Gitlab CICD: use functions inside gitlab-ci.yml」,在 GitLab CI/CD 裡頭,如何在 .gitlab-ci.yml 裡頭用 function ? 原始問題是,提問者有一個使用 curl 發訊息到 teams 的 script,在 Job 的 Script 裡頭會反覆的一直使用,如下:

image:
  name: hashicorp/terraform

before_script: 
  - export MYDATE=$(date "+%d/%m/%y - %H:%M:%S")

stages:
  - validate
  - plan

validate:
  stage: validate
  script:
    - terraform validate
    - 'curl --request POST --header "Authorization: Bearer $bearer"  --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'
  variables:
    msg: "Example1"

plan:
  stage: plan
  script:
    - terraform validate
    - 'curl --request POST --header "Authorization: Bearer $bearer"  --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'
  variables:
    msg: "Example2"

提問者已經試著在 .gitlab-ci.yml 裡,使用 anchor 的方法在 .gitlab-ci.yml 裡重複使用,如下:

image:
  name: hashicorp/terraform

before_script: 
  - export MYDATE=$(date "+%d/%m/%y - %H:%M:%S")

.send_message: &send_message
  script:  
  - 'curl --request POST --header "Authorization: Bearer $bearer"  --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'

stages:
  - validate
  - plan

validate:
  stage: validate
  script:
    - terraform validate
    - &send_message
  variables:
    msg: "Example1"

plan:
  stage: plan
  script:
    - terraform validate
    - &send_message
  variables:
    msg: "Example2"

但還是想詢問,也沒有更好的方法可以像使用 function,在 .gitlab-ci.yml 反覆使用重複的段落。

嘗試一:目前使用的方法有什麼問題?

原提問者在自己的實驗中,其實已經透過 Anchor 的方法,在 .gitlab-ci.yml 中重複的使用 send_message,但因為是使用 Anchor,其特性上必須在同一個 CI/CD YAML 中,所以,如果整個 CI/CD YAML 越來越龐大,開始進行拆分,這時候 send_message 就必須在需要使用的 YAML 中,重複一次,才能使用,使用 Anchor 來重複使用,看起來就不像原提問者想要的 function。

嘗試二:利用 !reference 解決這問題?

在 stack overflow 上看到這題目時,GitLab 的 !reference (Optimize GitLab CI/CD configuration files - !reference tags | GitLab Docs)語法,剛推出沒多久,在這情境下,剛好符合提問者使用,於是可以將提問者的題目修改為如下:

# file name: function.yml
.send_message:
  script:  
  - echo 'curl --request POST --header "Authorization Bearer $bearer"  --form "text=$MYDATE $msg" https://api.teams.com/v1/messages'

# file name: .gitlab-ci.yml
include:
  - local: functions.yml

default:
  image: ubuntu:24.04
  before_script: 
    - export MYDATE=$(date "+%d/%m/%y - %H:%M:%S")

stages:
  - validate
  - plan

validate:
  stage: validate
  script:
    - echo "terraform validate"
    - !reference [.send_message, script]
  variables:
    msg: "Example1"

plan:
  stage: plan
  script:
    - echo "terraform validate"
    - !reference [.send_message, script]
  variables:
    msg: "Example2"

GitLab CI/CD YAML 的 !reference 語法特性,就是為了解決 Anchor 無法跨 YAML 檔案使用而誕生的方法,它可以利用 include 的載入該 YAML,接著透過 !reference 語法來重複使用,縱使是在 script 裡,也可以直接載入使用,只要有 include 檔案進來,就可以到處使用,剛好可以適用原提問者想解決的問題。

總結

今天的題目,是我在 stack overflow 上目前回答過與 GitLab 相關題目中,被按加分最多的題目,眼尖的讀者,可能可以發現,其實 !reference 這個方法,已經在 Day02 的內容中有提到,但為什麼還想要再說一次呢?
因為在 Day02 中,是直接以介紹功能與特性的方法介紹,但是,在今天的題目中,是直接解答問題的角度來找到符合的特性,因為角度不太一樣,所以會想用不同的角度來看 !reference 的特性。如果是你,你會想怎麼解決原提問者的問題呢?

我是墨嗓(陳佑竹),期待這次的內容能帶給你實用的啟發與幫助。

參考範例

參考連結


上一篇
Day19 - CI/CD 解題趣-下一階段手動或自動執行,由本階段決定 - 02
下一篇
Day21 - 只在特定 Git Branch 的 Git Tag 執行 GitLab CI Job
系列文
GitLab CI 2025:深入玩轉流水線與實戰紀錄23
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言