Rust: Otomasi lint, format, dan testing dengan cargo devtools menyelesaikan kebutuhan pengembang Rust yang ingin menggabungkan format, lint, dan test dalam workflow otomatis. Artikel ini menjelaskan langkah konfigurasi cargo fmt, clippy, dan test melalui cargo devtools, lalu memasangkannya ke hook pre-commit serta pipeline CI tanpa mengorbankan kegesitan release.

1. Menyiapkan cargo devtools sebagai entrypoint workflow

cargo devtools menyediakan wrapper untuk mengelola toolchain linting dan testing secara konsisten. Mulailah dengan menambahkan dependensi devtools di Cargo.toml:

[dev-dependencies]
cargo-devtools = "*"

Setelah menginstal, buat file konfigurasi dalam .cargo/devtools.toml yang mendefinisikan task:

[tasks.fmt]
command = "cargo"
args = ["fmt"]

[tasks.clippy]
command = "cargo"
args = ["clippy", "--all-targets", "--all-features", "--", "-D", "warnings"]

[tasks.test]
command = "cargo"
args = ["test", "--workspace"]

Rancang task devtools untuk merepresentasikan tujuan lint, format, dan test. Di environment yang sama, `cargo devtools run fmt` menjadi standar untuk format, sementara `cargo devtools run clippy` dan `cargo devtools run test` menjaga keandalan quality gates.

2. Menggabungkan fmt, clippy, dan test dalam flow developer

Pengembang sebaiknya menjalankan fmt/clippy/test secara lokal sebelum commit. Gunakan cargo devtools untuk memudahkan, misalnya:

cargo devtools run fmt && cargo devtools run clippy && cargo devtools run test

Dengan mengunci perintah di devtools, tim tidak perlu mengingat opsi tambahan. Selain itu, tambahkan file .cargo/config.toml untuk menyetel target default dan cache build agar perintah berjalan konsisten:

[build]
target-dir = "target"

[unstable]
build-std = []

Folder target tunggal memungkinkan caching lint/test lintas task, yang penting untuk pipeline CI nanti.

3. Hook pre-commit dengan cargo-husky

Supaya developer tidak melewati tahap lint/test, gunakan cargo-husky untuk hook git. Pertama pasang dependency:

cargo install cargo-husky

Selanjutnya buat template hook di .husky/pre-commit yang memanggil devtools:

#!/bin/sh
cargo devtools run fmt && cargo devtools run clippy

Jangan lupa menambahkan chmod +x .husky/pre-commit. Hook seperti ini memastikan format dan lint dijalankan sebelum commit, meski developer memilih opsi GUI. Hindari menjalankan test lengkap di pre-commit jika workspace besar; cukup fmt dan clippy untuk menjaga kecepatan.

4. Pipeline lint dan test di GitHub Actions

Untuk lint dan testing otomatis pada push atau pull request, buat workflow minimal .github/workflows/ci.yaml:

name: CI

on:
  push:
    branches: ["main"]
  pull_request:
    branches: ["main"]

jobs:
  lint-test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Set up Rust
        uses: actions-rs/toolchain@v1
        with:
          toolchain: stable
          components: clippy, rustfmt
          override: true
      - name: Cache cargo
        uses: actions/cache@v4
        with:
          path: |
            target
            ~/.cargo/registry
            ~/.cargo/git
          key: ${{ runner.os }}-cargo-${{ hashFiles('**/Cargo.lock') }}
          restore-keys: |
            ${{ runner.os }}-cargo-
      - name: Run fmt
        run: cargo devtools run fmt
      - name: Run clippy
        run: cargo devtools run clippy
      - name: Run test
        run: cargo devtools run test

Cache target dan registri mempercepat lint/test di setiap job. Gunakan kunci cache yang bergantung pada Cargo.lock agar pembaruan dependency otomatis memicu restore baru. Jika workspace besar, pertimbangkan job terpisah untuk lint dan test agar parallelisasi lebih efisien.

5. Strategi caching dan incremental lint

Linting dengan clippy bisa lambat pada workspace besar. Untuk mempercepat, aktifkan fitur incremental compilation bawaan Rust (aktif secara default). Pastikan direktori target digunakan bersama di lokal dan CI agar artifact reusable. Dalam repo monorepo, gunakan flag --package atau --workspace untuk membatasi scope lint saat hanya ada perubahan kecil.

Untuk kontrol fine-grain, buat script yang mendeteksi crate yang berubah lalu menjalankan clippy hanya di crate tersebut:

changed=$(git diff --name-only origin/main | grep '^crates/' | cut -d'/' -f2 | uniq)
for crate in $changed; do
  cargo clippy -p "$crate" --all-targets
done

Metode incremental seperti ini mengurangi beban lint saat PR hanya menyentuh beberapa crate.

6. Monitoring status lint dan testing

Laporkan hasil lint/test ke sistem notifikasi agar tim tahu kapan pipeline gagal. GitHub Actions sudah menampilkan status di PR, tapi tambahkan badge di README untuk status terbaru. Jaga log yang jelas dengan format cargo devtools run clippy -- -D warnings sehingga setiap peringatan diperlakukan serius.

Monitoring aktif meningkatkan DX karena developer tahu apakah commit mereka menyelesaikan masalah sebelum merging. Fokuskan pada pesan log reformatting (fmt) yang bisa diamati di diff, dan pastikan clippy warning lawas dilog agar tidak menumpuk.

7. Mencegah false positive dan troubleshooting

False positive clippy biasanya muncul dari lint seperti clippy::restriction; sesuaikan clippy.toml untuk menonaktifkan lint yang relevan atau beri allow di level modul. Ini mencegah developer berhenti karena warning yang tidak berlaku.

Diagnosa umum:

  • fmt tidak mengubah apa pun: Pastikan rustfmt versi sama dengan toolchain, jalankan rustup component add rustfmt.
  • Cache rusak: Jika job CI melewatkan perubahan dependency, bersihkan cache manual dan kunci cache per commit dengan hashFiles.
  • Hook tidak berjalan: Periksa izin file .husky/pre-commit dan bahwa cargo-husky diinstal di path developer.

Sertakan dokumentasi di repo tentang cara menonaktifkan lint tertentu untuk alasan valid, dan gunakan issue template untuk menangani false positive agar solusinya tersentralisasi.

Kesimpulan

Dengan cargo devtools sebagai otak workflow lint-format-testing, cargo-husky untuk pre-commit, dan GitHub Actions dengan cache, proyek Rust dapat menjaga kualitas kode sambil mempertahankan kecepatan pengembangan. Kombinasi tooling ini memperkuat monitoring lint/test, memungkinkan pengambilan tindakan cepat terhadap kegagalan, serta menjaga false positive terkendali lewat konfigurasi yang eksplisit.