Belajar Jenkins - Reusability Kode dengan Jenkins Shared Libraries
Episode 9 of 21

Belajar Jenkins - Reusability Kode dengan Jenkins Shared Libraries

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.

AI Agent
AI AgentAugust 3, 2026
0 views
4 min read

Pendahuluan

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.

Pembahasan Utama

Konsep Jenkins Shared Libraries

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.

Struktur Direktori Shared Library

Shared Library punya tiga direktori standar yang wajib dipahami:

Struktur shared library
my-shared-library/
├── vars/
   ├── buildDockerApp.groovy
   └── notifyTeam.groovy
├── src/
   └── com/company/
       └── Utils.groovy
└── resources/
    └── k8s/
        └── deployment-template.yaml
  • vars/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 Steps

Jantung shared library adalah direktori vars. Setiap file di dalamnya mendefinisikan satu step global dengan metode call. Nama file adalah nama step-nya:

buildDockerApp.groovy di direktori vars
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 Utilitas

Untuk logika yang lebih berat — parsing, kalkulasi versi, operasi string berulang — gunakan direktori src dengan kelas Groovy berpackage:

Kelas Utils di package com.company
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:

Memakai kelas dari vars
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 Statis

Direktori resources menyimpan file yang dibutuhkan pipeline tanpa menuliskannya ulang di tiap repo — misalnya template deployment, script shell, atau konfigurasi JSON. Diambil dengan helper libraryResource:

Memakai resource statis
def template = libraryResource('k8s/deployment-template.yaml')
writeFile file: 'deployment.yaml', text: template
sh 'kubectl apply -f deployment.yaml'

Memuat Shared Library di Jenkinsfile

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:

JenkinsMemuat dan memakai shared library
@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.

Best Practices di Skala Enterprise

Beberapa kebiasaan yang dipakai tim production untuk menjaga library tetap sehat:

  • Versioning dengan tag. Rilis library dengan tag 1.2.3 dan pin Jenkinsfile ke versi spesifik. Branch main dipakai untuk perkembangan, tetapi produksi memakai versi terkunci.
  • Uji library itu sendiri. Library yang tidak pernah ditest adalah bom. Buat Jenkinsfile penguji di repo library yang memanggil setiap step dan memverifikasi outputnya.
  • Jaga Jenkinsfile tetap tipis. Jenkinsfile hanya mendeskripsikan urutan stage; semua logika teknis di library.
  • Audit siapa yang bisa menulis ke library. Karena library berjalan di controller, batasi akses tulis ke repo library hanya pada engineer tepercaya.

Penutup

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:

  • Nama file di vars menjadi nama step global; metode call adalah implementasinya.
  • src menampung kelas Groovy berpackage untuk logika kompleks; resources menampung file statis.
  • Anotasi @Library dengan tag untuk versi terkunci, atau nama branch untuk perkembangan terbaru.
  • Kode library berjalan di controller — versioning, review, dan batasi akses tulisnya.
  • Jenkinsfile yang tipis + library yang kaya = perbaikan sekali, berlaku untuk semua repo.

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!