Episode ini membahas cara menguji aplikasi di banyak kombinasi versi bahasa dan database dengan parallel matrix, memecah suite test besar ke banyak runner paralel dengan keyword parallel, serta membaca variabel CI_NODE_INDEX dan CI_NODE_TOTAL untuk membagi pekerjaan.

Di episode 9 kita membuat pipeline mengalir seperti DAG dengan needs:. Sekarang kita serang masalah kecepatan dari sisi lain: berapa banyak pekerjaan yang bisa dijalankan sekaligus. Bayangkan aplikasi yang harus diuji di Node.js 18, 20, dan 22, sekaligus dengan database PostgreSQL dan MySQL. Kalau kalian menyalin definisi job sampai enam kali, itu bukan hanya boros — setiap duplikasi adalah calon sumber bug yang rawan tidak sinkron.
GitLab menyelesaikan masalah ini dengan dua fitur: parallel: matrix: untuk menguji banyak kombinasi konfigurasi dari satu definisi job, dan parallel: N untuk memecah satu pekerjaan besar menjadi N runner otomatis. Keduanya adalah senjata utama tim yang ingin pipeline cepat tanpa menulis ulang config. Mari kita bedah.
Sebelum membahas matrix, mari pahami fondasinya — keyword parallel. Dengan parallel: 5, GitLab menciptakan lima instance dari job yang sama yang berjalan bersamaan, masing-masing dengan nama nama_job 1/5, nama_job 2/5, dan seterusnya:
e2e_tests:
stage: test
image: node:20-alpine
parallel: 5
script:
- npm ci
- npm run test:e2eJika dibiarkan begitu saja, kelima job menjalankan perintah yang sama persis — sia-sia. Nilai parallel baru bermanfaat saat tiap salinan mengerjakan bagian berbeda dari pekerjaan. GitLab menyediakan dua variabel predefined untuk itu:
CI_NODE_INDEX — nomor salinan saat ini, dimulai dari 1.CI_NODE_TOTAL — total jumlah salinan.Dengan keduanya, kalian bisa memecah suite test. Contoh nyata dengan Playwright yang punya flag --shard bawaan:
e2e_tests:
stage: test
image: mcr.microsoft.com/playwright:v1.45
parallel: 4
script:
- npm ci
- npx playwright test --shard=$CI_NODE_INDEX/$CI_NODE_TOTALSetiap salinan menjalankan --shard=1/4, --shard=2/4, dan seterusnya — satu suite besar dibagi rata ke empat runner. Total waktu pipeline turun hingga seperempat. Framework test modern (Jest, Vitest, pytest-xdist, Playwright) hampir semuanya mendukung pembagian berbasis index seperti ini, jadi pola ini sangat portabel.
Tip
Supaya shard seimbang, jangan asal membagi berdasarkan urutan file. Banyak framework menawarkan "shard by test duration" sehingga file yang lambat tidak menumpuk di satu runner. Prinsipnya sama di GitLab maupun tool lain: total waktu ditentukan oleh shard paling lambat, bukan rata-rata.
parallel: matrix: naik satu tingkat: daripada membuat N salinan identik, kalian mendefinisikan matriks kombinasi nilai, dan GitLab membuat satu job untuk setiap kombinasi. Setiap nilai dari key menjadi variabel environment yang bisa dipakai di dalam script:
test_app:
stage: test
image: node:20-alpine
parallel:
matrix:
- NODE_VERSION: ["18", "20", "22"]
DB_ENGINE: ["postgres", "mysql"]
script:
- echo "Menguji Node.js $NODE_VERSION dengan $DB_ENGINE"
- npm test -- --env $DB_ENGINEDari satu definisi job, GitLab menghasilkan enam job (3 versi Node dikali 2 database): kombinasi Node 18 + postgres, Node 18 + mysql, Node 20 + postgres, dan seterusnya. Nilai key — NODE_VERSION dan DB_ENGINE — otomatis menjadi variabel environment di dalam job, sehingga script bisa beradaptasi dengan kombinasi yang sedang berjalan. Di UI GitLab, tiap kombinasi tampil sebagai job terpisah dengan label seperti test_app 2/6, dan kalian bisa melihat status tiap kombinasi secara mandiri.
Matrix paling berguna ketika kombinasi benar-benar dipakai untuk mengubah perilaku job. Contoh: memilih image base sesuai versi yang diuji, atau memilih service database sesuai engine:
test_app:
stage: test
parallel:
matrix:
- NODE_VERSION: ["18", "20"]
DB_ENGINE: ["postgres", "mysql"]
image: node:${NODE_VERSION}-alpine
services:
- name: $DB_ENGINE:16-alpine
alias: db
script:
- npm test -- --db $DB_ENGINEPerhatikan dua pola menarik di sini. Pertama, image: diisi lewat interpolasi variabel NODE_VERSION — kombinasi Node 20 otomatis diuji di container Node 20. Kedua, services: dengan name: $DB_ENGINE:16-alpine memilih service database sesuai kombinasi. Semua ini terjadi tanpa satu pun if — hanya interpolasi nilai matrix.
Warning
Waspadai ledakan kombinasi. Dua array berisi 3 nilai menghasilkan 9 job, dan menambah satu array lagi (misalnya 2 versi OS) menggandakannya menjadi 18. GitLab membatasi jumlah job paralel per pipeline, dan kuota runner kalian juga punya batas. Atur matrix dengan sadar: uji silang penuh cukup untuk CI pada main, sementara pada setiap push biasa cukup subset yang ramping.
Kadang kalian tidak ingin semua kombinasi dijalankan — misalnya kombinasi tertentu tidak didukung aplikasi. GitLab menyediakan include: dan exclude: di dalam matrix untuk menyempurnakan daftar:
test_app:
stage: test
image: node:20-alpine
parallel:
matrix:
- NODE_VERSION: ["18", "20", "22"]
DB_ENGINE: ["postgres", "mysql"]
exclude:
- NODE_VERSION: "22"
DB_ENGINE: "mysql"
script:
- npm test -- --env $DB_ENGINEDengan exclude, kombinasi "Node 22 + mysql" (yang katakanlah memang belum didukung) dibuang dari daftar — total menjadi lima job, bukan enam. include bekerja sebaliknya: menambahkan kombinasi khusus yang tidak dihasilkan produk kartesian, misalnya satu kombinasi dengan flag konfigurasi tambahan. Aturan kecocokannya harus persis: nilai yang sama dengan kombinasi yang benar-benar dihasilkan matrix, jika tidak, exclude akan diabaikan diam-diam.
Matrix dan needs (episode 9) adalah pasangan yang kuat. Job deploy yang butuh semua hasil test bisa menunggu dengan needs yang menyebut semua kombinasi, atau cukup menunggu stage selesai:
deploy_staging:
stage: deploy
needs:
- job: test_app
artifacts: false
script:
- echo "Semua kombinasi matrix lolos, deploy"Karena test_app dengan matrix menghasilkan banyak job, needs: - job: test_app membuat deploy_staging menunggu seluruh kombinasi tersebut selesai. Ini pola gate yang tepat: deploy hanya terjadi setelah Node 18/20/22 dengan postgres dan mysql semuanya lolos — tanpa menulis ulang daftar kombinasi yang panjang.
Pada episode 10 ini kalian telah menguasai paralelisme di GitLab CI:
parallel: N membuat N salinan job yang berjalan bersamaan; dipasangkan dengan CI_NODE_INDEX dan CI_NODE_TOTAL untuk memecah suite test menjadi shard.parallel: matrix: menghasilkan satu job per kombinasi nilai — misalnya NODE_VERSION dikali DB_ENGINE — dan tiap nilai menjadi variabel environment.if.include / exclude menyempurnakan daftar kombinasi, dan kombinasi dengan needs menciptakan gate deploy yang rapi.Dengan matrix dan parallel, satu definisi job kini menghasilkan puluhan pekerjaan yang berjalan bersamaan — pipeline yang sama, waktunya jauh lebih singkat. Mulai episode berikutnya kita masuk ke skala yang lebih besar: memecah pipeline menjadi file-file terpisah. Di episode 11 kita akan membahas modularisasi pipeline dengan include: dan child pipelines — cara mengimpor konfigurasi dari file, project, template, bahkan remote, plus parent-child pipelines yang pas untuk arsitektur monorepo. Sampai jumpa di episode 11!