iT邦幫忙

2025 iThome 鐵人賽

DAY 14
2

在之前的鐵人賽中,談過工作與工作之間的相依關係 dependencies,也談過使用 needs 來構成 DAG 有向無環圖,可以想像,工作與工作之間的關聯在 Pipeline 之中,是非常重要的一件事情。隨著 GitLab 版本的推移,因為為了讓 CI/CD YAML 更有彈性、更靈活,一些新的語法與關聯關係就此誕生。接下來會談 CI/CD YAML 語法,隨著版本演進而做的優化與加強。

如何讓其中一個工作完成,即進行下一個工作

標題可能有些難以想像,直接以案例來描述:一條工作流程中,編譯(Build Stage)階段,正式環境的參數跟非正式環境的使用的參數,可能會不太一樣,而編譯後又會進行相同的測試(Test Stage)階段,因此,就會產生一個需求:如果編譯階段「其中一個工作完成後」,即開始進行測試階段的工作。

這個需求該如何完成呢?以測試階段的工作環節來思考,以往有相依關係的工作,就會放在 needs 裡,但是在這邊的需求中,當執行正式環境流水線時,就只有正式環境的打包工作進行,非正式環境的打包工作不會執行,因此 needs 的條件中,一定無法滿足,但如果工作上又需要透過 needs 的特性來完成,該怎麼辦呢?

針對這個需要,在 GitLab 16.2 之後,正式在 rules 加入的 rules:needs,可以以特定條件,來限制該條件下的 needs,使用在上面的案例中,就可以用底下的方式表示:

default:
  image: ubuntu:24.04

variables:
  IS_PROD:
    value: "false"
    options: ["true", "false"]
    description: "IS Prod or not"
    
build-dev:
  stage: build
  rules:
    - if: $IS_PROD == "false"
  script: echo "not prod , build Dev version"

build-prod:
  stage: build
  rules:
    - if: $IS_PROD == "true"
  script: echo "is prod, build Prod version"

tests:
  stage: test
  rules:
    - if: $IS_PROD == "false"
      needs: ['build-dev']
    - if: $IS_PROD == "true"
      needs: ['build-prod']
  script: echo "is not prod needs build-dev job, is prod needs build-prod job"

以上這邊的案例來說,關鍵點就是 rules 的部分,直接在對應的條件下,帶入所需的 needs

  rules:
    - if: $IS_PROD == "false"
      needs: ['build-dev']
    - if: $IS_PROD == "true"
      needs: ['build-prod']

不同條件,給予不同的變數數值

另外,延伸至上面的題目,如果正式環境與非正式環境使用變數的數值也要不太一樣呢?例如有一個叫做 BUILD_MODE 的參數,其數值在正式環境的時候,要特別標示 Prod Mode,非正式環境改預設標示 Dev Mode呢?
這邊則可以透過 rules:variables 來進行表示。當條件成立時,則設定該變數的數值。以上面的案例加以調整,可以是:

default:
  image: ubuntu:24.04

variables:
  IS_PROD:
    value: "false"
    options: ["true", "false"]
    description: "IS Prod or not"
    
build-dev:
  stage: build
  rules:
    - if: $IS_PROD == "false"
  script: echo "not prod , build Dev version"

build-prod:
  stage: build
  rules:
    - if: $IS_PROD == "true"
  script: echo "is prod, build Prod version"

tests:
  stage: test
  variables:
    BUILD_MODE: "Dev Mode"
  rules:
    - if: $IS_PROD == "false"
      needs: ['build-dev']
    - if: $IS_PROD == "true"
      needs: ['build-prod']
      variables:
        BUILD_MODE: "Prod Mode"
  script: 
    - echo "is not prod needs build-dev job, is prod needs build-prod job"
    - echo "Your Mode is ${BUILD_MODE}"

同樣的,這邊的關鍵是,在 rules 底下,對應的條件中成立時,直接給予對應的變數參數設定。

  rules:
    - if: $IS_PROD == "false"
      needs: ['build-dev']
    - if: $IS_PROD == "true"
      needs: ['build-prod']
      variables:
        BUILD_MODE: "Prod Mode"

結論

繼昨天談到 only / except 語法即將停用改為 rules 取代之後,也可以發現 rules 可以提供的語法支援也越來越多元,越來越有彈性,開始支援之後 needs 更是省去了許多麻煩事。我是墨嗓(陳佑竹),期待這次的內容能帶給你實用的啟發與幫助。

參考範例

參考連結


上一篇
Day13 - GitLab 宣告停用的語法及替代方案
系列文
GitLab CI 2025:深入玩轉流水線與實戰紀錄14
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言