Fitur lockfile di Bazel memungkinkan perekaman versi atau dependensi spesifik dari library atau paket software yang diperlukan oleh project. Hal ini dilakukan dengan menyimpan hasil resolusi modul dan evaluasi ekstensi. File kunci mempromosikan build yang dapat direproduksi, sehingga memastikan lingkungan pengembangan yang konsisten. Selain itu, fitur ini meningkatkan efisiensi build dengan memungkinkan Bazel melewati bagian proses penyelesaian yang tidak terpengaruh oleh perubahan dalam dependensi project. Selain itu, file kunci meningkatkan stabilitas dengan mencegah update yang tidak terduga atau perubahan yang merusak di library eksternal, sehingga mengurangi risiko munculnya bug.
Pembuatan Lockfile
File kunci dibuat di root ruang kerja dengan nama
MODULE.bazel.lock
. File ini dibuat atau diperbarui selama proses build,
khususnya setelah penyelesaian modul dan evaluasi ekstensi. Yang penting, file ini hanya mencakup dependensi yang disertakan dalam pemanggilan build saat ini.
Saat perubahan terjadi dalam project yang memengaruhi dependensinya, file kunci akan otomatis diperbarui untuk mencerminkan status baru. Hal ini memastikan bahwa file lock tetap berfokus pada kumpulan dependensi tertentu yang diperlukan untuk build saat ini, sehingga memberikan representasi yang akurat dari dependensi yang di-resolve project.
Penggunaan Lockfile
File lock dapat dikontrol oleh tanda
--lockfile_mode
untuk
menyesuaikan perilaku Bazel saat status project berbeda dari
file lock. Mode yang tersedia adalah:
update
(Default): Gunakan informasi yang ada dalam file kunci untuk melewati download file registri yang diketahui dan untuk menghindari evaluasi ulang ekstensi yang hasilnya masih terbaru. Jika informasi tidak ada, informasi tersebut akan ditambahkan ke file lock. Dalam mode ini, Bazel juga menghindari pembaruan informasi yang dapat berubah, seperti versi yang dibatalkan, untuk dependensi yang belum berubah.refresh
: Sepertiupdate
, tetapi informasi yang dapat diubah selalu diperbarui saat beralih ke mode ini dan kira-kira setiap jam saat berada dalam mode ini.error
: Sepertiupdate
, tetapi jika ada informasi yang tidak ada atau sudah tidak berlaku, Bazel akan gagal dengan error. Mode ini tidak pernah mengubah file kunci atau melakukan permintaan jaringan selama penyelesaian. Ekstensi modul yang menandai dirinya sebagaireproducible
mungkin masih melakukan permintaan jaringan, tetapi diharapkan selalu menghasilkan hasil yang sama.off
: File kunci tidak diperiksa maupun diperbarui.
Manfaat Lockfile
File kunci menawarkan beberapa manfaat dan dapat digunakan dengan berbagai cara:
Build yang dapat direproduksi. Dengan merekam versi atau dependensi tertentu dari library software, file kunci memastikan bahwa build dapat direproduksi di berbagai lingkungan dan dari waktu ke waktu. Developer dapat mengandalkan hasil yang konsisten dan dapat diprediksi saat membangun project mereka.
Resolusi inkremental yang cepat. File kunci memungkinkan Bazel menghindari download file registry yang sudah digunakan dalam build sebelumnya. Hal ini meningkatkan efisiensi build secara signifikan, terutama dalam skenario yang penyelesaiannya dapat memakan waktu.
Stabilitas dan pengurangan risiko. File kunci membantu mempertahankan stabilitas dengan mencegah update yang tidak terduga atau perubahan yang merusak di library eksternal. Dengan mengunci dependensi ke versi tertentu, risiko munculnya bug akibat update yang tidak kompatibel atau belum diuji akan berkurang.
File kunci tersembunyi
Bazel juga mempertahankan file lock lain di
"$(bazel info output_base)"/MODULE.bazel.lock
. Format dan konten
file kunci ini tidak ditentukan secara eksplisit. Fitur ini hanya digunakan sebagai pengoptimalan performa. Meskipun dapat dihapus bersama dengan dasar output melalui
bazel clean --expunge
, kebutuhan untuk melakukannya adalah bug di Bazel itu sendiri atau
ekstensi modul.
Isi Lockfile
File kunci berisi semua informasi yang diperlukan untuk menentukan apakah status project telah berubah. Bagian ini juga mencakup hasil pembuatan proyek dalam status saat ini. File kunci terdiri dari dua bagian utama:
- Hash semua file jarak jauh yang menjadi input untuk penyelesaian modul.
- Untuk setiap ekstensi modul, file lock mencakup input yang memengaruhinya,
yang diwakili oleh
bzlTransitiveDigest
,usagesDigest
, dan kolom lainnya, serta output dari menjalankan ekstensi tersebut, yang disebut sebagaigeneratedRepoSpecs
Berikut adalah contoh yang menunjukkan struktur file kunci, beserta penjelasan untuk setiap bagian:
{
"lockFileVersion": 10,
"registryFileHashes": {
"https://bcr.bazel.build/bazel_registry.json": "8a28e4af...5d5b3497",
"https://bcr.bazel.build/modules/foo/1.0/MODULE.bazel": "7cd0312e...5c96ace2",
"https://bcr.bazel.build/modules/foo/2.0/MODULE.bazel": "70390338... 9fc57589",
"https://bcr.bazel.build/modules/foo/2.0/source.json": "7e3a9adf...170d94ad",
"https://registry.mycorp.com/modules/foo/1.0/MODULE.bazel": "not found",
...
},
"selectedYankedVersions": {
"foo@2.0": "Yanked for demo purposes"
},
"moduleExtensions": {
"//:extension.bzl%lockfile_ext": {
"general": {
"bzlTransitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
"usagesDigest": "aLmqbvowmHkkBPve05yyDNGN7oh7QE9kBADr3QIZTZs=",
...,
"generatedRepoSpecs": {
"hello": {
"bzlFile": "@@//:extension.bzl",
...
}
}
}
},
"//:extension.bzl%lockfile_ext2": {
"os:macos": {
"bzlTransitiveDigest": "oWDzxG/aLnyY6Ubrfy....+Jp6maQvEPxn0pBM=",
"usagesDigest": "aLmqbvowmHkkBPve05y....yDNGN7oh7r3QIZTZs=",
...,
"generatedRepoSpecs": {
"hello": {
"bzlFile": "@@//:extension.bzl",
...
}
}
},
"os:linux": {
"bzlTransitiveDigest": "eWDzxG/aLsyY3Ubrto....+Jp4maQvEPxn0pLK=",
"usagesDigest": "aLmqbvowmHkkBPve05y....yDNGN7oh7r3QIZTZs=",
...,
"generatedRepoSpecs": {
"hello": {
"bzlFile": "@@//:extension.bzl",
...
}
}
}
}
}
}
Hash File Registri
Bagian registryFileHashes
berisi hash semua file dari
registry jarak jauh yang diakses selama penyelesaian modul. Karena algoritma resolusi sepenuhnya deterministik jika diberi input yang sama dan semua input jarak jauh di-hash, hal ini memastikan hasil resolusi yang sepenuhnya dapat direproduksi sekaligus menghindari duplikasi informasi jarak jauh yang berlebihan dalam file lock. Perhatikan bahwa
hal ini juga memerlukan perekaman saat registry tertentu tidak berisi modul
tertentu, tetapi registry dengan prioritas lebih rendah memilikinya (lihat entri "tidak ditemukan" dalam
contoh). Informasi yang pada dasarnya dapat berubah ini dapat diperbarui melalui
bazel mod deps --lockfile_mode=refresh
.
Bazel menggunakan hash dari file lock untuk mencari file registry di cache repositori sebelum mendownloadnya, yang mempercepat resolusi berikutnya.
Versi yang Dibatalkan Pemublikasian yang Dipilih
Bagian selectedYankedVersions
berisi versi modul yang dibatalkan
yang dipilih oleh penyelesaian modul. Karena biasanya akan menghasilkan error saat mencoba mem-build, bagian ini hanya tidak kosong jika versi yang dibatalkan secara eksplisit diizinkan melalui --allow_yanked_versions
atau BZLMOD_ALLOW_YANKED_VERSIONS
.
Kolom ini diperlukan karena, dibandingkan dengan file modul, informasi versi yang dibatalkan
pada dasarnya dapat berubah dan dengan demikian tidak dapat dirujuk oleh hash. Informasi ini dapat diperbarui melalui bazel mod deps --lockfile_mode=refresh
.
Ekstensi Modul
Bagian moduleExtensions
adalah peta yang hanya menyertakan ekstensi yang digunakan
dalam pemanggilan saat ini atau yang sebelumnya dipanggil, sekaligus mengecualikan ekstensi
yang tidak lagi digunakan. Dengan kata lain, jika ekstensi tidak lagi digunakan di seluruh grafik dependensi, ekstensi tersebut akan dihapus dari peta moduleExtensions
.
Jika ekstensi tidak bergantung pada sistem operasi atau jenis arsitektur, bagian ini hanya menampilkan satu entri "umum". Jika tidak, beberapa entri disertakan, yang diberi nama sesuai dengan OS, arsitektur, atau keduanya, dengan masing-masing sesuai dengan hasil evaluasi ekstensi pada spesifikasi tersebut.
Setiap entri dalam peta ekstensi sesuai dengan ekstensi yang digunakan dan diidentifikasi oleh file dan nama yang memuatnya. Nilai yang sesuai untuk setiap entri berisi informasi relevan yang terkait dengan ekstensi tersebut:
bzlTransitiveDigest
adalah ringkasan penerapan ekstensi dan file .bzl yang dimuat secara transitif olehnya.usagesDigest
adalah ringkasan penggunaan ekstensi dalam grafik dependensi, yang mencakup semua tag.- Kolom lain yang tidak ditentukan yang melacak input lain ke ekstensi, seperti konten file atau direktori yang dibacanya atau variabel lingkungan yang digunakannya.
generatedRepoSpecs
mengenkode repositori yang dibuat oleh ekstensi dengan input saat ini.- Kolom
moduleExtensionMetadata
opsional berisi metadata yang disediakan oleh ekstensi seperti apakah repositori tertentu yang dibuatnya harus diimpor melaluiuse_repo
oleh modul root. Informasi ini mendukung perintahbazel mod tidy
.
Ekstensi modul dapat memilih untuk tidak disertakan dalam file lock dengan menetapkan
metadata yang ditampilkan dengan reproducible = True
. Dengan melakukannya, mereka berjanji bahwa mereka akan selalu membuat repositori yang sama jika diberi input yang sama.
Praktik Terbaik
Untuk memaksimalkan manfaat fitur file kunci, pertimbangkan praktik terbaik berikut:
Perbarui file lock secara rutin untuk mencerminkan perubahan pada dependensi atau konfigurasi project. Hal ini memastikan bahwa build berikutnya didasarkan pada set dependensi yang paling baru dan akurat. Untuk mengunci semua ekstensi sekaligus, jalankan
bazel mod deps --lockfile_mode=update
.Sertakan file kunci dalam kontrol versi untuk memfasilitasi kolaborasi dan memastikan semua anggota tim memiliki akses ke file kunci yang sama, sehingga meningkatkan konsistensi lingkungan pengembangan di seluruh project.
Gunakan
bazelisk
untuk menjalankan Bazel, dan sertakan file.bazelversion
dalam kontrol versi yang menentukan versi Bazel yang sesuai dengan file lock. Karena Bazel sendiri merupakan dependensi build Anda, file kunci khusus untuk versi Bazel, dan akan berubah meskipun di antara rilis Bazel yang kompatibel mundur. Menggunakanbazelisk
memastikan bahwa semua developer menggunakan versi Bazel yang cocok dengan file kunci.
Dengan mengikuti praktik terbaik ini, Anda dapat memanfaatkan fitur file kunci di Bazel secara efektif, sehingga menghasilkan alur kerja pengembangan software yang lebih efisien, andal, dan kolaboratif.
Konflik Penggabungan
Format file kunci dirancang untuk meminimalkan konflik penggabungan, tetapi konflik masih dapat terjadi.
Resolusi Otomatis
Bazel menyediakan driver penggabungan git kustom untuk membantu menyelesaikan konflik ini secara otomatis.
Siapkan driver dengan menambahkan baris ini ke file .gitattributes
di root repositori Git Anda:
# A custom merge driver for the Bazel lockfile.
# https://bazel.build/external/lockfile#automatic-resolution
MODULE.bazel.lock merge=bazel-lockfile-merge
Kemudian, setiap developer yang ingin menggunakan driver harus mendaftarkannya sekali dengan mengikuti langkah-langkah berikut:
- Instal jq (1.5 atau yang lebih baru).
- Jalankan perintah berikut:
jq_script=$(curl https://raw.githubusercontent.com/bazelbuild/bazel/master/scripts/bazel-lockfile-merge.jq)
printf '%s\n' "${jq_script}" | less # to optionally inspect the jq script
git config --global merge.bazel-lockfile-merge.name "Merge driver for the Bazel lockfile (MODULE.bazel.lock)"
git config --global merge.bazel-lockfile-merge.driver ">jq -s '&&${jq_script}'
-- %O %A %B %A.jq_tmp mv %A.jq_tmp %A"
Resolusi Manual
Konflik penggabungan sederhana di kolom registryFileHashes
dan selectedYankedVersions
dapat diselesaikan dengan aman dengan menyimpan semua entri dari kedua sisi
konflik.
Jenis konflik penggabungan lainnya tidak boleh diselesaikan secara manual. Sebagai gantinya:
- Memulihkan status sebelumnya dari file kunci
melalui
git reset MODULE.bazel.lock && git checkout MODULE.bazel.lock
. - Selesaikan konflik apa pun dalam file
MODULE.bazel
. - Jalankan
bazel mod deps
untuk memperbarui file lock.