Thuta Learning
CI/CD with GitHub Actions
IntermediateDevOps & Toolsbeginner

Matrix Builds — Version များစွာပေါ်တွင် စမ်းသပ်ခြင်း

ဒီခန်းပြီးရင် ဘာတတ်သွားမလဲ

  • Matrix Builds — Version များစွာပေါ်တွင် စမ်းသပ်ခြင်း concept ကို နားလည်ရှင်းပြနိုင်ရန်
  • Diagram ကို ဖတ်ပြီး pipeline ထဲမှာ job တွေ ဘယ်လိုစီးဆင်းပြီး ဘာက gate လုပ်သလဲ ခြေရာခံနိုင်ရန်
  • Workflow file ကို ဖတ်ပြီး ဘယ် job တွေ ဘယ်အစဉ်လိုက် run မလဲ ကြိုတင်ပြောနိုင်ရန်

နားလည်ထားရမယ့် အချက်

Matrix ဆိုသည်မှာ job definition တစ်ခုတည်းကို ရေးပြီး Actions က သင်ဖော်ပြထားသော variable များ၏ combination တစ်ခုစီအတွက် job အစစ်တစ်ခုစီအဖြစ် ချဲ့ထွင်ပေးသော နည်းလမ်းဖြစ်သည်။ strategy.matrix အောက်တွင် အမည်ပေးထားသော array များ — ဥပမာ os နှင့် node-version — ကို ကြေညာပြီး၊ အဲဒီ job ထဲက step တိုင်းသည် လက်ရှိ combination ကို matrix context မှတစ်ဆင့် ဖတ်နိုင်သည်။ Combination ခြောက်ခုသည် runner ခြောက်ခုပေါ်တွင် ပြိုင်တူ run သော job ခြောက်ခု ဖြစ်လာပြီး၊ တစ်ခုစီတွင် ကိုယ်ပိုင် cache၊ ကိုယ်ပိုင် checkout နှင့် checks စာရင်းထဲတွင် ကိုယ်ပိုင် ရလဒ်တစ်ကြောင်းစီ ရှိသည်။

include နှင့် exclude တို့က cross product အပြည့်ကို လက်ခံရမည့်အစား grid ကို ချိန်ညှိခွင့် ပေးသည်။ exclude သည် အဓိပ္ပာယ်မရှိသော combination များကို ဖယ်ထုတ်သည် — Windows အတွက် ဘယ်တော့မှ မထွက်ခဲ့သော Node version၊ သို့မဟုတ် Linux ပေါ်မှာသာ support လုပ်သော runtime ဟောင်း။ include ကတော့ ရှိပြီးသား combination နှင့် ကိုက်မကိုက်အပေါ် မူတည်ပြီး အလုပ်နှစ်မျိုး လုပ်သည် — include entry ထဲက key အားလုံး ကိုက်ညီလျှင် အပို key များကို အဲဒီ job ပေါ်သို့ ထပ်ဖြည့်ပေးပြီး၊ မကိုက်လျှင် job အသစ်တစ်ခု တိုးလာသည်။ ဒီ အပြုအမူ နှစ်မျိုးက လူတွေကို အံ့အားသင့်စေတတ်သည်။ ရှိပြီးသား combination တစ်ခုသို့ coverage: true ထည့်လျှင် အဲဒီ job ကို အလှဆင်ပေးပြီး၊ မကိုက်သော os တစ်ခု ထည့်လျှင် သတ္တမမြောက် job တစ်ခု ဖြစ်လာသည်။

fail-fast ရဲ့ default သည် true ဖြစ်ပြီး combination တစ်ခု ကျရှုံးသည်နှင့် ကျန် sibling အားလုံးကို ချက်ချင်း cancel လုပ်သည်။ ဒါက မိနစ်များ ချွေတာဖို့အတွက် မှန်ကန်သော default ဖြစ်ပြီး၊ တစ်ခုခုကို လေ့လာချင်ချိန်တွင် လုံးဝ မှားသော default ဖြစ်သည်။ fail-fast ဖွင့်ထားပြီး Node 18 မှာ ကျရှုံးလျှင် Node 18 ပျက်နေကြောင်းသာ သိရသည်၊ ပိတ်ထားလျှင် 20 နှင့် 22 ပါ ပျက်နေသလား သိရမည် — ဒါက version-specific bug တစ်ခုနှင့် တကယ်ပျက်နေသော commit တစ်ခုကြား ကွာခြားချက်ဖြစ်သည်။ Debug လုပ်နေချိန်တိုင်း fail-fast: false ထားပါ။

