Mengapa Setiap Build Perlu Identitas Unik

Anda baru saja menjalankan build. Sebuah file JAR muncul di direktori output. Atau mungkin arsip ZIP, atau biner yang sudah dikompilasi. Tampilannya sama seperti build lain yang Anda lakukan minggu ini. Anda salin ke server, deploy, dan lanjutkan.

Tiga hari kemudian, seseorang melaporkan bug di production. Anda perlu mencari tahu artifact mana yang sebenarnya berjalan. Anda periksa server, menemukan file bernama app-1.0.0.jar, dan menyadari bahwa Anda tidak tahu apakah ini build dari Selasa atau Kamis. Keduanya diberi label 1.0.0. Keduanya berasal dari repositori yang sama. Tapi ada yang salah, dan Anda tidak bisa melacak masalahnya kembali ke kode sumber.

Inilah saatnya ketika identitas artifact yang hilang menjadi sakit kepala operasional yang nyata.

Masalah dengan Hanya Nomor Versi

Nomor versi adalah bentuk identifikasi paling dasar. Mereka memberi Anda gambaran kasar tentang apa yang Anda hadapi. 1.0.0, 2.3.1, 3.0.0-beta -- label ini membantu manusia memahami progresi dan kompatibilitas.

Tapi nomor versi saja cepat rusak dalam praktik.

Bayangkan Anda membangun versi 1.0.0 hari ini. Besok, Anda menjalankan build yang sama dari kode sumber yang sama. Anda mendapatkan 1.0.0 lagi. Sekarang Anda memiliki dua file berbeda dengan label yang sama. Mana yang ada di production? Mana yang sudah diuji? Jika Anda perlu mereproduksi bug, 1.0.0 mana yang harus Anda gunakan?

Kenyataan yang tidak nyaman adalah bahwa dua build dari kode sumber yang identik dapat menghasilkan artifact yang berbeda. Versi dependensi mungkin berubah di package manager Anda. Build tool itu sendiri mungkin telah diperbarui. Lingkungan build -- patch sistem operasi, versi library, bahkan zona waktu -- dapat memperkenalkan perbedaan halus. Nomor versi sama, artifact berbeda.

Apa yang Membuat Identitas Artifact yang Baik

Identitas artifact yang berguna harus unik, dapat dilacak, dan permanen. Ia harus menjawab tiga pertanyaan:

  • Kode apa yang digunakan?
  • Kapan ini dibangun?
  • Build run mana yang menghasilkannya?

Pendekatan paling umum menggabungkan tiga informasi menjadi satu pengenal.

Build ID

Setiap pipeline run mendapatkan nomor sekuensial. Jenkins menyebutnya nomor build. GitLab CI menyebutnya pipeline ID. GitHub Actions menyebutnya run number. Apa pun namanya, ini adalah integer yang terus meningkat dan unik dalam sebuah proyek. Build 142 selalu berbeda dari Build 143.

Tapi build ID saja tidak memberi tahu Anda kode apa yang dibangun. Anda perlu lebih.

Commit Hash

Setiap commit di Git memiliki SHA hash -- string heksadesimal panjang yang secara unik mengidentifikasi status persis kode sumber pada titik itu. Ketika Anda menggabungkan build ID dengan commit hash, Anda mendapatkan sesuatu yang kuat: "Artifact ini berasal dari build 142, yang menggunakan commit a3f2c9e."

Jika ada yang salah, Anda bisa checkout commit persis itu dan melihat kode yang dikompilasi. Tanpa tebak-tebakan, tanpa "saya pikir ini adalah versi yang kami gunakan."

Timestamp

Beberapa tim menambahkan timestamp ke identitas. Ini membantu ketika Anda perlu tahu persis kapan build terjadi, terutama saat membandingkan artifact di berbagai lingkungan. Tapi timestamp saja tidak unik -- dua build di pipeline yang berbeda bisa mulai pada detik yang sama.

Kombinasi build ID, commit hash, dan timestamp memberi Anda identitas yang kuat dan mudah dibaca manusia. Sesuatu seperti 142-a3f2c9e-20250321T143022. Tidak cantik, tapi tidak ambigu.

