在上一篇我們學到在workflow中用shell command執行js檔的方式複用workflow
這篇我們會來會來看一下如何使用matrix策略自動建立job
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);
})
在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產生一堆的job後發現某一些根本用不到,還要多寫一些語法讓它們不要被執行,那使用include
就是一個好選擇
include的值會是裝了物件的陣列
擴充的規則有兩項
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 }}"
以上這個例子一共會產生6個job,拆解後產生job的步驟如下
include迭代到第二個物件 {size: 'large', dessert: 'ice cream'},把所有原本的組合中dessert為ice cream的size都覆寫成large
include迭代到第三個物件 {fruit: 'mango', decoration: 'chocolate'},把所有原本的組合中fruit為mango的都加上decoration: chocolate
include迭代到第四個物件 {fruit: 'raspberry'},因為原本的組合中沒有一個的fruit是raspberry,擴充新的組合raspberry(藍色)
include迭代到第五個物件 {fruit: 'raspberry', dessert: 'ice cream'},原來的組合中有dessert為ice cream的,但不允許覆蓋原來的組合的原本就有的屬性,且因為上階段產生的組合不是原來的組合之一,所以也不能幫它加上新屬性,所以擴充新的組合raspberry、ice cream(藍色)
使用 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 }}"
以上這個例子一共會產生9個job,拆解後產生job的步驟如下