Release yang otomatis belum lengkap bila deployment masih manual. Di episode ini kita menyelaraskan semantic-release dengan GitOps: tag versi memicu sinkronisasi ArgoCD atau Flux, dan environment staging naik ke produksi lewat branch. Tag versi menjadi satu-satunya sumber kebenaran.

Di episode 18 kita memantau rilis: tag versi, dashboard release, dan validasi pasca-rilis. Tapi ada satu mata rantai yang sering terputus: versi sudah terbit otomatis, sementara deployment ke cluster masih dikerjakan manual oleh manusia. Di sinilah GitOps masuk. Prinsipnya sederhana tapi kuat — Git adalah satu-satunya sumber kebenaran, dan perubahan yang masuk ke Git otomatis disinkronkan ke environment oleh operator seperti ArgoCD atau Flux.
Di episode ini kita membahas:
GitOps, pola yang dipopulerkan Weaveworks dan diadopsi ArgoCD maupun Flux, berdiri di atas tiga prinsip inti:
Semantic-release adalah pasangan alami GitOps. Release automation menentukan versi, GitOps menentukan ke mana versi itu berjalan. Keduanya bekerja dari sumber yang sama: Git.
Alur lengkapnya menjadi satu garis lurus tanpa intervensi manusia:
staging.v1.4.0-rc.1 di branch staging.main.v1.4.0, lalu deployment ke produksi berjalan.Kuncinya satu: versi yang dirilis semantic-release harus identik dengan versi image yang di-deploy. Jangan biarkan deploy mengambil versi sendiri yang berbeda dari tag rilis. Image ditandai persis seperti tag versi:
docker build -t ghcr.io/acme/api:"${RELEASE_VERSION}" .
docker push ghcr.io/acme/api:"${RELEASE_VERSION}"Variabel RELEASE_VERSION diambil langsung dari output semantic-release, bukan ditebak. Dengan begitu kalian selalu bisa menelusuri "versi X berjalan di cluster" kembali ke commit dan changelog yang tepat.
Model yang paling mudah dipahami: satu branch untuk satu environment.
| Branch | Sifat | Contoh versi | Environment |
|---|---|---|---|
staging | prerelease | 1.4.0-rc.1 | Staging |
main | stable | 1.4.0 | Production |
Promotion bukan berarti menyalin artifact, melainkan mempromosikan versi yang sudah terverifikasi. Kode di staging sudah diuji, sehingga merge staging ke main hanya mewarisi versi yang sudah dikenal baik. semantic-release mengurus kenaikan versinya:
fix baru di staging → 1.4.0-rc.2.main → 1.4.0 stabil tanpa suffix.feat berikutnya di staging → 1.5.0-rc.1.Pola paling populer untuk ArgoCD: aplikasi target diatur lewat sebuah repository manifest (misalnya acme/deploy-configs) yang berisi kustomize atau helm chart. Workflow release menulis versi baru ke manifest itu, lalu ArgoCD menyinkronkannya ke cluster.
apiVersion: argoproj.io/v1alpha1
kind: Application
metadata:
name: api
namespace: argocd
spec:
project: default
destination:
namespace: production
server: https://kubernetes.default.svc
source:
repoURL: https://github.com/acme/deploy-configs
targetRevision: production
path: apps/api
syncPolicy:
automated:
prune: true
selfHeal: trueWorkflow release mengganti image tag di manifest lalu push ke repository tersebut:
#!/usr/bin/env bash
set -euo pipefail
VERSION="${1:?tag versi wajib diisi}"
MANIFEST_REPO="git@github.com:acme/deploy-configs.git"
git clone --depth 1 --branch production "$MANIFEST_REPO" /tmp/deploy
cd /tmp/deploy
sed -i "s|image: ghcr.io/acme/api:.*|image: ghcr.io/acme/api:${VERSION}|" apps/api/deploy.yaml
git add apps/api/deploy.yaml
git commit -m "chore: promote api ${VERSION} ke production"
git pushKelebihan pola ini: setiap perubahan deployment adalah sebuah commit yang bisa direview dan di-revert. Rollback tinggal git revert v1.3.0 ke versi sebelumnya — dan ArgoCD otomatis mengembalikan cluster ke kondisi itu.
Pola kedua tidak membutuhkan workflow tambahan sama sekali. ArgoCD Image Updater atau Flux ImagePolicy memantau registry container, menemukan tag versi baru yang memenuhi aturan semver, lalu memperbarui manifest secara otomatis.
apiVersion: image.toolkit.fluxcd.io/v1beta2
kind: ImagePolicy
metadata:
name: api
spec:
imageRepositoryRef:
name: api
filterTags:
pattern: '^v(?P<semver>\d+\.\d+\.\d+)$'
policy:
semver:
range: '>=1.0.0'Policy di atas hanya mengambil tag versi stabil tanpa suffix rc, sehingga image updater tidak akan pernah men-deploy release candidate ke produksi. Kalian bisa memverifikasi kebijakan yang aktif dengan flux get imagepolicy api.
Warning
Pola image updater menyerahkan keputusan "versi mana yang berjalan" kepada operator GitOps. Pastikan filter semver-nya ketat — suffix prerelease mudah terlewat dan berakhir di produksi. Pola manifest repo lebih eksplisit dan lebih mudah diaudit, karena setiap perubahan adalah commit yang punya jejak.
Bagaimana deployment tahu bahwa sebuah release baru saja diterbitkan? Dua trigger yang paling umum:
release — berjalan ketika GitHub Release diterbitkan oleh semantic-release.workflow_run — berjalan ketika workflow release lain selesai dengan sukses.Contoh trigger berbasis event release:
name: Deploy Production
on:
release:
types: [published]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout manifest repo
uses: actions/checkout@v4
with:
repository: acme/deploy-configs
- name: Promote ke production
run: ./promote.sh "${{ github.event.release.tag_name }}"Contoh trigger berbasis workflow lain yang selesai:
name: Deploy Staging
on:
workflow_run:
workflows: ["Release Candidate"]
types: [completed]
branches: [staging]
jobs:
deploy:
runs-on: ubuntu-latest
steps:
- name: Ambil versi dari release terakhir
run: |
VERSION="${{ github.event.workflow_run.head_branch }}"
echo "men-deploy hasil release di branch $VERSION"Tip
Gunakan satu trigger saja. Jika kalian men-trigger deploy dari event release sekaligus dari push tag, release yang sama akan memicu deployment dua kali — membuang menit runner dan berisiko race condition. Jadikan event release sebagai trigger tunggal, karena hanya terjadi sekali per rilis.
Tip
Jadikan tag versi sebagai sumber kebenaran. Tag v1.4.0 bersifat immutable: ia selalu menunjuk ke commit yang sama, sehingga rollback selalu punya titik acuan yang pasti. Jangan mengandalkan label latest yang bergerak — dengan latest, kalian tidak akan pernah tahu versi mana yang benar-benar berjalan di produksi. Periksa dengan git tag -l untuk memastikan hanya tag versi yang terbit.
Di episode ini kita menghubungkan release automation dengan deployment automation:
staging untuk rc, main untuk stable.release atau workflow_run — satu trigger, jangan dua.Release dan deployment kini berada dalam satu alur otomatis. Di episode 20 kita memastikan seluruh tim bisa mengikuti standar ini — lewat dokumentasi, onboarding, dan code review. Sampai jumpa!