Pengenalan langsung

Untuk menghindari backlog lint yang menghambat rilisan, rakit pipeline lint paralel yang bisa dijalankan di runner self-hosted menggunakan cargo-make. Artikel ini menunjukkan cara menyusun task runner, memastikan lint dipanggil sebelum commit lewat cargo-husky, serta menerapkan caching artefak lint dan feedback loop cepat agar pengalaman developer tetap responsif.

Langkah-langkah berikut akan memberikan konfigurasi nyata agar lint bisa berjalan simultan, cache output yang mahal, dan tetap stabil saat tim menyiapkan rilis.

Desain workflow lint paralel dengan cargo-make

cargo-make memungkinkan kita mendefinisikan task lint yang bisa dijalankan dalam flow. Gunakan flow khusus lint untuk mengelompokkan format, clippy, dan checker keduanya, lalu jalankan secara paralel agar tidak menunggu satu per satu.

Contoh konfigurasi Makefile.toml

Berikut setup minimal yang memperlihatkan task lint paralel dan langkah cache:

[config]
default_task = "lint_pipeline"

[tasks.fmt]
description = "Cek format"
command = "cargo"
args = ["fmt", "--", "--check"]

[tasks.clippy]
description = "Clippy"
command = "cargo"
args = ["clippy", "--", "-D", "warnings"]

[tasks.lint-tests]
description = "Unit test sebagai bagian lint"
command = "cargo"
args = ["test", "--lib"]

[flows.lint_pipeline]
tasks = ["fmt", "clippy", "lint-tests"]
parallel = true

Atur flag parallel = true di flow sehingga cargo-make memanggil task bersamaan. Output tetap tertata karena cargo-make menampung log masing-masing task.

Penerapan cargo-husky pre-commit

Letakkan script cargo make lint_pipeline pada hook pre-commit agar semua perubahan lokal melewati lint sebelum push. Struktur di .husky/pre-commit bisa seperti ini:

#!/bin/sh
. "$(dirname "$0")/_/husky.sh"

cargo make lint_pipeline

Dengan pre-commit, developer mendapatkan feedback cepat saat mereka menyimpan. Pastikan tugas yang berat tetap ter-cache sehingga hook tidak menjadi beban.

Runner self-hosted dan caching artefak lint

Runner self-hosted membantu mengontrol environment dan memanfaatkan cache pada storage lokal. Berikut prinsip utama:

  1. Cache dependency: simpan ~/.cargo/registry dan target agar cargo fmt dan clippy tidak mengunduh ulang dependency.
  2. Cache artefak lint: simpan target lint seperti target/debug/deps karena clippy sering memerlukan build ulang. Poin penting: cache tersebut harus invalidasi saat CARGO_HOME berubah atau saat Cargo.lock diubah.
  3. Self-hosted runner: jalankan cargo make lint_pipeline di runner khusus agar tidak bersaing resource dengan build lain. Atur service systemd untuk mengecek versi toolchain agar tetap konsisten.

Contoh langkah caching di GitHub Actions dengan runner self-hosted:

steps:
  - name: Restore cargo cache
    uses: actions/cache@v4
    with:
      path: |
        ~/.cargo/registry
        ~/.cargo/git
        target
      key: rust-cargo-${{ hashFiles('**/Cargo.lock') }}

  - name: Run lint pipeline
    run: cargo make lint_pipeline

Penggunaan key berdasarkan hash Cargo.lock memastikan cache invalid ketika dependency berubah, tapi tetap luas untuk lint.

Membangun feedback loop cepat dan menjaga lint stabil saat rilis

Untuk developer experience yang baik:

  • Lint lokal ringan: tampilkan lint paling umum di editor (Rust Analyzer + clippy lint level) agar masalah terdeteksi sebelum commit.
  • Cache parcial: aktifkan cache lint di CI dan hook pre-commit untuk meminimalkan waktu respon. Sample: cache target/debug/deps dan target/debug/build.
  • Lint gating di release: hanya pipeline lint yang telah berhasil pada branch main bisa di-merge. Terapkan override task cargo make lint_pipeline --makefile Makefile.toml --profile release untuk memastikan flag release diterapkan.

Dengan pendekatan ini, rilisan tidak tergantung pada lint yang tidak stabil karena lint dijalankan ulang dengan dependency dan target tersinkronisasi.

Contoh workflow GitHub Actions untuk pipeline lint

Jika perlu alternatif selain runner self-hosted, gunakan GitHub Actions dengan job lint yang juga menjalankan cargo-make paralel dan caching. Pastikan job hanya dieksekusi pada push atau PR ke branch tertentu.

name: Rust Lint Pipeline

on:
  push:
    branches: [main, develop]
  pull_request:
    branches: [main]

jobs:
  lint:
    runs-on: [self-hosted, linux]
    steps:
      - uses: actions/checkout@v4
      - name: Restore cargo cache
        uses: actions/cache@v4
        with:
          path: |
            ~/.cargo/registry
            ~/.cargo/git
            target
          key: rust-lint-${{ runner.os }}-${{ hashFiles('**/Cargo.lock') }}
      - name: Setup Rust toolchain
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          override: true
      - name: Run lint pipeline
        run: cargo make lint_pipeline

Pemilihan runner dengan tag self-hosted menjamin kontrol terhadap hardware dan cache lokal. Jika lupa tag, job akan dialihkan ke runner GitHub hosted yang mungkin lebih lambat.

Tips troubleshooting saat lint gagal

Ketika lint gagal, diagnosis cepat penting. Berikut langkah-langkah:

  1. Periksa output cargo-make: cargo-make mencetak log per task. Carilah task yang menghasilkan exit code non-zero.
  2. Reproduksi lokal: jalankan cargo make lint_pipeline di mesin pengembang atau runner untuk memastikan tidak ada resource yang hilang.
  3. Cek cache: jika clippy gagal karena binary lama, bersihkan cache dengan cargo clean dan hapus folder target yang ditargetkan untuk lint.
  4. Update toolchain: pastikan rustup toolchain konsisten. Jalankan rustup show untuk memastikan stable dipakai.
  5. Cek konfigurasi Cargo.husky: jika pre-commit memblokir push tapi pipeline lint berhasil, mungkin versi cargo-make tidak ditemukan di PATH. Pastikan hook memanggil cargo make lewat toolchain yang sama.

Debug log lengkap dan perhatian pada caching membantu tim menemukan penyebab tanpa menunggu queue CI panjang.

Kesimpulan

Dengan cargo-make sebagai task runner utama, cargo-husky pre-commit, caching artefak lint, dan runner self-hosted/GitHub Actions yang disesuaikan, Anda bisa mempertahankan lint paralel yang cepat tanpa mengorbankan stabilitas rilisan. Siapkan cache dengan hati-hati, jalankan lint secara paralel, dan selalu beri feedback loop cepat bagi developer.