နောက်ဆုံး blog post ရေးခဲ့တာက ပြီးခဲ့တဲ့ဇန်နဝါရီလကဆိုတော့ ဘာမှမရေးဖြစ်ခဲ့တာ တနှစ်နီးပါးလောက်တောင် ရှိသွားခဲ့ပါပြီ။ ဒီကြားထဲမှာ ကိုယ်ရေးကိုယ်တာကိစ္စတွေနဲ့ အာရုံများနေတာရော ပျင်းနေတာရောပါတယ်။ ဒီရက်ပိုင်းမှ Bubble Tea ကို စမ်းကြည့်ချင်တာရော personal income tax တွက်ဖို့ CLI app လေးတခုရေးချင်တာရောနဲ့ PIT Calculator CLI app လေးလုပ်ဖြစ်တယ်။ ရိုးရိုး CLI interface နဲ့ TUI interface ဆိုပြီး နှစ်ခုနဲ့ စမ်းကြည့်လို့ရပါတယ်။ Copilot အကူအညီနဲ့ ပါ README သေချာရေးဖြစ်သွားတော့ အဆင်ပြေရင် စမ်းကြည့်ကြစေချင်ပါတယ်။ Life insurance နဲ့ တခြား အခွန်သက်သာခွင့်တွေရယ် bonus နဲ့ တခြား taxable income တွေအတွက်ရယ်တော့ ထပ်ထည့်ဖို့တော့ ကျန်ပါဦးမယ်။
နိဒါန်း#
Software development မှာ code quality နဲ့ consistency ဆိုတာ မဖြစ်မနေလိုအပ်တဲ့အရာတွေပါ။ Team နဲ့လုပ်ရတဲ့ project တွေမှာဆို coding style တယောက်တမျိုးစီရေးကြတာတွေကြောင့် ဖတ်ရခက်တာမျိုးတွေ၊ bug ဖြစ်စေနိုင်တဲ့ ပုံစံမျိုးတွေ မပါဖို့နဲ့ unreachable code တွေ မရှိနေဖို့ အတွက် PR နဲ့ stable branch ကို code merge တာတွေမှာ linting က အရေးကြီးပါတယ်။
အခု post မှာတော့ PIT Calculator CLI app မှာသုံးထားတဲ့ linter အတွက် workflow အကြောင်းကွက်ပြီး ပြောပြချင်လို့ပါ။ အလုပ်မှာကတော့ သုံးဖြစ်ပေမည့် personal project မှာတော့ Hugo ရဲ့ deployment အတွက်ကလွဲရင် အခုမှစသုံးဖြစ်တာပါ။
Workflow For Lint#
ဒါက ကျွန်တော်လက်ရှိသုံးဖြစ်နေတဲ့ Go အတွက် linter workflow ပါ။
name: Lint
permissions:
contents: read
on:
push:
branches: [main]
paths:
- "cmd/**"
- "pkg/**"
- "go.mod"
- "go.sum"
- ".github/workflows/lint.yml"
pull_request:
branches: [main]
paths:
- "cmd/**"
- "pkg/**"
- "go.mod"
- "go.sum"
- ".github/workflows/lint.yml"
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v6
- name: Set up Go
uses: actions/setup-go@v6
with:
go-version: "1.25.5"
# Caching prevents redownloading dependencies on every run until
# go.mod/go.sum changes
- name: Cache Go modules
uses: actions/cache@v5
with:
path: |
~/go/pkg/mod # Go modules cache
~/.cache/go-build # Go build cache
key: ${{ runner.os }}-go-${{ hashFiles('**/go.sum') }}
# Ensures gofmt sees only actual Go code that belongs to your module
- name: Run go fmt
run: |
FILES=$(gofmt -s -l $(go list -f '{{.Dir}}' ./...))
if [ -n "$FILES" ]; then
echo "❌ Formatting issues found:"
echo "$FILES"
exit 1
fi
echo "✅ Code formatting is correct"
- name: Run go vet
run: |
go vet ./...
echo "✅ Code analysis passed"
- name: Check for imports
run: |
go mod tidy
if [ -n "$(git diff --name-only go.mod go.sum)" ]; then
echo "❌ go.mod/go.sum are not tidy. Run 'go mod tidy' to fix:"
git diff
exit 1
fi
echo "✅ Dependencies are tidy"
Breaking Down#
1. Staring on:#
on:
push:
branches: [main]
paths:
- "cmd/**"
- "pkg/**"
- "go.mod"
- "go.sum"
- ".github/workflows/lint.yml"
pull_request:
branches: [main]
paths:
- "cmd/**"
- "pkg/**"
- "go.mod"
- "go.sum"
- ".github/workflows/lint.yml"
ဒီ on: အပိုင်းက workflow ကို ဘယ်အချိန်မှာစအလုပ်လုပ်မယ်ဆိုတာကို သတ်မှတ်ထားတာပါ။
pushနဲ့pull_requestနှစ်ခုလုံးမှာ အလုပ်လုပ်ပါမယ်။branches: [main]ဆိုတာကmainbranch ကို code push တာ ဒါမှမဟုတ်mainbranch ကို PR တင်တာမျိုးလုပ်မှသာ အလုပ်လုပ်ပါလိမ့်မယ်။paths:မှာcmd/**၊pkg/**အစရှိတဲ့ Go file တွေ ဒါမှမဟုတ် workflow filelint.ymlကို ပြင်မှသာ ဒီ workflow ကို run မှာဖြစ်လို့ လိုအပ်တဲ့အချိန်မှာပဲ run ပြီး GitHub Actions အတွက် ကုန်ကျစရိတ်ကိုလျှော့ချလို့ရပါတယ်။
2. Preparing Environment And Caching#
runs-on: ubuntu-latest: Job ကို Ubuntu latest environment ပေါ်မှာ run ပါမယ်။uses: actions/setup-go@v6: Go v1.25.5 ကို install လုပ်ပါမယ်။actions/cache@v5:go.sumfile မှာ အပြောင်းအလဲမရှိသ၍ Go modules တွေကို ပြန်ပြီး download လုပ်စရာမလိုတော့ဘဲ cache ကနေ ပြန်ယူသုံးတဲ့အတွက် build time ကို သိသိသာသာ လျှော့ချပေးပါတယ်။ အချိန်ကုန်ငွေကုန်သက်သာစေတဲ့ အဓိကအချက်ပါ။
3. Code Formatting#
FILES=$(gofmt -s -l $(go list -f '{{.Dir}}' ./...))
if [ -n "$FILES" ]; then
echo "❌ Formatting issues found:"
echo "$FILES"
exit 1
fi
echo "✅ Code formatting is correct"
gofmt -s -l: သေချာ format မလုပ်ထားတဲ့ file list ကို ထုတ်ပေးပါတယ်။if [ -n "$FILES" ]; then:$FILESထဲမှာ file တွေပါနေတယ်ဆိုရင် workflow ကိုexit 1နဲ့ fail လိုက်မှာပါ။ ဒါက format မမှန်တဲ့ code တွေmainbranch ထဲရောက်မသွားအောင် ကာကွယ်ထားတာပါ။
4. Static Code Analysis#
go vet ./...: format string မှားတာ(%s နေရာမှာ %d လိုမျိုး format specifier မှားသုံးထားတာမျိုး)တွေ၊ shadowed variable တွေ၊ struct tag မှားသုံးထားတာတွေ၊ unreachable code တွေနဲ့ unsafe conversion တွေကို စစ်ပေးတာပါ။
5. Checking Unused Dependencies#
go mod tidy
if [ -n "$(git diff --name-only go.mod go.sum)" ]; then
echo "❌ go.mod/go.sum are not tidy. Run 'go mod tidy' to fix:"
git diff
exit 1
fi
echo "✅ Dependencies are tidy"
go mod tidy: မလိုအပ်တဲ့ dependency တွေကို ရှင်းပေးပြီး လိုတာတွေကိုထည့်ပေးပါတယ်။if [ -n "$(git diff --name-only go.mod go.sum)" ]; then:git diffနဲ့go.modဒါမှမဟုတ်go.sumfile တွေမှာ ပြောင်းလဲတာရှိမရှိ စစ်တာပါ။ ပြောင်းလဲတာရှိရင် (ဆိုလိုတာက developer ကgo mod tidyကို မ run ခဲ့ဘူး) လို့ ယူဆပြီး workflow ကိုexit 1နဲ့ fail လိုက်မှာပါ။
နိဂုံး#
ဒီ linting workflow က code quality နဲ့ issue ကို ၁၀၀% မစစ်ပေးနိုင်ပါဘူး။ PR review လုပ်တဲ့အခါမှာ အကူအညီဖြစ်အောင်နဲ့ reviewer မမြင်လိုက်တာတွေ ပါမသွားအောင် တဘက်တလမ်းကနေ ကူညီနိုင်တာပဲရှိတာပါ။ မှန်ကန်တဲ့ design pattern တွေသုံးဖို့၊ maintainability ကို ကျစေတဲ့ cognitive complexity နည်းဖို့တွေကတော့ ကိုယ်တိုင်ပဲလုပ်ရမှာပါ။ နောက်ပိုင်းကျရင် တခြားအသုံးဝင်တဲ့ workflow တွေလည်း ထပ်ရေးကြည့်ပါဦးမယ်။ အခုလက်ရှိ repo တွေမှာလည်း ကြည့်လို့ရပါတယ်။
