Menyusun pipeline lint dan build yang terpisah sebagai gerbang kualitas sebelum rilis. Menghubungkan status check ke validasi pull request serta menerapkan stage gate agar hanya kode yang lolos lint dan build yang boleh digabungkan ke branch utama.

Di episode 8 commit analyzer menentukan kapan rilis terjadi, tetapi kualitas kodenya ditentukan jauh sebelumnya. Semantic-release hanya menaikkan versi dan menerbitkan package — ia tidak peduli apakah kode itu rusak. Kalau kode jelek lolos sampai ke rilis, hasilnya tetap rilis jelek.
Episode ini membangun gerbang kualitas: pipeline lint yang memisahkan eslint, stylelint, dan shellcheck dari build, menghubungkannya ke validasi pull request, dan menerapkan stage gate agar hanya kode yang lolos yang boleh di-merge.
Lint dan build menjawab dua pertanyaan berbeda. Lint menanyakan: apakah kode ini ditulis dengan benar dan konsisten? Build menanyakan: apakah kode ini bisa dikompilasi menjadi artefak yang berfungsi?
Dengan memisahkannya, kegagalan lebih mudah diidentifikasi. Lint gagal berarti masalah di kode; build gagal berarti masalah di integrasi. Kalau keduanya digabung, kalian tidak tahu mana yang harus diperbaiki lebih dulu.
name: Lint
on:
pull_request:
push:
branches: [main, staging]
jobs:
eslint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm run lint
stylelint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npx stylelint "src/**/*.css"
shellcheck:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- run: shellcheck scripts/*.sheslint menangani JavaScript dan TypeScript, stylelint menangani CSS, shellcheck memeriksa skrip shell — masing-masing sebagai job independen. Job independen berarti hasil setiap alat bisa dilihat dan dianalisis sendiri-sendiri, dan satu kegagalan tidak menyembunyikan kegagalan lainnya.
jobs:
build:
runs-on: ubuntu-latest
needs: [eslint, stylelint, shellcheck]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm run buildKata kunci needs memastikan build baru berjalan setelah ketiga job lint lolos. Ini menghemat waktu runner: tidak ada gunanya membangun kode yang sudah jelas melanggar aturan.
Mari gabungkan lint, build, dan release dalam satu workflow:
name: CI
on:
pull_request:
push:
branches: [main, staging]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm run lint
- run: npx stylelint "src/**/*.css"
- run: shellcheck scripts/*.sh
build:
runs-on: ubuntu-latest
needs: [lint]
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: 22
- run: npm ci
- run: npm run build
release:
runs-on: ubuntu-latest
needs: [build]
if: github.event_name == 'push'
permissions:
contents: write
steps:
- uses: actions/checkout@v4
with:
persist-credentials: false
- run: npm ci
- name: Semantic Release
run: npx semantic-release
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}Tiga lapis: lint menjalankan semua alat lint, build menunggu lint dan membangun artefak, release menunggu build dan hanya berjalan saat push ke main atau staging — bukan saat pull request. Dengan persist-credentials: false, token checkout tidak terbawa ke langkah berikutnya.
Warning
Untuk menerapkan stage gate, aktifkan branch protection pada main
dan staging di Settings > Branches, lalu "Require status checks to pass
before merging". Nama status check harus sama persis dengan nama job,
misalnya lint dan build, dan job itu harus berjalan pada event
pull request. Kalau job hanya berjalan saat push, status check tidak
muncul di PR dan penggabungan tidak akan terblokir.
Status check adalah bukti yang ditampilkan GitHub di halaman pull request. Ketika job bernama lint gagal, PR menampilkan tanda silang dan tidak bisa di-merge selama branch protection aktif. Ketika semua hijau, tombol merge aktif kembali.
Inilah yang dimaksud stage gate: satu-satunya pintu masuk kode ke main dan staging adalah PR yang lolos seluruh gerbang. Rilis hanya terjadi dari branch yang kodenya sudah tervalidasi.
Tip
Jaga job lint tetap cepat. Lint yang berjalan lebih dari dua menit biasanya menandakan scope terlalu luas atau caching tidak aktif. Pipeline yang cepat membuat stage gate terasa ringan dan developer tidak tergoda mencari jalan pintas.
| Kesalahan | Gejala | Solusi |
|---|---|---|
| Nama job beda dari status check | Branch protection tidak mendeteksi | Samakan nama job dengan required check |
| Lint hanya jalan saat push | PR bisa di-merge tanpa lint | Tambahkan event pull_request |
| Build dan lint digabung | Kegagalan sulit didiagnosis | Pisahkan job per alat dan tahap |
| Release jalan saat PR | Rilis terjadi sebelum disetujui | Kondisikan github.event_name == 'push' |
| Token checkout ikut terbawa | Akses lebih luas dari perlu | Set persist-credentials: false |
Pada episode 9 ini kalian telah:
needs sehingga kegagalan mudah dilacak.lint dan build.Di episode 10 kita akan memakai Semantic Release Dry Run & Verification — latihan penuh tanpa efek samping untuk memastikan versi dan changelog yang dihasilkan sudah benar sebelum rilis asli. Sampai jumpa di episode 10!