Berikut cara Anda dapat membangun identitas itu di pipeline CI:

BUILD_ID="${CI_PIPELINE_ID:-142}"
COMMIT_HASH="${CI_COMMIT_SHA:-a3f2c9e}"
TIMESTAMP=$(date +%Y%m%d%H%M%S)
ARTIFACT_NAME="myapp-${BUILD_ID}-${COMMIT_HASH}-${TIMESTAMP}.jar"

echo "Building ${ARTIFACT_NAME}"
# ... build steps ...
cp target/app.jar "dist/${ARTIFACT_NAME}"

Aturan Artifact Immutable

Setelah artifact menerima identitasnya, identitas itu tidak boleh berubah. Ini adalah prinsip immutability.

Artifact immutable berarti:

  • Anda tidak pernah menimpa artifact yang sudah ada.
  • Anda tidak pernah menggunakan ulang identitas untuk file yang berbeda.
  • Anda tidak pernah memodifikasi artifact setelah dibangun.

Jika Anda perlu membangun ulang, Anda mendapatkan identitas baru. Artifact lama tetap di tempatnya, dengan label aslinya. Ini mungkin tampak boros, tapi ini adalah fondasi ketertelusuran.

Tanpa immutability, penyimpanan artifact Anda menjadi kacau balau dengan file yang ditimpa dan riwayat yang hilang. Anda tidak bisa dengan percaya diri mengatakan "ini adalah artifact yang diuji di staging" karena seseorang mungkin telah menggantinya dengan versi yang lebih baru dengan nama yang sama.

Dengan immutability, Anda dapat melacak setiap artifact melalui siklus hidupnya. Anda tahu persis artifact mana yang masuk ke staging, mana yang masuk ke production, dan mana yang masih menunggu pengujian. Anda dapat membandingkan artifact di berbagai lingkungan dan memastikan mereka identik.

Di Mana Artifact Disimpan?

Identitas saja tidak cukup. Anda juga perlu tempat untuk menyimpan artifact agar tetap ada di luar mesin build.

Jika artifact Anda berada di folder di server CI atau laptop Anda, mereka akan hilang ketika disk dibersihkan, mesin diganti, atau Anda kehabisan ruang. Anda memerlukan sistem penyimpanan terpusat yang dapat diakses oleh semua orang yang membutuhkannya -- pengembang, penguji, tim operasi, dan pipeline deployment.

Penyimpanan ini disebut registry. Bisa berupa file server sederhana, repositori artifact khusus seperti Nexus atau Artifactory, atau solusi cloud-native seperti container registry untuk image Docker. Yang penting adalah ini menjadi sumber kebenaran tunggal untuk semua artifact yang dibangun.

Ketika Anda menggabungkan identitas unik dan immutable dengan registry yang andal, Anda menciptakan rantai kepemilikan untuk setiap perangkat lunak yang Anda hasilkan. Anda dapat melacak setiap instance yang berjalan kembali ke build persisnya, kode sumbernya, dan kondisi di mana ia dibuat.

Daftar Periksa Praktis

  • Setiap build menghasilkan pengenal unik yang menggabungkan build ID, commit hash, dan timestamp.
  • Artifact tidak pernah ditimpa atau diganti dengan identitas yang sama.
  • Penyimpanan artifact terpusat dan dapat diakses oleh semua tim yang membutuhkannya.
  • Anda dapat melacak artifact yang di-deploy kembali ke commit kode sumber yang persis.
  • Proses deployment Anda mencatat identitas artifact mana yang berjalan di setiap lingkungan.

Kesimpulan

Build tanpa identitas unik adalah liabilitas. Anda tidak bisa men-debug masalah production secara efektif, Anda tidak bisa memverifikasi apa yang berjalan di mana, dan Anda tidak bisa mempercayai proses deployment Anda. Kombinasi build ID, commit hash, dan timestamp memberi Anda cara sederhana dan andal untuk mengidentifikasi setiap artifact yang Anda hasilkan. Buatlah immutable, simpan di registry, dan Anda tidak perlu lagi menebak-nebak versi perangkat lunak mana yang sebenarnya berjalan.