Linting paralel untuk setiap paket TypeScript dalam monorepo dan release otomatis di CI itu bisa diatur secara deterministik: jalankan linting dan tes secara terisolasi, kumpulkan hasilnya, lalu baru biarkan pipeline merilis saat semuanya sukses. Dalam panduan ini saya tunjukkan bagaimana mengonfigurasi pnpm/Nx, mengelola lint-staged atau ESLint paralel, dan menautkannya dengan tahap release otomatis di GitHub Actions.
Fokusnya adalah membuat CI yang bisa dipercaya—linting dijalankan serentak di seluruh paket, hasilnya terakumulasi, dan hanya jika linting dan tes valid maka stage release (generate changelog, tagging, publish npm) dijalankan. Berikut langkah-langkah terperinci dan contoh YAML konkret.
Mengurai tantangan linting paralel di monorepo TypeScript
Monorepo TypeScript biasanya terdiri dari banyak paket yang punya konfigurasi ESLint masing-masing. Menjalankan linting secara serial di seluruh paket bisa memakan waktu. Maka dari itu, gunakan fitur paralel yang ditawarkan pnpm atau Nx untuk mengeksekusi linting per paket sekaligus.
Jika menggunakan pnpm, pastikan Anda menulis script lint di package.json di root ataupun setiap paket. Contoh struktur skrip:
{
"scripts": {
"lint": "eslint . --ext .ts,.tsx",
"lint:packages": "pnpm --parallel --filter "@org/*" lint"
}
}
Dengan flag --parallel dan --filter Anda bisa memanggil linting untuk paket-paket yang relevan secara bersamaan. Jangan lupa define pnpm-workspace.yaml agar pnpm mengenali relasi antar paket.
Alternatifnya, jika Anda memakai Nx, gunakan target lint dan jalankan nx run-many --target=lint --parallel. Nx mengoptimalkan dependensi dan mendeteksi paket-paket yang tidak berubah sehingga linting hanya dilakukan di apa yang perlu.
Lint-staged masih penting untuk menjaga kualitas kode di developer machine. Jalankan lint-staged untuk memformat file yang di-commit, tapi dalam konteks CI gunakan lint global agar tidak bergantung pada env lokal.
Pipeline CI langkah demi langkah
Desain pipeline harus berurutan: pertama install dan cache, lalu linting paralel, tes, dan terakhir release otomatis. Berikut langkah-langkahnya:
- Instal dependensi dan caching: gunakan cache untuk pnpm store dan node_modules agar install lebih cepat. Simpan file
pnpm-lock.yamldannode_modules/.pnpm. - Linting paralel per paket: jalankan
pnpm lint:packagesataunx run-many --target=lint --parallel. Simpan log dan gunakan reporter yang bisa diaggregate (misal format JUnit) bila Anda butuh integrasi hasil. - Agregasi hasil linting: jika lint gagal di satu paket, pipeline harus langsung berhenti. Sertakan output path file agar tim mudah men-debug. Bisa juga tambahkan langkah tambahan untuk menyimpan artefak log lint agar reviewer bisa melihat detail.
- Jalankan tes unit/integrasi: jalankan
pnpm testataunx run-many --target=test --parallelsesudah lint sukses. - Release otomatis: hanya jika lint dan tes sukses, jalankan job release yang membuat changelog, menandai commit, dan melakukan
pnpm publish.
Dengan pendekatan ini, linting dan testing melewati seluruh paket sebelum job release dijalankan. Jika linting gagal, job release tidak akan dieksekusi karena job release bergantung (needs) pada lint/test yang sukses.
Contoh GitHub Actions pipeline
Berikut contoh file .github/workflows/ci.yml yang menerapkan linting paralel dan release otomatis:
name: CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
lint-test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 9
- name: Restore pnpm cache
uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
- name: Install dependencies
run: pnpm install
- name: Lint semua paket
run: pnpm lint:packages
- name: Jalankan tes
run: pnpm test
release:
needs: lint-test
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
steps:
- uses: actions/checkout@v4
- uses: pnpm/action-setup@v2
with:
version: 9
- name: Restore pnpm cache
uses: actions/cache@v4
with:
path: ~/.pnpm-store
key: pnpm-store-${{ hashFiles('pnpm-lock.yaml') }}
- name: Install dependencies
run: pnpm install --frozen-lockfile
- name: Generate changelog
run: pnpm conventional-changelog -p angular -i CHANGELOG.md -s
- name: Create release tag
run: |
VERSION=$(node -p "require('./package.json').version")
git tag v$VERSION
git push origin v$VERSION
- name: Publish ke npm
run: pnpm publish --access public
env:
NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }}
Job lint-test menjalankan linting paralel lalu tes. Job release membutuhkan job sebelumnya sukses, dan hanya berjalan di branch main.
Mekanisme release otomatis dan gate lint/test
Release otomatis membutuhkan tiga hal utama:
- Generate changelog otomatis: gunakan tool seperti
conventional-changelogatauchangesets. Di pipeline hanya jalankan tool ini setelah lint + tes berhasil. - Tagging: pipeline harus memanfaatkan versi dari
package.jsonatau tool versioning, lalu buat tag Git dan push instant. - Publish npm: langkah terakhir, hanya dieksekusi bila semua job sebelumnya berhasil, dan memerlukan token npm aman di GitHub Secrets.
Gunakan job dependency via needs agar release tidak jalan bila lint/test gagal. Tambahkan if: github.ref == 'refs/heads/main' untuk mencegah release dari cabang lain.
Jika menggunakan Nx, release job bisa memanggil target khusus misalnya nx release yang menggabungkan lint, tes, changelog, dan publish.
Tips caching dan debugging
Cache sangat penting untuk kecepatan:
- Simpan pnpm store dengan
actions/cache. Gunakan key berbasis hash lockfile agar cache invalid saat lockfile berubah. - Cache node_modules/ pnpm store agar proses install lebih cepat, khususnya untuk linting paralel yang membutuhkan dependensi.
- Jika linting mengalami timeouts, periksa parallel limit di ESLint: Anda bisa gunakan
ESLINT_PARALLEL=4ataupnpm lint -- --max-warnings=0untuk menghindari warning.
Debugging linting paralel: jika job lint menyatakan failed tapi output tidak jelas, tambahkan step tambahan untuk mencetak pnpm lint --report-unused-disable-directives atau gunakan reporter JUnit agar Anda bisa melihat file tepatnya.
Dengan desain ini, CI Anda akan menjalankan linting per paket secara paralel, hasil linting dan test dijadikan gate untuk release otomatis, dan caching menjaga pipeline tetap responsif.
Komentar
0 komentar
Masuk ke akun kamu untuk ikut berkomentar.
Belum ada komentar
Jadilah yang pertama ikut berdiskusi!