နားလည်ထားရမယ့် အချက်
Workflow file တစ်ခုဟာ repository ရဲ့ .github/workflows/ directory အောက်မှာ .yml (သို့) .yaml extension နဲ့ ရှိရပါမယ်။ ဒီနေရာက ညှိလို့ရတဲ့ setting မဟုတ်ပါဘူး - GitHub က အဲဒီ directory တစ်ခုတည်းကိုပဲ ကြည့်ပါတယ်။ ဒါကြောင့် file ကို workflows/ci.yml ဒါမှမဟုတ် .github/ci.yml မှာ ထားမိရင် error တစ်ခုမှ မမြင်ရဘဲ ဘာမှ မဖြစ်ပါဘူး - ဒါက အသစ်စတဲ့သူတွေ အချိန်အကုန်ဆုံး နာရီပါပဲ။
ဖွဲ့စည်းပုံက အလွှာသုံးလွှာပါ။ အပေါ်ဆုံးမှာ name (Actions tab မှာ ပြမယ့် အမည်၊ မထည့်ရင် file path ကို သုံးပါတယ်)၊ on (ဘယ် event တွေက ဒီ workflow ကို trigger လုပ်မလဲ)၊ နဲ့ jobs (တကယ် အလုပ်လုပ်မယ့် အရာတွေ) ရှိပါတယ်။ YAML မှာ quote မခံထားတဲ့ on: ဟာ Actions အတွက် မှန်ကန်တဲ့ ရေးနည်းဖြစ်ပြီး၊ ဒါဟာ သာမန် key တစ်ခုပါပဲ။
jobs အောက်မှာ ကိုယ်ပေးထားတဲ့ id (ဥပမာ lint, test) တစ်ခုစီရှိပြီး၊ job တစ်ခုစီမှာ runs-on (ဘယ် runner image ပေါ်မှာ run မလဲ) နဲ့ steps (အစဉ်လိုက် လုပ်မယ့် အလုပ်စာရင်း) ရှိရပါမယ်။ step တစ်ခုဟာ uses ဖြစ်နိုင်သလို run လည်း ဖြစ်နိုင်ပါတယ် - uses က တခြားသူရေးထားပြီးသား action တစ်ခုကို ခေါ်သုံးတာ (input တွေကို with နဲ့ ပေးတယ်)၊ run ကတော့ runner ရဲ့ shell ထဲမှာ command တွေ တိုက်ရိုက် run တာပါ။ step တစ်ခုမှာ uses နဲ့ run နှစ်ခုလုံး တစ်ပြိုင်နက် မထားနိုင်ပါဘူး။ name ကတော့ log ထဲမှာ ဖတ်ရလွယ်အောင် ထည့်ပေးတဲ့ label ပါ။
လူအများဆုံး နားလည်မှုလွဲတာက အောက်ပါအချက်ပါ - job တွေဟာ default အားဖြင့် တစ်ပြိုင်နက်တည်း၊ သီးခြား virtual machine အသစ်တစ်လုံးစီပေါ်မှာ run ပါတယ်။ file အထက်အောက် ရေးထားလို့ အစဉ်လိုက် run မယ်လို့ မထင်ပါနဲ့။ job တစ်ခုက ဆွဲထားတဲ့ dependency တွေ၊ ဆောက်ထားတဲ့ file တွေကို နောက် job တစ်ခုက လုံးဝ မမြင်ပါဘူး။ အစဉ်လိုက် လိုချင်ရင် needs နဲ့ တိတိကျကျ ချိတ်ပေးရပါတယ်။
WORKFLOW > JOBS > STEPS
-----------------------
file: .github/workflows/ci.yml
+---------------------------------------------------------------+
| name: CI on: [push, pull_request] |
| |
| jobs: |
| +--------------------------+ +--------------------------+ |
| | lint: | | test: | |
| | runs-on: ubuntu-latest | | runs-on: ubuntu-latest | |
| | steps: | | steps: | |
| | 1 uses: checkout@v4 | | 1 uses: checkout@v4 | |
| | 2 uses: setup-node@v4 | | 2 uses: setup-node@v4 | |
| | 3 run: npm ci | | 3 run: npm ci | |
| | 4 run: npm run lint | | 4 run: npm test | |
| +--------------------------+ +--------------------------+ |
| fresh VM #1 fresh VM #2 |
| |
| these two start AT THE SAME TIME and share no files |
+---------------------------------------------------------------+
uses: -> run somebody else's reusable action, inputs via with:
run: -> run shell commands on this runnerလက်တွေ့ scenario နဲ့ ချိတ်ကြည့်မယ်
အောက်က workflow မှာ job နှစ်ခု - lint နဲ့ test - ရှိပါတယ်။ file ထဲမှာ lint က အပေါ်မှာ ရှိပေမယ့် အရင် run မယ်လို့ မဆိုလိုပါဘူး။ GitHub က နှစ်ခုလုံးကို တစ်ပြိုင်နက် စတင်ပြီး runner နှစ်လုံး သီးခြားစီ ခွဲပေးပါတယ်။ ဒါကြောင့် နှစ်ခုစလုံးမှာ checkout နဲ့ setup-node ကို ထပ်ရေးထားရတာပါ - test job က lint job ရဲ့ file တွေကို လုံးဝ မမြင်လို့ပါ။ ပထမတွေ့တဲ့အခါ ထပ်နေသလို ခံစားရပေမယ့် ဒါက runner သီးသန့်စီ ဖြစ်တဲ့ သဘောသဘာဝကို တိုက်ရိုက် ရောင်ပြန်ဟပ်နေတာပါ။
step တွေကို သေချာကြည့်ပါ။ uses: actions/checkout@v4 က input မလိုတဲ့အတွက် with မပါပါဘူး။ uses: actions/setup-node@v4 ကတော့ with: node-version: '20' လိုအပ်ပါတယ် - '20' ကို quote ခံထားတာက YAML မှာ quote မခံရင် နံပါတ်အဖြစ် ဖတ်လို့ဖြစ်ပြီး၊ '20.10' လိုမျိုးဆိုရင် ပိုဆိုးပါတယ် (float ဖြစ်သွားပြီး နောက်က သုည ပျောက်နိုင်ပါတယ်)။ ဒါကြောင့် version string တွေကို quote အမြဲ ခံပါ။
run: step တွေက runner ရဲ့ shell (Linux မှာ bash) ထဲမှာ တိုက်ရိုက် execute လုပ်ပါတယ်။ step တစ်ခုစီဟာ shell process အသစ်ဖြစ်လို့ step တစ်ခုမှာ cd လုပ်ထားတာ နောက် step ကို မလိုက်ပါဘူး - directory ပြောင်းချင်ရင် working-directory ကို သုံးပါ။ log ထဲမှာ step တစ်ခုစီက ဖွင့်လို့ရတဲ့ ခေါင်းစဉ်တစ်ခုစီ ဖြစ်လာလို့ name ရေးထားရင် ဘယ်နေရာ ကျရှုံးလဲ ချက်ချင်း တွေ့ရပါတယ်။
အတူတူ စမ်းရေးကြည့်မယ်
name: Anatomy Demo
on: [push]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
- run: npm ci
- name: Lint the source
run: npm run lint
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Node.js
uses: actions/setup-node@v4
with:
node-version: '20'
cache: npm
- run: npm ci
- name: Run unit tests in the api package
working-directory: packages/api
run: npm test
push တိုင်းမှာ ဒီ workflow က run ပြီး job နှစ်ခုဖြစ်တဲ့ lint နဲ့ test ကို တစ်ပြိုင်နက် စတင်ပါတယ်၊ တစ်ခုစီက ubuntu-latest runner အသစ် သီးသန့်စီ ရပါတယ်။ Actions tab မှာ job နှစ်ခု ဘေးချင်းယှဉ်လျက် ပေါ်နေမှာဖြစ်ပြီး တစ်ခုက ကျရှုံးလည်း ကျန်တစ်ခုက ဆက်ပြီး run နေပါလိမ့်မယ်။ job တစ်ခုစီအတွင်းမှာတော့ step တွေက အစဉ်လိုက် run ပြီး၊ step တစ်ခု ကျရှုံးရင် အဲဒီ job ရဲ့ ကျန် step တွေကို ကျော်ပစ်ပါတယ်။ test job ရဲ့ npm test က packages/api directory ထဲမှာ run ပါတယ်။ job နှစ်ခုလုံး အောင်မြင်မှသာ run တစ်ခုလုံး အစိမ်းရောင် ဖြစ်ပါတယ်။၅ မိနစ် စမ်းကြည့်
အထက်ပါ workflow ကို ကူးယူပြီး lint job ရဲ့ ပထမ step ဖြစ်တဲ့ actions/checkout@v4 ကို ဖျက်လိုက်ပါ။ push လုပ်ပြီး Actions tab မှာ ဘယ်လို ကျရှုံးလဲ ကြည့်ပါ - error message က ဘာလို့ "file not found" မျိုး ဖြစ်နေလဲ ဆိုတာ စဉ်းစားပါ။ ပြီးရင် test job ထဲမှာ echo လုပ်တဲ့ step တစ်ခု ထည့်ပြီး၊ lint job က ဖန်တီးထားတဲ့ file တစ်ခုကို ဖတ်ကြည့်ပါ။ ဘာဖြစ်လဲ ခန့်မှန်းပြီးမှ run ကြည့်ပါ။
သတိလေးတစ်ချက်
file ကို .github/workflows/ အောက်မှာ မထားတာ၊ ဒါမှမဟုတ် .github/workflow/ (s မပါ) လို့ စာလုံးပေါင်းမှားတာ - GitHub က တိတ်တဆိတ် လျစ်လျူရှုပါတယ်။
job တွေ file ထဲက အစဉ်လိုက် run မယ်လို့ ထင်ပြီး job တစ်ခုက ဆောက်ထားတဲ့ file ကို နောက် job တစ်ခုမှာ ရှိမယ်လို့ မှတ်ယူတာ - needs နဲ့ artifact မပါဘဲ ဘယ်တော့မှ မရပါဘူး။
GitHub Docs - Workflow syntax for GitHub Actions — CI/CD with GitHub Actions