Jika tim Anda mengelola proyek Nuxt.js dan ingin proses rilis yang konsisten tanpa menaikkan versi serta menulis changelog secara manual, kombinasi Changesets dan GitHub Actions adalah pendekatan yang praktis. Intinya: setiap perubahan yang layak dirilis diberi metadata semver lewat changeset, CI memvalidasi kualitas kode, lalu branch utama memicu pembuatan release PR yang menyiapkan bump versi dan changelog otomatis.

Pendekatan ini cocok untuk tim kecil hingga menengah karena mengurangi kesalahan manusia, menjaga disiplin semantic versioning, dan tetap transparan di level pull request. Artikel ini fokus pada implementasi nyata untuk proyek Nuxt.js, bukan teori rilis secara umum.

Mengapa release flow otomatis penting untuk proyek Nuxt.js

Pada proyek Nuxt.js, perubahan bisa datang dari banyak sisi: komponen UI, composable, middleware, konfigurasi build, integrasi API, sampai paket internal jika repositori berbentuk monorepo. Tanpa alur rilis yang jelas, masalah umum yang sering muncul adalah:

  • versi paket naik tidak konsisten dengan dampak perubahan,
  • changelog tertinggal atau tidak akurat,
  • rilis dilakukan meski lint, test, atau build sedang gagal,
  • dua orang merilis perubahan yang sama,
  • token publish terlalu luas atau bocor di pipeline.

Dengan Changesets, keputusan versi dibuat saat perubahan masih ada di PR, bukan di akhir saat orang sudah lupa konteks. Dengan GitHub Actions, validasi dan otomatisasi rilis dijalankan secara berulang dengan aturan yang sama untuk seluruh tim.

Gambaran arsitektur alur rilis

Alur yang sederhana dan mudah dirawat biasanya cukup seperti ini:

  1. Developer membuat branch fitur dari main.
  2. Perubahan kode ditambah file changeset jika perubahan tersebut perlu dirilis.
  3. Pull request ke main menjalankan lint, test, dan build.
  4. Setelah merge ke main, workflow release membuat atau memperbarui release PR.
  5. Saat release PR di-merge, workflow yang sama dapat melakukan publish dan membuat git tag/release note sesuai kebutuhan.