ကုန်ကျစရိတ်သည် မြှောက်ဖော်ကိန်းဖြစ်သည်။ 2x3 matrix သို့ တတိယ OS တစ်ခု ထည့်လျှင် job သုံးခုသာ တိုးတာမဟုတ်ဘဲ Node version တစ်ခုစီအတွက် ထပ်တိုးပြီး၊ တစ်ခုစီက minute ကုန်စေသည်။

text
MATRIX EXPANDING INTO PARALLEL JOBS
-----------------------------------
  strategy.matrix
    os:           [ubuntu-latest, windows-latest]
    node-version: ['18', '20', '22']

                node 18       node 20       node 22
             +-------------+-------------+-------------+
  ubuntu     |    job 1    |    job 2    |    job 3    |
             |             |             | +coverage   |
             +-------------+-------------+-------------+
  windows    |  EXCLUDED   |    job 4    |    job 5    |
             +-------------+-------------+-------------+

  2 x 3 = 6 combinations, minus 1 exclude = 5 parallel jobs
  the include entry decorated job 3, it did not add a job 6

  fail-fast: true    job 3 fails -> jobs 1,2,4,5 CANCELLED
  fail-fast: false   job 3 fails -> all five still report

လက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်

Node 18, 20, 22 ကို Linux နှင့် Windows ပေါ်တွင် support လုပ်သည်ဟု ကြေညာထားသော library တစ်ခု ထုတ်နေသည် ဆိုပါစို့။ Matrix မပါလျှင် version တစ်ခုတည်းပေါ်မှာ စမ်းပြီး ကျန်တာ မျှော်လင့်ရမည်၊ သို့မဟုတ် job တစ်ခုတည်းကို ငါးကြိမ် copy-paste လုပ်ပြီး တဖြည်းဖြည်း ကွဲထွက်သွားစေရမည်။ strategy.matrix ဖြင့် job ကို တစ်ကြိမ်တည်း ရေးရသည်။

runs-on: ${{ matrix.os }} သည် ချဲ့ထွင်ထားသော job တစ်ခုစီကို runner image မတူညီစွာ ကျရောက်စေသည့် အပိုင်းဖြစ်သည်။ name: node ${{ matrix.node-version }} on ${{ matrix.os }} က မြင်ရသည်ထက် ပိုအရေးကြီးသည် — မပါလျှင် job တိုင်းသည် checks စာရင်းထဲတွင် အမည်တူညီစွာ ပေါ်နေပြီး ဘယ်တစ်ခု နီသွားလဲ ခွဲမရတော့ဘဲ၊ ဒါက matrix ရှိရခြင်း၏ အဓိက အကြောင်းရင်း အချက်အလက်မျိုးဖြစ်သည်။

exclude entry က Windows ပေါ်မှာ Node 18 ကို ဖယ်ထားသည်၊ အကြောင်းက အဲဒီ combination ကို ဘယ်တော့မှ ကတိမပေးခဲ့သောကြောင့်ဖြစ်သည်။ include entry က coverage: true ကို combination တစ်ခုတည်းသို့ တွယ်ပေးထားသဖြင့် coverage upload သည် ငါးကြိမ်မဟုတ်ဘဲ တစ်ကြိမ်သာ run ပြီး၊ ကွဲလွဲသော report ငါးခုကို ပေါင်းစပ်စရာ မလိုတော့ပါ။

Debug လုပ်နေချိန်တွင် fail-fast: false ထားပြီး grid တစ်ခုလုံးကို ဖတ်ပါ။ Pipeline တည်ငြိမ်လာပြီး repo အလုပ်များလာသောအခါ PR တစ်ခုတည်းက သင့် plan ခွင့်ပြုသော runner အားလုံးကို မသိမ်းပိုက်စေရန် max-parallel ကို စဉ်းစားပါ။

အတူတူ စမ်းရေးကြည့်မယ်

yaml
name: Matrix tests

