Seluruh konsep dari 19 episode dirajut menjadi satu pipeline produksi nyata. Kalian akan mengikuti alur dari commit fitur, build multi-arch, deploy staging, gerbang persetujuan manual, hingga canary production dengan alert otomatis, ditutup dengan checklist kesiapan produksi.

Selama 19 episode kita membangun kemampuan satu per satu: rules, Docker, artifact, security, environment, agent Kubernetes, dan progressive delivery. Sekarang saatnya ujian akhir: merangkai semuanya menjadi satu pipeline yang berjalan di dunia nyata. Episode ini memandu alur produksi end-to-end untuk aplikasi my-app — dari commit fitur pertama hingga alert release di Slack.
Alur lengkapnya: commit fitur melewati lint, unit test, SAST, secret detection, dan review app; merge ke main memicu parent-child pipeline untuk build multi-arch dengan Kaniko dan scan Trivy; deploy staging diuji dengan integration serta E2E Cypress; persetujuan manual di protected environment membuka jalan ke production; lalu canary 10 persen, health check, promosi penuh, cleanup review app, dan alert menutup alur.
File utama .gitlab-ci.yml di root repository:
include:
- template: Jobs/SAST.gitlab-ci.yml
- template: Jobs/Secret-Detection.gitlab-ci.yml
stages:
- test
- review
- build
- staging
- approval
- production
- cleanup
workflow:
rules:
- if: $CI_PIPELINE_SOURCE == "merge_request_event"
- if: $CI_COMMIT_BRANCH == "main"
variables:
IMAGE_TAG: $CI_COMMIT_SHABlok include menarik template SAST dan Secret Detection resmi GitLab. workflow mencegah pipeline ganda untuk push dan merge request.
Setiap push ke feature branch menjalankan lapisan kualitas:
lint:
stage: test
image: node:22-alpine
script:
- npm ci
- npm run lint
unit_test:
stage: test
image: node:22-alpine
script:
- npm ci
- npm testTemplate SAST dan Secret Detection menghasilkan job sast serta secret_detection otomatis. Set keduanya memakai allow_failure: false lewat rules tambahan, sehingga kerentanan di kode langsung memblokir merge request.
Setiap merge request mendapat environment sementara:
review_app:
stage: review
image: alpine/helm:latest
variables:
KUBE_CONTEXT: my-group/my-app:prod-agent
KUBE_NAMESPACE: review-$CI_MERGE_REQUEST_IID
script:
- helm upgrade --install review-$CI_MERGE_REQUEST_IID ./chart
--set image.tag=$IMAGE_TAG
environment:
name: review/$CI_MERGE_REQUEST_IID
url: https://review-$CI_MERGE_REQUEST_IID.example.com
on_stop: stop_review_appon_stop menautkan environment sementara dengan job pembersih. Begitu MR di-merge, GitLab memicu stop_review_app untuk menghapus release.
Setelah MR disetujui dan di-merge, job di bawah memicu child pipeline di child/build-ci.yml:
build_images:
stage: build
trigger:
include: child/build-ci.yml
strategy: depend
rules:
- if: $CI_COMMIT_BRANCH == "main"Child pipeline berisi build multi-arch dan scan container:
stages:
- build
- scan
kaniko_build:
stage: build
image: gcr.io/kaniko-project/executor:v1.23.2-debug
script:
- /kaniko/executor
--context $CI_PROJECT_DIR
--dockerfile $CI_PROJECT_DIR/Dockerfile
--destination $CI_REGISTRY_IMAGE:${CI_COMMIT_SHA}
--destination $CI_REGISTRY_IMAGE:latest
trivy_scan:
stage: scan
image: aquasec/trivy:0.58.2
script:
- trivy image --exit-code 1 --severity CRITICAL $CI_REGISTRY_IMAGE:${CI_COMMIT_SHA}strategy: depend membuat parent menunggu child selesai — deploy hanya berjalan jika build dan scan berhasil.
deploy_staging:
stage: staging
image: alpine/helm:latest
variables:
KUBE_CONTEXT: my-group/my-app:prod-agent
KUBE_NAMESPACE: staging
script:
- helm upgrade --install my-app ./chart
--set image.tag=$IMAGE_TAG
environment:
name: staging
url: https://staging.example.com
e2e_test:
stage: staging
image: cypress/included:13.6.0
script:
- npm ci
- npm run test:integration
- npm run test:e2eJob E2E memakai image resmi Cypress yang sudah berisi browser — tidak perlu menginstal apa pun. Integration test dan E2E menguji aplikasi terhadap data nyata setelah deploy staging selesai.
Kepatuhan menuntut persetujuan manusia sebelum produksi:
approve_production:
stage: approval
script:
- echo "Menunggu persetujuan lead security dan release manager"
when: manual
environment:
name: production
rules:
- if: $CI_COMMIT_BRANCH == "main"Environment production diatur sebagai protected environment di Settings, sehingga hanya user dengan peran yang diizinkan yang bisa memicu atau menyetujui. Job ini adalah pintu: tanpa klik manual, job di stage production tidak akan pernah berjalan.
Warning
when: manual tanpa protected environment hanyalah formalitas — siapa pun dengan akses ke project bisa mengklik. Pastikan environment production terdaftar sebagai protected dan hanya maintainer atau release manager yang masuk daftar akses.
Setelah disetujui, release mengalir dalam dua langkah:
deploy_canary:
stage: production
image: alpine/helm:latest
variables:
KUBE_CONTEXT: my-group/my-app:prod-agent
KUBE_NAMESPACE: production
script:
- helm upgrade --install my-app ./chart
--set canary.weight=10
--set image.tag=$IMAGE_TAG
environment:
name: production/canary
url: https://app.example.com
promote_production:
stage: production
image: alpine/helm:latest
variables:
KUBE_CONTEXT: my-group/my-app:prod-agent
KUBE_NAMESPACE: production
script:
- ./scripts/healthcheck.sh
- helm upgrade --install my-app ./chart
--set canary.weight=100
--set image.tag=$IMAGE_TAG
environment:
name: production
url: https://app.example.comScript healthcheck.sh mengecek metrik Prometheus (persis pola episode 17) dan melakukan rollback otomatis jika error rate melonjak. Canary 10 persen terbukti sehat, baru trafik penuh dilepas.
Pipeline ditutup dengan dua job terakhir:
stop_review_app:
stage: cleanup
image: alpine/helm:latest
variables:
KUBE_CONTEXT: my-group/my-app:prod-agent
script:
- helm uninstall review-$CI_MERGE_REQUEST_IID
environment:
name: review/$CI_MERGE_REQUEST_IID
action: stop
notify_release:
stage: cleanup
image: alpine:latest
script:
- curl -s -X POST -H 'Content-type: application/json'
--data "{\"text\":\"Release ${CI_COMMIT_SHA} sukses ke production\"}"
https://hooks.slack.com/services/T000/B000/XXXXXXXX
rules:
- if: $CI_COMMIT_BRANCH == "main"
when: alwaysURL webhook Slack bisa diganti dengan endpoint Telegram bot untuk notifikasi yang sama. Dengan when: always, alert tetap terkirim meskipun ada job sebelumnya yang gagal — tim selalu tahu kondisi release.
Sebelum menyalakan pipeline semacam ini, pastikan poin berikut:
workflow: rules mencegah pipeline ganda pada push dan merge request.Pipeline produksi yang utuh bukan kumpulan job, melainkan sistem kepercayaan berlapis: kualitas diuji, keamanan diperiksa, manusia mengawasi, dan mesin siap memundurkan kesalahan.
Dengan ini seri Belajar GitLab CI/CD selesai — kalian telah membangun fondasi lengkap dari konsep dasar hingga pipeline production-grade. Terus berlatih di project nyata, dan jadikan pipeline ini titik awal arsitektur kalian sendiri. Sampai jumpa di seri berikutnya!