Pipeline yang besar dan monolitik sulit dipelihara, apalagi ketika banyak tim berbagi satu repository. Episode ini membedah cara memecah pipeline menjadi modul yang bisa dipakai ulang dengan include local, project, template, dan remote, plus menerapkan parent-child serta multi-project pipelines untuk arsitektur monorepo.

Di episode 10 sebelumnya kita membahas bagaimana parallel: matrix dan parallel: 5 memecah pekerjaan menjadi banyak runner paralel sehingga durasi pipeline bisa dipangkas drastis. Sekarang bayangkan dua tahun kemudian: repository mulai dipegang banyak tim, dan file .gitlab-ci.yml di root repository sudah membengkak menjadi ribuan baris dengan job yang saling menyalin konfigurasi. Setiap tim meng-copy-paste blok yang sama, dan satu perubahan kecil pada konfigurasi build berarti mengedit sekaligus memikirkan dampaknya ke puluhan job di seluruh repository.
Situasi ini persis seperti sebuah buku catatan raksasa yang dipakai bersama-sama oleh seluruh kelas: setiap kali satu siswa ingin menulis, siswa lain harus menunggu, dan semua orang harus membaca halaman yang sama hanya untuk menemukan bagian miliknya. Di dunia nyata, tim DevOps tidak bekerja seperti itu. Mereka memecah file besar menjadi modul, menyimpan konfigurasi umum di tempat terpusat, dan mengorkestrasi pipeline kecil-kecil yang bertanggung jawab atas domain masing-masing.
Episode ini membahas dua alat utama GitLab untuk memecahkan masalah tersebut: keyword include untuk reusability kode, dan teknik parent-child pipelines serta multi-project pipelines untuk memecah pipeline besar menjadi sub-pipeline yang independen. Inilah fondasi arsitektur pipeline enterprise yang akan terus kita pakai di episode-episode berikutnya.
.gitlab-ci.yml Monolitik Menjadi MasalahSebelum membahas solusinya, mari pahami dulu akar masalahnya. File pipeline monolitik tidak hanya terasa "panjang" — ia menimbulkan empat masalah konkret di tim nyata:
git merge, dan resolver konflik pipeline adalah salah satu pekerjaan paling tidak menyenangkan.Solusi GitLab untuk masalah-masalah ini adalah keyword include, yang memungkinkan pipeline dibangun dari banyak file YAML — mirip cara bahasa pemrograman modern memecah kode menjadi modul dan fungsi.
include: local: Modul dalam Repository yang Samainclude: local mengimpor file YAML dari repository yang sedang diproses. Ini pola paling dasar untuk memecah .gitlab-ci.yml besar menjadi file-file per domain.
include:
- local: /ci/build.yml
- local: /ci/test.yml
- local: /ci/deploy.yml
stages: [build, test, deploy]build-backend:
stage: build
image: node:20-alpine
script:
- npm ci
- npm run buildPath local selalu dimulai dengan / (relatif ke root repository) atau relatif terhadap file yang meng-include-nya. File yang di-include bisa berisi definisi job, stage, variabel, atau apa pun yang sah di .gitlab-ci.yml.
Tip
Gunakan folder .gitlab/ci/ atau ci/ untuk menyimpan modul-modul ini. Konvensi yang konsisten membuat tim langsung tahu di mana mencari konfigurasi job tertentu tanpa harus membaca isi file utama.
include: project: Reuse Konfigurasi Lintas RepositoryMasalah local adalah ia hanya bekerja di dalam satu repository. Padahal konfigurasi linting, build, atau deploy biasanya identik di banyak proyek. include: project mengimpor file YAML dari repository GitLab lain — dalam organisasi yang sama atau bahkan dari project publik.
include:
- project: "my-org/ci-templates"
ref: v2.4.0
file: /templates/build.yml
- project: "my-org/ci-templates"
ref: v2.4.0
file: /templates/test.ymlPerhatikan pasangan ref dan file: ref memilih branch, tag, atau commit dari project sumber. Mengikat include ke tag (v2.4.0) alih-alih branch main adalah praktik terbaik — beginilah template internal perusahaan dapat di-versioning dengan semantic versioning, sama seperti library software.
include: template: Template Resmi GitLabinclude: template mengimpor template CI resmi yang dikelola tim GitLab. Template ini mencakup pekerjaan keamanan, SAST, dependency scanning, dan berbagai bahasa pemrograman.
include:
- template: Jobs/SAST.gitlab-ci.yml
- template: Security/Container-Scanning.gitlab-ci.ymlTemplate adalah cara tercepat mengadopsi fitur GitLab tanpa menulis apapun. Kita akan membedah template keamanan ini secara mendalam di episode 12.
include: remote: Import dari URL HTTP/Sinclude: remote mengambil file YAML dari URL eksternal. Ini berguna untuk berbagi konfigurasi lintas organisasi, misalnya template publik yang dikelola komunitas.
include:
- remote: "https://example.com/team/pipeline-base.yml"Warning
Include remote adalah pintu masuk yang berbahaya jika tidak hati-hati. Kalian mengeksekusi konfigurasi dari URL yang tidak kalian kontrol. Pastikan URL dikelola organisasi kalian, atau setidaknya pin ke commit hash tertentu, dan jangan pernah meng-include URL yang bisa diubah siapa pun. Untuk penggunaan internal, project + ref jauh lebih aman dan bisa diaudit.
extends: Warisan Konfigurasi Tanpa Salin-TempelSelain include, GitLab menyediakan keyword extends untuk mewarisi konfigurasi dari job lain dalam file yang sama. Ini menggantikan YAML anchors yang sudah deprecated di versi modern.
.base-job:
image: node:20-alpine
variables:
NODE_ENV: production
before_script:
- npm ci
build-app:
extends: .base-job
stage: build
script:
- npm run buildPerhatikan bahwa job yang dimulai dengan titik (.base-job) tidak dijalankan oleh GitLab — ia hanya dijadikan cetakan. extends melakukan merge konfigurasi: nilai yang tidak ditimpa diwarisi, sedangkan nilai yang ditulis di job turunan akan menimpa milik parent. Ini adalah cara paling idiomatis untuk menghindari copy-paste.
Ketika repository membengkak menjadi monorepo — misalnya berisi folder frontend, backend, dan docs — satu pipeline raksasa membuat semua tim terikat pada konfigurasi bersama. Parent-child pipelines memecahnya: pipeline induk (parent) memicu sub-pipeline (child) yang masing-masing memiliki file YAML dan lifecycle sendiri.
stages: [pre, build, deploy]
build-children:
stage: pre
trigger:
include:
- local: /frontend/child-ci.yml
- local: /backend/child-ci.yml
strategy: dependKeyword trigger membuat job bertindak sebagai pemantik pipeline lain, bukan mengeksekusi script. Dengan strategy: depend, parent pipeline menunggu child pipeline selesai sebelum melanjutkan ke stage berikutnya — cocok ketika build monorepo harus selesai sebelum deploy. Setiap child pipeline berjalan di bawah naungan pipeline induknya dan bisa menggunakan predefined variables seperti CI_PROJECT_DIR untuk folder masing-masing.
Berkebalikan dengan child pipeline (masih di repository yang sama), multi-project pipeline memicu pipeline di repository terpisah. Ini adalah tulang punggung pola downstream pipeline: repository A (misalnya shared library) selesai build, lalu memicu test di repository B (aplikasi yang mengonsumsi library tersebut).
trigger-deploy:
stage: deploy
trigger:
project: my-org/api-gateway
branch: main
strategy: dependUntuk memicu pipeline di project lain, GitLab menggunakan CI_JOB_TOKEN dari project pemantik — artinya project target harus memberi izin akses melalui fitur Pipeline trigger pada project settings. Hasil pipeline downstream dapat dipantau langsung dari pipeline upstream di UI GitLab.
| Tujuan | Alat | Contoh |
|---|---|---|
Memecah .gitlab-ci.yml besar dalam satu repo | include: local | /ci/test.yml |
| Share template antar repo dalam organisasi | include: project | repo ci-templates + tag v2.4.0 |
| Mengaktifkan fitur resmi GitLab | include: template | Jobs/SAST.gitlab-ci.yml |
| Import konfigurasi dari luar organisasi | include: remote | URL publik tim |
| Mewarisi konfigurasi antar job | extends | job .base-job |
| Monorepo dengan banyak tim | Parent-child pipelines | trigger: include: |
| Memicu pipeline di repo lain | Multi-project pipelines | trigger: project: |
Important
Kombinasi include dan extends adalah pola inti arsitektur CI/CD modern di GitLab: gunakan include untuk menyusun pipeline dari banyak file, dan extends untuk menurunkan konfigurasi di dalam file tersebut. Keduanya menggantikan YAML anchors dan only/except yang deprecated.
Pada episode ini kita telah membahas cara memecah pipeline monolitik: keempat bentuk include — local, project, template, dan remote — beserta contoh masing-masing; keyword extends untuk mewarisi konfigurasi antar job; parent-child pipelines dengan trigger: include yang cocok untuk monorepo; serta multi-project pipelines dengan trigger: project untuk menghubungkan pipeline lintas repository.
Inti dari episode ini: pipeline bukanlah satu file raksasa, melainkan orkestrasi modul-modul kecil yang independen. Dengan modularisasi, tim bisa bergerak cepat, template bisa di-versioning, dan setiap bagian pipeline bertanggung jawab atas domainnya sendiri.
Di episode 12 selanjutnya kita masuk ke FASE 5: DevSecOps Native GitLab — mengaktifkan SAST, Secret Detection, Dependency Scanning, dan Container Scanning hanya dengan beberapa baris include: template, lalu membaca hasilnya dari Security Center. Sampai jumpa!