Model ini sengaja sederhana. Anda tidak perlu branch develop, staging, atau release/* jika kebutuhan tim belum menuntut itu. Untuk banyak tim kecil hingga menengah, satu branch utama dengan PR review dan CI yang ketat sudah cukup stabil.

Struktur branch yang disarankan

  • main: selalu siap dirilis, semua perubahan masuk lewat pull request.
  • feature/* atau fix/*: branch kerja developer.
  • changeset-release/main atau nama serupa: biasanya dikelola otomatis oleh action saat membuat release PR.

Catatan: Jika tim Anda sering melakukan hotfix, tetap gunakan pola yang sama: buat branch fix dari main, sertakan changeset, lalu merge lewat PR biasa. Hindari bypass langsung ke branch utama.

Menyiapkan Changesets di proyek Nuxt.js

Changesets bekerja baik untuk satu paket maupun monorepo. Pada proyek Nuxt.js standar, penggunaan paling umum adalah untuk mengelola versi aplikasi atau library internal yang dipublikasikan.

Instalasi awal

npm install -D @changesets/cli

Inisialisasi konfigurasi:

npx changeset init

Perintah ini akan membuat folder .changeset dan file konfigurasi dasar. Struktur sederhananya biasanya seperti ini:

project-root/
├─ .changeset/
│  ├─ config.json
│  └─ README.md
├─ .github/
│  └─ workflows/
├─ app.vue
├─ nuxt.config.ts
└─ package.json

Konfigurasi Changesets

Contoh konfigurasi yang aman untuk sebagian besar kebutuhan:

{
  "$schema": "https://unpkg.com/@changesets/config/schema.json",
  "changelog": "@changesets/cli/changelog",
  "commit": false,
  "fixed": [],
  "linked": [],
  "access": "restricted",
  "baseBranch": "main",
  "updateInternalDependencies": "patch",
  "ignore": []
}

Beberapa poin penting:

  • baseBranch harus sesuai dengan branch utama tim Anda.
  • commit: false berarti changeset tidak otomatis membuat commit lokal. Ini biasanya lebih aman agar developer tetap sadar terhadap perubahan yang dikomit.
  • access relevan jika Anda mem-publish paket ke registry. Untuk paket publik, nilainya sering perlu disesuaikan.

Jika Anda tidak yakin dengan nilai tertentu, jangan terlalu banyak mengubah konfigurasi default. Perubahan yang tidak perlu justru membuat alur rilis lebih sulit dipahami tim.

Membuat changeset untuk setiap perubahan yang dirilis

Saat sebuah PR mengubah perilaku yang akan dirilis, buat changeset:

npx changeset

CLI akan meminta Anda memilih paket yang terpengaruh, tipe versi, dan ringkasan perubahan. Untuk satu paket, hasilnya kurang lebih seperti ini:

---
"my-nuxt-app": minor
---

Menambahkan dukungan cache pada fetch data halaman produk.

Pemilihan level semver:

  • patch: bug fix, refactor internal tanpa perubahan API publik, perbaikan kecil.
  • minor: fitur baru yang kompatibel ke belakang.
  • major: perubahan yang memutus kompatibilitas.

Kesalahan umum adalah menandai semua perubahan sebagai patch. Untuk proyek Nuxt.js, perubahan pada API modul internal, props komponen bersama, struktur payload yang dikonsumsi banyak halaman, atau perilaku plugin global bisa layak dianggap minor atau bahkan major.

Menambahkan script yang konsisten di package.json

Supaya CI mudah dirawat, definisikan script yang eksplisit. Contoh minimal:

{
  "scripts": {
    "dev": "nuxt dev",
    "build": "nuxt build",
    "test": "vitest run",
    "lint": "eslint .",
    "changeset": "changeset",
    "version-packages": "changeset version",
    "release": "changeset publish"
  }
}

Intinya bukan nama script-nya, tetapi konsistensinya. Workflow CI sebaiknya memanggil script dari package.json, bukan menaruh logika command langsung secara acak di banyak file workflow. Ini memudahkan debugging saat tim mengganti test runner, package manager, atau struktur proyek.

Workflow CI untuk pull request: lint, test, build, dan validasi changeset

Pull request adalah tempat terbaik untuk menghentikan masalah sebelum masuk ke main. Untuk proyek Nuxt.js, validasi yang masuk akal adalah:

  • install dependency secara deterministik,
  • lint,
  • test unit atau integration yang tersedia,
  • build Nuxt untuk menangkap error konfigurasi dan import,
  • opsional: cek bahwa PR memiliki changeset jika memang ada perubahan yang harus dirilis.

Contoh workflow GitHub Actions untuk PR:

name: ci

on:
  pull_request:
    branches:
      - main

concurrency:
  group: ci-${{ github.event.pull_request.number }}
  cancel-in-progress: true

jobs:
  validate:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm

      - name: Install dependencies
        run: npm ci

      - name: Lint
        run: npm run lint

      - name: Test
        run: npm run test

      - name: Build
        run: npm run build

      - name: Check changeset status
        run: npx changeset status --output=/tmp/changeset-status.json

Kenapa langkah build penting untuk Nuxt.js? Karena banyak masalah baru terlihat saat bundling atau saat Nuxt membaca konfigurasi runtime, alias, plugin, atau import dinamis. Lulus test belum tentu berarti aplikasi bisa dibangun dengan benar.

Perlukah memaksa setiap PR memiliki changeset?

Tidak selalu. Dokumentasi internal, perubahan CI, atau refactor tanpa dampak rilis bisa tidak memerlukan changeset. Ada dua pendekatan:

  • Ketat: semua PR harus punya changeset kecuali diberi label pengecualian.
  • Fleksibel: changeset disarankan, reviewer yang memastikan apakah perubahan layak dirilis.

Untuk tim kecil hingga menengah, pendekatan fleksibel dengan checklist review sering lebih realistis dibanding validasi yang terlalu kaku.

Workflow release di main branch dengan release PR otomatis

Setelah perubahan masuk ke main, Anda ingin workflow yang:

  • mengumpulkan semua changeset yang belum dirilis,
  • menaikkan versi paket secara otomatis,
  • menghasilkan changelog,
  • membuat atau memperbarui release PR,
  • opsional: publish saat release PR sudah di-merge.

Action yang umum dipakai untuk ini adalah changesets/action. Contoh workflow dasarnya:

name: release

on:
  push:
    branches:
      - main

concurrency:
  group: release-main
  cancel-in-progress: false

jobs:
  release:
    runs-on: ubuntu-latest
    permissions:
      contents: write
      pull-requests: write
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Setup Node.js
        uses: actions/setup-node@v4
        with:
          node-version: 20
          cache: npm
          registry-url: https://registry.npmjs.org

      - name: Install dependencies
        run: npm ci

      - name: Validate before release
        run: |
          npm run lint
          npm run test
          npm run build

      - name: Create Release PR or Publish
        uses: changesets/action@v1
        with:
          version: npm run version-packages
          publish: npm run release
          title: "chore: release packages"
          commit: "chore: release packages"
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
          NPM_TOKEN: ${{ secrets.NPM_TOKEN }}

Bagaimana workflow ini bekerja:

  • Jika ada changeset yang belum dirilis, action akan membuat atau memperbarui release PR.
  • Setelah release PR di-merge ke main, run berikutnya akan mendeteksi versi sudah siap dan menjalankan publish command.

Ini memberikan titik kontrol yang jelas: tim tetap meninjau hasil bump versi dan changelog sebelum publish benar-benar terjadi.

Mengapa release PR berguna untuk DX tim

  • Semua perubahan versi terlihat jelas di satu PR.
  • Changelog bisa direview sebelum dipublikasikan.
  • Publish tidak terjadi dari branch fitur atau PR biasa.
  • Tim punya jejak audit yang lebih baik dibanding sekadar tagging manual dari laptop seseorang.

Strategi token dan secret yang aman

Workflow release hampir selalu membutuhkan token. Prinsip utamanya: beri hak akses sekecil mungkin dan pisahkan token berdasarkan kebutuhan.

Secret yang umum diperlukan

  • GITHUB_TOKEN: disediakan GitHub Actions untuk membuat commit, PR, atau release di repository yang sama.
  • NPM_TOKEN: hanya jika Anda benar-benar mem-publish paket ke npm atau registry kompatibel.

Praktik aman yang disarankan

  • Gunakan secret repository atau environment, jangan hardcode token di workflow.
  • Batasi permission job dengan blok permissions, jangan memakai akses default yang terlalu luas.
  • Gunakan token khusus otomasi, bukan token pribadi developer utama jika bisa dihindari.
  • Jika registry mendukung, pertimbangkan mekanisme publish yang lebih aman seperti token granular atau trusted publishing. Implementasinya bergantung pada registry yang dipakai.

Catatan: Jangan mengekspos token lewat log. Hindari command yang mencetak isi environment variable, dan hati-hati saat menambahkan mode debug di workflow release.

Mencegah rilis ganda dan konflik publish

Masalah rilis ganda biasanya muncul saat dua workflow release berjalan hampir bersamaan, atau saat publish dipicu ulang dari commit yang sama. Ada beberapa lapisan pencegahan yang sebaiknya dipakai bersama.

1. Gunakan concurrency di workflow release

Pada contoh sebelumnya, bagian berikut penting:

concurrency:
  group: release-main
  cancel-in-progress: false

Ini membantu memastikan hanya satu job release untuk branch utama yang berjalan pada saat yang sama. Untuk release, cancel-in-progress: false sering lebih aman agar job yang sudah mulai tidak dihentikan di tengah proses publish.

2. Publish hanya dari main branch

Jangan pernah menjalankan publish pada event pull_request. Publish harus dibatasi ke push pada branch utama, sehingga tidak ada risiko paket terbit dari branch sementara atau fork.

3. Pastikan release job tidak dipicu dari banyak workflow berbeda

Kesalahan umum adalah memiliki satu workflow untuk membuat release PR dan workflow lain yang juga mencoba publish dengan logika terpisah. Jika keduanya mengonsumsi changeset yang sama, konflik mudah terjadi. Untuk tim kecil, satu workflow release yang jelas biasanya lebih aman daripada banyak workflow yang tumpang tindih.

4. Lindungi main dengan required checks

Jika branch protection mengharuskan lint/test/build lulus sebelum merge, kemungkinan release PR yang buruk masuk ke main menjadi lebih kecil. Ini tidak langsung mencegah rilis ganda, tetapi mencegah rilis yang tidak valid.

5. Hindari publish manual dari laptop kecuali untuk recovery

Begitu tim memakai alur CI, publish manual sebaiknya menjadi pengecualian untuk insiden tertentu. Jika publish manual tetap sering dilakukan, status versi dan tag akan mudah menyimpang dari histori otomatis.

Langkah implementasi bertahap

Agar adopsi tidak mengganggu pekerjaan tim, lakukan secara bertahap.

Tahap 1: rapikan script proyek

  1. Pastikan npm run lint, npm run test, dan npm run build benar-benar stabil di lokal dan CI.
  2. Jika build Nuxt kadang gagal karena dependensi lingkungan, selesaikan dulu akar masalahnya sebelum menambah alur release otomatis.

Tahap 2: inisialisasi Changesets

  1. Install @changesets/cli.
  2. Jalankan npx changeset init.
  3. Tambahkan panduan internal kapan memakai patch, minor, dan major.

Tahap 3: terapkan workflow CI untuk PR

  1. Tambahkan workflow lint/test/build.
  2. Aktifkan branch protection pada main.
  3. Pastikan semua merge ke main melalui PR.

Tahap 4: aktifkan release PR otomatis

  1. Tambahkan workflow release dengan changesets/action.
  2. Simpan NPM_TOKEN hanya jika memang akan publish ke registry.
  3. Uji dengan PR kecil yang menghasilkan changeset patch.

Tahap 5: dokumentasikan aturan operasional

  1. Siapa yang boleh merge release PR.
  2. Kapan perubahan boleh dikecualikan dari changeset.
  3. Prosedur rollback jika publish gagal.

Contoh aturan review changeset untuk tim

Supaya konsisten, reviewer bisa memakai aturan sederhana berikut:

  • Perubahan bug fix tanpa perubahan kontrak publik: patch.
  • Fitur baru yang tidak merusak integrasi lama: minor.
  • Perubahan pada API, opsi modul, atau perilaku default yang dapat merusak konsumen: major.
  • Perubahan internal murni tanpa dampak rilis: boleh tanpa changeset jika disepakati tim.

Untuk proyek Nuxt.js yang juga menyediakan modul atau komponen yang dipakai lintas aplikasi, reviewer harus lebih sensitif terhadap perubahan public surface area. Misalnya, mengganti nama composable, mengubah shape data dari plugin, atau menghapus opsi konfigurasi adalah kandidat kuat untuk major version.

Trade-off dibanding tagging manual

Kelebihan Changesets + CI

  • Konsistensi: versi dan changelog dibentuk dari metadata yang ditulis dekat dengan perubahan.
  • Auditability: keputusan semver bisa ditinjau di PR.
  • Keamanan proses: publish tidak bergantung pada laptop seseorang.
  • DX tim: developer tidak perlu mengingat detail rilis di akhir sprint.

Kekurangan dan biaya adopsi

  • Ada disiplin tambahan: developer harus membuat changeset saat perlu.
  • Workflow CI/release menambah kompleksitas operasional awal.
  • Jika test dan build belum stabil, otomatisasi justru akan sering gagal dan terasa menghambat.
  • Untuk proyek yang sangat jarang dirilis, tagging manual mungkin terasa lebih sederhana dalam jangka pendek.

Kesimpulannya, jika tim merilis cukup rutin dan lebih dari satu orang terlibat, otomatisasi hampir selalu memberi manfaat bersih. Jika proyek masih sangat kecil dan satu maintainer saja yang mengelola semuanya, tagging manual mungkin masih memadai sementara waktu.

Masalah umum dan tips debugging

Release PR tidak pernah muncul

  • Periksa apakah ada file di .changeset/ yang belum dikonsumsi.
  • Pastikan workflow release berjalan pada push ke main, bukan hanya pada pull request.
  • Verifikasi baseBranch di config sesuai dengan branch utama.
  • Pastikan GITHUB_TOKEN memiliki izin membuat pull request dan commit.

Build lulus di PR tapi publish gagal

  • Periksa apakah NPM_TOKEN tersedia di workflow release.
  • Pastikan publish memang hanya dilakukan dari branch yang benar.
  • Lihat apakah ada konflik versi, paket sudah pernah dipublish, atau tag sudah ada.

Changeset salah memilih patch/minor/major

  • Perbaiki sebelum merge jika masih di PR.
  • Jika sudah telanjur masuk, buat changeset korektif pada PR berikutnya. Hindari mengubah histori release yang sudah dipublish kecuali benar-benar diperlukan.

Workflow release terpicu berkali-kali

  • Pastikan tidak ada dua workflow release berbeda untuk branch yang sama.
  • Gunakan concurrency dengan group yang konsisten.
  • Cek apakah commit dari bot memicu workflow lain yang tidak dimaksudkan.

Checklist adopsi untuk tim kecil hingga menengah

  • Semua perubahan ke main masuk lewat pull request.
  • Script lint, test, dan build stabil di CI.
  • Changesets sudah diinisialisasi dan dipahami tim.
  • Ada aturan kapan perubahan perlu changeset.
  • Branch protection aktif dengan required checks.
  • Workflow PR dan workflow release dipisah jelas.
  • GITHUB_TOKEN dan NPM_TOKEN dikelola lewat secret, bukan hardcoded.
  • Workflow release memakai concurrency untuk mencegah publish paralel.
  • Publish hanya terjadi dari main.
  • Ada prosedur recovery jika publish gagal di tengah jalan.

Penutup

Untuk proyek Nuxt.js: Release Flow SemVer Otomatis dengan Changesets dan CI bukan sekadar soal mengurangi pekerjaan manual, tetapi tentang membuat proses rilis bisa diprediksi, dapat diaudit, dan aman untuk dijalankan oleh lebih dari satu orang. Dengan branch strategy yang sederhana, changeset per PR, validasi lint/test/build, serta release PR otomatis di GitHub Actions, tim mendapatkan alur yang jelas dari perubahan kode sampai versi baru terbit.

Mulailah dari alur minimum yang stabil: satu branch utama, CI yang tegas, dan release PR otomatis. Setelah itu, barulah tambahkan kebutuhan lain bila memang muncul dari operasi sehari-hari, bukan karena konfigurasi terasa “kurang canggih”.