on:
  pull_request:
  workflow_dispatch:

jobs:
  test:
    name: node ${{ matrix.node-version }} on ${{ matrix.os }}
    runs-on: ${{ matrix.os }}
    strategy:
      fail-fast: false
      max-parallel: 4
      matrix:
        os: [ubuntu-latest, windows-latest]
        node-version: ['18', '20', '22']
        exclude:
          - os: windows-latest
            node-version: '18'
        include:
          - os: ubuntu-latest
            node-version: '22'
            coverage: true
    steps:
      - uses: actions/checkout@v4

      - uses: actions/setup-node@v4
        with:
          node-version: ${{ matrix.node-version }}
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Run tests
        run: npm test

      - name: Collect coverage on one combination only
        if: matrix.coverage
        run: npm run coverage
You should see
ဒီ definition သည် job ငါးခုအဖြစ် ချဲ့ထွင်သည် — Ubuntu ပေါ်တွင် Node 18, 20, 22 နှင့် Windows ပေါ်တွင် Node 20, 22 — ဆိုလိုသည်မှာ 2x3 grid မှ Windows/Node 18 entry ကို နုတ်လိုက်ခြင်းဖြစ်သည်။ တစ်ခုစီသည် ကိုယ်ပိုင် runner ပေါ်တွင် ပြိုင်တူ run ပြီး name: expression က ပေးသော အမည်ဖြင့် သီးခြား check တစ်ခုစီအဖြစ် ပေါ်လာသည်။ Ubuntu/Node 22 job တစ်ခုတည်းသာ matrix.coverage သတ်မှတ်ထားသဖြင့် coverage step သည် အဲဒီမှာသာ run ပြီး ကျန်လေးခုတွင် skip ဖြစ်သည်။ fail-fast သည် false ဖြစ်သောကြောင့် combination တစ်ခု ကျရှုံးလျှင် ကျန်တာများကို မဖျက်သိမ်းဘဲ တစ်ခုစီ ကိုယ်ပိုင် ရလဒ် တင်ပြသည်၊ ငါးခုထဲမှ တစ်ခုခု ကျရှုံးလျှင် workflow တစ်ခုလုံး နီသည်။ fail-fast ကို default အတိုင်း ထားခဲ့လျှင် ပထမဆုံး ကျရှုံးမှုက ကျန် run နေဆဲ sibling အားလုံးကို cancel လုပ်မည်ဖြစ်ပြီး၊ ကျန် combination များသည် အောင် သို့မဟုတ် ရှုံး မဟုတ်ဘဲ cancelled အဖြစ် တင်ပြမည်။

၅ မိနစ် စမ်းကြည့်

သင့် 2x3 matrix ထဲသို့ macos-latest ကို ထည့်ပါ။ Push မလုပ်ခင် job ဘယ်နှစ်ခု မျှော်လင့်သည်ကို ချရေးထားပါ။ ထို့နောက် fail-fast: true ထားပြီး Node 18 မှာသာ test တစ်ခုကို တမင်ပျက်စေကာ၊ fail-fast: false ဖြင့် တူညီသော run နှင့် ဘယ် combination များက ရလဒ်တင်ပြသလဲ နှိုင်းယှဉ်ကြည့်ပါ။ နောက်ဆုံးတွင် ရှိပြီးသား combination တစ်ခုရဲ့ အပို flag ကို include ထဲသို့ ရွှေ့ပြီး၊ job အသစ်တစ်ခု ဖန်တီးမည့်အစား ရှိပြီးသား job ကို အလှဆင်ကြောင်း အတည်ပြုပါ။

သတိလေးတစ်ချက်

Version-specific ကျရှုံးမှုကို debug လုပ်နေချိန်တွင် fail-fast ကို default အတိုင်း ထားခြင်း — ပထမဆုံး နီသွားသော combination က ကျန်တာအားလုံးကို cancel လုပ်သဖြင့် တခြား version များပါ ပျက်နေသလား ဘယ်တော့မှ မသိရတော့ပါ။

include entry ရဲ့ key အားလုံး ရှိပြီးသား combination နှင့် မကိုက်ဘဲ ထည့်ခြင်း — အဲဒီ job ပေါ်သို့ flag ထည့်ပေးမည့်အစား job အပိုတစ်ခု တိတ်တဆိတ် တိုးလာပြီး matrix သည် ကုန်ကျစရိတ်နှင့်တကွ ကြီးထွားလာသည်။

