Pada banyak pipeline CI/CD, linting dan tes masih dijalankan penuh saat setiap commit masuk, padahal sebagian besar file yang tidak relevan tidak berubah. Linting & Tes CI/CD bisa dibuat lebih cepat dengan pendekatan caching yang meniru ide "useless if": hanya jalankan proses ketika diff memicu dependensi tertentu.
Dalam artikel ini kita akan bahas prinsip cache bertumpu pada file tracking dependensi, validasi diff sebelum eksekusi, serta bagaimana menambah langkah cerdas di pipeline (GitHub Actions/GitLab CI) agar developer experience (DX) tetap nyaman.
Masalah linting & tes rerun di setiap commit
Linting atau tes, misalnya unit test, sering kali memakai konteks proyek yang besar. Setelah satu perubahan kecil—misalnya README atau dokumentasi—pipeline tetap menjalankan seluruh suite, membuang waktu dan resource. Pendekatan tradisional bisa cukup, namun masukan tim juga ingin respons cepat. Di sini diperlukan strategi untuk mendeteksi apakah satu job harus dijalankan.
Konsep "Useless If" untuk linting dan tes yang selektif
Ide dari "useless if" adalah menambahkan pemeriksaan awal yang seolah-olah tidak berguna (misalnya if (!cacheHit) runExpensiveWork()), namun sebenarnya memutuskan apakah pekerjaan berat perlu dilakukan. Kita adaptasi ke linting & tes dengan mekanisme berikut:
Menentukan dependensi file
Buat file manifest dependensi yang mencatat file sumber apa saja yang memicu linting atau tes tertentu. Misalnya lint-deps.json berisi daftar path yang mestinya diobservasi. Saat pipeline berjalan, bandingkan diff dengan daftar ini. Jika tidak ada perubahan pada file-file tersebut, langkah linting dianggap tidak diperlukan.
Pendekatan ini butuh pemeliharaan: saat menambahkan modul baru yang perlu linting atau tes khusus, cukup update manifest. Karena manifest sendiri jarang berubah, cache yang menjaga hashing file-file sejauh ini tetap valid.
Validasi diff sebelum eksekusi
Pipeline membaca daftar file yang berubah dari commit (misal: git diff --name-only origin/main). Kemudian lakukan pencocokan dengan manifest dependensi. Jika tidak ada irisan, linting/t es dapat di-skip, dan pipeline mencatat cache tetap valid. Jika ada irisan, langkah selanjutnya berjalan dan hasilnya disimpan sebagai cache artifact.
Manfaat untuk DX developer
Developer mendapatkan umpan balik lebih cepat ketika perubahan kecil dikirim. Mereka juga tetap memiliki kepercayaan bahwa linting/t es dijalankan bila benar-benar diperlukan. Tambahan langkah pemeriksaan membuat pipeline terasa cerdas tanpa perlu intervensi manual.
Implementasi langkah cerdas di pipeline CI/CD
Berikut pendekatan umum:
- Hitung diff dengan branch target.
- Baca manifest dependensi (termasuk glob pattern bila perlu).
- Jika diff tidak memicu manifest, skip job linting/test dan gunakan cache artifact sebagai bukti validitas.
- Jika terpicu, jalankan lint/test dan simpan hasil ke cache yang dapat dipakai job berikutnya.
Contoh GitHub Actions
Berikut snapshot job linting yang mengecek diff dan memanfaatkan cache artifact:
name: CI
on:
pull_request:
branches: [main]
jobs:
lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Hitung diff terhadap target
id: diff
run: |
git fetch origin main
echo "files=$(git diff --name-only origin/main)")" >> $GITHUB_OUTPUT
- name: Baca manifest dependensi
id: deps
run: |
python - <<'PY'
import json
import pathlib
print('::set-output name=paths::' + json.dumps(json.load(open('lint-deps.json'))))
PY
- name: Tentukan skip lint
id: should_run
run: |
python - <<'PY'
import json, os
files = os.environ['FILES'].split()
deps = json.loads(os.environ['DEPS'])
if not any(f.startswith(dep) for dep in deps for f in files):
print('::set-output name=skip::true')
PY
env:
FILES: ${{ steps.diff.outputs.files }}
DEPS: ${{ steps.deps.outputs.paths }}
- name: Restore lint cache
uses: actions/cache@v3
with:
path: .cache/lint
key: lint-${{ github.sha }}
- name: Jalankan lint
if: steps.should_run.outputs.skip != 'true'
run: npm run lint
- name: Tandai lint sebagai dicache
if: steps.should_run.outputs.skip != 'true'
run: mkdir -p .cache/lint && touch .cache/lint/.lint-ok
Langkah should_run bertindak sebagai "useless if"—job linting hanya dijalankan kalau diff memicu manifest. Cache artifact (.cache/lint) disiapkan agar job berikutnya tahu apakah linting sudah dijalankan.
Variant GitLab CI/CD
Prinsipnya sama: gunakan rules:exists atau script untuk memeriksa diff, lalu gunakan cache: dengan key yang mencakup hash manifest. Misalnya, job lint akan memiliki when: on_success kalau validasi diff menentukan lint perlu dijalankan.
Dependency tracking dan caching artifact
Berikut praktik yang memperkuat sistem:
- Hash manifest: deteksi perubahan manifest dengan hash, sehingga perubahan file dependensi menginvalidasi cache.
- Caching berbasis artifact: simpan hasil linting, build, atau test berikut metadata (timestamp atau hash diff). Gunakan caching action atau job artifact agar job berikutnya dapat memvalidasi ulang tanpa rerun.
- Pelaporan status: ketika cache digunakan, berikan catatan di log bahwa linting/t es di-skip karena tidak ada perubahan relevan.
Debugging cache yang tidak valid
Jika linting/t es tidak berjalan padahal seharusnya, cek langkah berikut:
- Log diff: pastikan output diff memang mencakup file yang diubah. Kesalahan fetch atau ref bisa menyebabkan diff kosong.
- Periksa manifest: ada kemungkinan path tidak sesuai dengan struktur repo (misal, path relatif atau glob yang tidak cocok). Gunakan debug output untuk menampilkan isi manifest dan file yang match.
- Cache key mismatch: pastikan key cache menyertakan hash manifest/diff. Jika tidak, job lain bisa memakai cache lama yang tidak relevan.
- Fallback manual: tambahkan opsi environment seperti
FORCE_LINT=trueuntuk mengabaikan skip dan memaksa linting saat debugging.
Kesimpulan
Dengan menerapkan prinsip "useless if" sebagai langkah validasi diff sebelum linting dan tes, pipeline CI/CD lebih efisien tanpa mengorbankan kualitas. Tracking dependensi file, caching artifact hasil linting, dan debugging cache memastikan DX developer tetap nyaman sambil mengurangi waktu tunggu. Pendekatan ini sejalan dengan kebutuhan proyek modern yang ingin respons lintas team lebih cepat.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!