iT邦幫忙

2024 iThome 鐵人賽

DAY 20
0
DevOps

菜逼八用Github Actions系列 第 20

Day 20 - 用matrix策略自動建立job

  • 分享至 

  • xImage
  •  

目錄

摘要

在上一篇我們學到在workflow中用shell command執行js檔的方式複用workflow

這篇我們會來會來看一下如何使用matrix策略自動建立job

什麼是matrix策略

matrix策略是一種能夠在一個job中自動根據變數建立多個接收不同值去做一樣事的job的方式,可以減少重複撰寫job,並提高workflow的可維護性

這個方式常被用於同個repo的多個環境的測試,你可以把它想成是Github Action的job版的for迴圈的概念,迴圈內內呼叫同個function只是每次傳入的參數值都不同

matrix底下定義的屬性可以有多個,一個就是一維的matrix,三個就是三維的matrix(類似三層套在一起的for迴圈)

不過需要注意有個限制,在一個workflow中自動產出的job最多只能有256個,也就是說所有屬性值的長度相乘後不可超過256

const matrix = {
  envs: ['dev', 'alpha', 'beta', 'prod'],
}

matrix.envs.forEach((env) => {
  runUnitTest(env);
})

使用matrix

在jobs底下的stragy.matrix定義陣列,陣列中裝的元素是要傳給script或者command的變數

陣列中的元素可以是基本型別的值,也可以是物件

jobs:
  greet-to-someone:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        greeting: ['Have you ever', 'Will you']
        action: ['go to ', 'live at']
        country: ['Japan', 'Canada', 'Taiwan']
    steps:
      - name: Greet
        run: echo "${{ matrix.greeting }} ${{ matrix.action }} ${{ matrix.country }}?"

以這個例子來說會產生12個job(2*2*3)

使用matrix

擴充matrix

如果你想要擴充matrix,但是又不想要以多維matrix產生一堆的job後發現某一些根本用不到,還要多寫一些語法讓它們不要被執行,那使用include就是一個好選擇

include的值會是裝了物件的陣列

擴充的規則有兩項

  1. 不允許覆蓋原來的組合的原本就有的屬性,但可以新增屬性
  2. 不允許幫新產生的組合新增屬性
jobs:
  prepare-dessert:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        fruit: [mango, strawberry]
        # 因為ice和cream中間有空格,所以要用引號包住
        dessert: ['ice cream', cake]
        include:
          - size: small
          - size: large
            dessert: 'ice cream'
          - fruit: mango
            decoration: chocolate
          - fruit: raspberry
          - fruit: raspberry
            dessert: 'ice cream'
    steps:
      - name: ready
        run: echo "${{ matrix.fruit }} ${{ matrix.dessert }} ${{ matrix.decoration }} ${{ matrix.size }}"

https://ithelp.ithome.com.tw/upload/images/20240911/20135568TmTrlX5VzP.png

以上這個例子一共會產生6個job,拆解後產生job的步驟如下

  1. fruit和dessert產生4(2*2)個組合,這些組合是原本就會有的(黃色)
  1. include迭代到第一個物件 {size: 'small'},因為原有的組合都沒有size屬性,把所有原本的組合都加上size: small
  1. include迭代到第二個物件 {size: 'large', dessert: 'ice cream'},把所有原本的組合中dessert為ice cream的size都覆寫成large
    https://ithelp.ithome.com.tw/upload/images/20240911/20135568jKeTjOUPuc.png

  2. include迭代到第三個物件 {fruit: 'mango', decoration: 'chocolate'},把所有原本的組合中fruit為mango的都加上decoration: chocolate
    https://ithelp.ithome.com.tw/upload/images/20240911/20135568962TWXZAsP.png

  3. include迭代到第四個物件 {fruit: 'raspberry'},因為原本的組合中沒有一個的fruit是raspberry,擴充新的組合raspberry(藍色)
    https://ithelp.ithome.com.tw/upload/images/20240911/20135568j05l0nBesF.png

  4. include迭代到第五個物件 {fruit: 'raspberry', dessert: 'ice cream'},原來的組合中有dessert為ice cream的,但不允許覆蓋原來的組合的原本就有的屬性,且因為上階段產生的組合不是原來的組合之一,所以也不能幫它加上新屬性,所以擴充新的組合raspberry、ice cream(藍色)
    https://ithelp.ithome.com.tw/upload/images/20240911/20135568SvGfJn479P.png

縮減matrix

使用 exclude 可以排除特定的矩陣組合,因此也能避免生成不需要的 job

jobs:
  prepare-dessert:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        fruit: [mango, strawberry, raspberry]
        dessert: ['ice cream', cake]
        sauce: ['chocolate', 'strawberry']
        exclude:
          - fruit: mango
            dessert: cake
            sauce: strawberry
          - fruit: raspberry
            dessert: 'ice cream'
         
    steps:
      - name: ready
        run: echo "${{ matrix.fruit }} ${{ matrix.dessert }}"

https://ithelp.ithome.com.tw/upload/images/20240911/20135568qt2h9vgtbB.png
以上這個例子一共會產生9個job,拆解後產生job的步驟如下

  1. fruit和dessert產生12(3*2*2)個組合,這些組合是原本就會有的(黃色)

https://ithelp.ithome.com.tw/upload/images/20240911/20135568UFX4C2mgUH.png

  1. include迭代到第一個物件 {fruit: 'mango', dessert: 'cake', sauce: 'strawberry'},移除掉同時符合這三個條件的一組合(半透明)

https://ithelp.ithome.com.tw/upload/images/20240911/20135568YWvca2wFWF.png

  1. include迭代到第二個物件 {fruit: 'raspberry', dessert: 'ice cream'},移除掉同時符合這兩個條件的兩組合

https://ithelp.ithome.com.tw/upload/images/20240911/20135568a3KUbjKgyQ.png


上一篇
Day 19 - 在workflow中執行js檔
下一篇
Day 21 - fail-fast策略 & continue-on-error策略
系列文
菜逼八用Github Actions28
圖片
  直播研討會
圖片
{{ item.channelVendor }} {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言