GitHub Docs - Running variations of jobs in a workflowCI/CD with GitHub Actions

ဒီနေရာမှာ လူအများမှားတတ်တယ်

  • Version-specific ကျရှုံးမှုကို debug လုပ်နေချိန်တွင် fail-fast ကို default အတိုင်း ထားခြင်း — ပထမဆုံး နီသွားသော combination က ကျန်တာအားလုံးကို cancel လုပ်သဖြင့် တခြား version များပါ ပျက်နေသလား ဘယ်တော့မှ မသိရတော့ပါ။
  • include entry ရဲ့ key အားလုံး ရှိပြီးသား combination နှင့် မကိုက်ဘဲ ထည့်ခြင်း — အဲဒီ job ပေါ်သို့ flag ထည့်ပေးမည့်အစား job အပိုတစ်ခု တိတ်တဆိတ် တိုးလာပြီး matrix သည် ကုန်ကျစရိတ်နှင့်တကွ ကြီးထွားလာသည်။
  • Workflow ကို production branch ပေါ် တိုက်ရိုက်မစမ်းဘဲ branch (သို့) test repository တွင် အရင်အတည်ပြုပါ။

လေ့ကျင့်ခန်း

သင့် 2x3 matrix ထဲသို့ macos-latest ကို ထည့်ပါ။ Push မလုပ်ခင် job ဘယ်နှစ်ခု မျှော်လင့်သည်ကို ချရေးထားပါ။ ထို့နောက် fail-fast: true ထားပြီး Node 18 မှာသာ test တစ်ခုကို တမင်ပျက်စေကာ၊ fail-fast: false ဖြင့် တူညီသော run နှင့် ဘယ် combination များက ရလဒ်တင်ပြသလဲ နှိုင်းယှဉ်ကြည့်ပါ။ နောက်ဆုံးတွင် ရှိပြီးသား combination တစ်ခုရဲ့ အပို flag ကို include ထဲသို့ ရွှေ့ပြီး၊ job အသစ်တစ်ခု ဖန်တီးမည့်အစား ရှိပြီးသား job ကို အလှဆင်ကြောင်း အတည်ပြုပါ။

You'll know it worked when: ဒီ definition သည် job ငါးခုအဖြစ် ချဲ့ထွင်သည် — Ubuntu ပေါ်တွင် Node 18, 20, 22 နှင့် Windows ပေါ်တွင် Node 20, 22 — ဆိုလိုသည်မှာ 2x3 grid မှ Windows/Node 18 entry ကို နုတ်လိုက်ခြင်းဖြစ်သည်။ တစ်ခုစီသည် ကိုယ်ပိုင် runner ပေါ်တွင် ပြိုင်တူ run ပြီး name: expression က ပေးသော အမည်ဖြင့် သီးခြား check တစ်ခုစီအဖြစ် ပေါ်လာသည်။ Ubuntu/Node 22 job တစ်ခုတည်းသာ matrix.coverage သတ်မှတ်ထားသဖြင့် coverage step သည် အဲဒီမှာသာ run ပြီး ကျန်လေးခုတွင် skip ဖြစ်သည်။ fail-fast သည် false ဖြစ်သောကြောင့် combination တစ်ခု ကျရှုံးလျှင် ကျန်တာများကို မဖျက်သိမ်းဘဲ တစ်ခုစီ ကိုယ်ပိုင် ရလဒ် တင်ပြသည်၊ ငါးခုထဲမှ တစ်ခုခု ကျရှုံးလျှင် workflow တစ်ခုလုံး နီသည်။ fail-fast ကို default အတိုင်း ထားခဲ့လျှင် ပထမဆုံး ကျရှုံးမှုက ကျန် run နေဆဲ sibling အားလုံးကို cancel လုပ်မည်ဖြစ်ပြီး၊ ကျန် combination များသည် အောင် သို့မဟုတ် ရှုံး မဟုတ်ဘဲ cancelled အဖြစ် တင်ပြမည်။

Matrix Builds — Version များစွာပေါ်တွင် စမ်းသပ်ခြင်း | Thuta Learning