Di skala enterprise, copy-paste Jenkinsfile ke puluhan repository adalah bom waktu: perbaikan satu bug harus diulang di mana-mana dan drift konfigurasi tidak terhindarkan. Episode ini membedah konsep Jenkins Shared Libraries, struktur direktori vars, src, dan resources, serta cara memuat dan menggunakannya dari Jenkinsfile.

Di episode 8 sebelumnya kita membangun pipeline Docker yang lengkap dan aman. Sekarang bayangkan perusahaan kalian punya bukan satu, tapi tiga puluh repository aplikasi — masing-masing dengan Jenkinsfile yang mirip: build image Docker, push ke registry, jalankan test, kirim notifikasi. Apa yang terjadi ketika pola-pola itu di-copy-paste ke setiap repo?
Pertama, semua duplikasi itu menjadi hidup. Bug di pola build harus diperbaiki 30 kali. Kedua, drift: setelah beberapa bulan, repo A punya penambahan security scan, repo B tidak; repo C sudah update ke cara baru, sisanya masih cara lama. Ketiga, review sulit: mana yang benar? Yang paling berbahaya, perbaikan keamanan yang telat sampai di satu repo berarti satu repo masih rentan.
Analoginya seperti mengelola invoice: kalau setiap kantor membuat format invoice sendiri dan aturan pajaknya di-hardcode di tiap spreadsheet, perubahan regulasi pajak berarti memeriksa ulang puluhan file. Solusinya adalah satu template terpusat yang dipakai semua. Untuk Jenkins, jawabannya adalah Jenkins Shared Libraries: satu repository Git yang menjadi sumber tunggal logika pipeline, dan setiap Jenkinsfile tinggal memanggilnya.
Shared Library adalah repositori Groovy terpisah yang di-load Jenkins untuk menyediakan function, class, dan resource statis yang bisa dipakai semua pipeline. Jenkinsfile di tiap repo aplikasi menjadi sangat tipis — tinggal orkestrasi stage, sementara detail teknis (cara build, cara push, cara notify) hidup di satu tempat.
Efeknya mirip pustaka standar bahasa pemrograman: kalian tidak menulis ulang fungsi sorting di setiap program, kalian memakai yang sudah ada. Perubahan satu kali di pustaka langsung berlaku untuk semua pengguna.
Shared Library punya tiga direktori standar yang wajib dipahami:
my-shared-library/
├── vars/
│ ├── buildDockerApp.groovy
│ └── notifyTeam.groovy
├── src/
│ └── com/company/
│ └── Utils.groovy
└── resources/
└── k8s/
└── deployment-template.yamlvars/ — global functions/steps. Setiap file Groovy di sini menjadi step kustom yang bisa dipanggil langsung dari Jenkinsfile. File buildDockerApp.groovy menghasilkan step buildDockerApp.src/ — kelas Groovy standar dan kode utilitas. Mengikuti struktur package seperti com.company.Utils, dipakai untuk logika yang lebih kompleks.resources/ — file statis: JSON, shell scripts, template. Diambil lewat helper libraryResource dan bisa ditulis ke workspace.vars/: Custom Global StepsJantung shared library adalah direktori vars. Setiap file di dalamnya mendefinisikan satu step global dengan metode call. Nama file adalah nama step-nya:
def call(String imageName, String tag = 'latest') {
sh "docker build -t ${imageName}:${tag} ."
sh "docker tag ${imageName}:${tag} ${imageName}:latest"
echo "Image ${imageName}:${tag} berhasil dibangun"
}Metode call di atas menerima nama image dan tag dengan default latest. Begitu library di-load, seluruh pipeline bisa memanggilnya seperti step bawaan Jenkins: buildDockerApp 'ghcr.io/company/api-service' — perhatikan ini persis seperti memanggil step sh atau echo, karena Jenkins memperlakukan file di vars sebagai step global.
Tip
Rule of thumb: semakin banyak logika di vars dan semakin sedikit di Jenkinsfile, semakin mudah library dipertahankan. Jenkinsfile aplikasi seharusnya hampir tidak berisi sh — cukup panggilan ke step kustom dan orkestrasi stage.
src/: Kelas Groovy dan UtilitasUntuk logika yang lebih berat — parsing, kalkulasi versi, operasi string berulang — gunakan direktori src dengan kelas Groovy berpackage:
package com.company
class Utils {
static String shortSha(String fullSha) {
return fullSha.take(8)
}
}Kelas ini bisa dipakai dari dalam step di vars untuk memanfaatkan logika yang sama di banyak tempat:
def call(String imageName, String fullSha) {
def utils = new com.company.Utils()
def tag = utils.shortSha(fullSha)
sh "docker build -t ${imageName}:${tag} ."
}resources/: File StatisDirektori resources menyimpan file yang dibutuhkan pipeline tanpa menuliskannya ulang di tiap repo — misalnya template deployment, script shell, atau konfigurasi JSON. Diambil dengan helper libraryResource:
def template = libraryResource('k8s/deployment-template.yaml')
writeFile file: 'deployment.yaml', text: template
sh 'kubectl apply -f deployment.yaml'Library didaftarkan di Jenkins lewat Manage Jenkins → System → Global Pipeline Libraries dengan URL repo, credentials bila privat, dan versi default. Setelah terdaftar, Jenkinsfile memuatnya dengan anotasi @Library di baris teratas:
@Library('my-shared-library@main') _
pipeline {
agent any
stages {
stage('Build') {
steps {
buildDockerApp 'ghcr.io/company/api-service'
}
}
stage('Notify') {
steps {
notifyTeam 'sukses'
}
}
}
}Sintaks @Library('my-shared-library@main') _ di atas berarti: muat library bernama my-shared-library pada versi branch main. Underscore di akhir memuat seluruh step global di vars ke scope top-level sehingga bisa dipanggil langsung. Versi tidak harus branch — bisa tag: @Library('my-shared-library@1.2.3') _ untuk versi yang terkunci dan immutable, atau @Library('my-shared-library@main') _ untuk selalu mengikuti perkembangan terbaru.
Warning
Shared library adalah kode Groovy yang dijalankan di controller. Kode di dalamnya tidak sandboxed seperti Jenkinsfile biasa — butuh persetujuan admin (Script Approval) untuk fungsi tertentu. Perlakukan library seperti code production: versi berbasis semantic versioning, tinjau lewat pull request, dan jangan pernah menaruh rahasia atau hardcoded credentials di dalamnya.
Beberapa kebiasaan yang dipakai tim production untuk menjaga library tetap sehat:
1.2.3 dan pin Jenkinsfile ke versi spesifik. Branch main dipakai untuk perkembangan, tetapi produksi memakai versi terkunci.Pada episode 9 ini kita memecahkan masalah duplikasi kode di skala enterprise: copy-paste Jenkinsfile ke puluhan repository yang berbahaya karena perbaikan harus diulang di mana-mana dan drift tak terhindarkan. Solusinya adalah Jenkins Shared Libraries — satu repositori Groovy terpusat berisi vars untuk custom global steps dengan metode call, src untuk kelas dan utilitas Groovy, serta resources untuk file statis yang diambil lewat libraryResource. Library dimuat dengan @Library('my-shared-library@main') _ dan membuat Jenkinsfile tipis serta konsisten di seluruh organisasi.
Inti yang harus kalian bawa:
vars menjadi nama step global; metode call adalah implementasinya.src menampung kelas Groovy berpackage untuk logika kompleks; resources menampung file statis.@Library dengan tag untuk versi terkunci, atau nama branch untuk perkembangan terbaru.Kalian sekarang punya pondasi yang reusable. Tapi semua build menghasilkan output — dan output itu harus dikelola. Di episode 10 berikutnya kita membahas manajemen build artifacts dan workspace: menyimpan hasil build lewat archiveArtifacts, berbagi file antar agent dengan stash dan unstash, serta membersihkan workspace agar disk tidak pernah penuh. Sampai jumpa di episode 10!