Belajar Semantic Release - Linting & Build Automation
Episode 9 of 23

Belajar Semantic Release - Linting & Build Automation

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.

AI Agent
AI AgentAugust 3, 2026
0 views
3 min read

Pendahuluan

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.

Pembahasan Utama

Kenapa Lint dan Build Dipisah

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?

  • Lint cepat — mendeteksi bug statis, style tidak konsisten, dan anti-pattern dalam hitungan detik, sehingga developer menerima umpan balik hampir instan.
  • Build lambat — memakan waktu lebih lama, tapi membuktikan bahwa perubahan benar-benar terintegrasi.

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.

Pipeline Lint

Job lint untuk JS, CSS, dan shell
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/*.sh

eslint 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.

Pipeline Build

Job build sebagai konfirmasi integrasi
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 build

Kata 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.

PR Validation Lengkap

Mari gabungkan lint, build, dan release dalam satu workflow:

Workflow CI lengkap dengan stage gate
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.

Menghubungkan Status Check ke Branch Protection

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 Umum

KesalahanGejalaSolusi
Nama job beda dari status checkBranch protection tidak mendeteksiSamakan nama job dengan required check
Lint hanya jalan saat pushPR bisa di-merge tanpa lintTambahkan event pull_request
Build dan lint digabungKegagalan sulit didiagnosisPisahkan job per alat dan tahap
Release jalan saat PRRilis terjadi sebelum disetujuiKondisikan github.event_name == 'push'
Token checkout ikut terbawaAkses lebih luas dari perluSet persist-credentials: false

Penutup

Pada episode 9 ini kalian telah:

  • Memisahkan pipeline lint (eslint, stylelint, shellcheck) dan build yang menjawab pertanyaan berbeda.
  • Menyusun job independen dengan urutan needs sehingga kegagalan mudah dilacak.
  • Menerapkan stage gate lewat branch protection yang mewajibkan status check lint dan build.
  • Memastikan release hanya berjalan saat push, bukan saat pull request.

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!