Lockfile Bazel

Laporkan masalah Lihat sumber

Fitur lockfile di Bazel memungkinkan perekaman versi atau dependensi tertentu library software atau paket yang diperlukan oleh project. Hal ini dilakukan dengan menyimpan hasil resolusi modul dan evaluasi ekstensi. Lockfile mendukung build yang dapat direproduksi, sehingga memastikan lingkungan pengembangan yang konsisten. Selain itu, atribut ini meningkatkan efisiensi build dengan memungkinkan Bazel melewati bagian proses resolusi yang tidak terpengaruh oleh perubahan dalam dependensi project. Selain itu, lockfile meningkatkan stabilitas dengan mencegah update yang tidak terduga atau perubahan yang dapat menyebabkan gangguan di library eksternal, sehingga mengurangi risiko munculnya bug.

Pembuatan Lockfile

Lockfile dibuat di bawah root ruang kerja dengan nama MODULE.bazel.lock. Library ini dibuat atau diupdate selama proses build, khususnya setelah resolusi modul dan evaluasi ekstensi. Yang penting, modul ini hanya menyertakan dependensi yang disertakan dalam pemanggilan build saat ini.

Saat terjadi perubahan pada project yang memengaruhi dependensinya, lockfile akan otomatis diupdate untuk mencerminkan status baru. Hal ini memastikan bahwa lockfile tetap fokus pada kumpulan dependensi tertentu yang diperlukan untuk build saat ini, sehingga memberikan representasi akurat dari dependensi project yang telah diselesaikan.

Penggunaan Lockfile

Lockfile dapat dikontrol oleh flag --lockfile_mode untuk menyesuaikan perilaku Bazel saat status project berbeda dengan lockfile. Mode yang tersedia adalah:

  • update (Default): Gunakan informasi yang ada di lockfile untuk melewati download file registry yang diketahui dan menghindari evaluasi ulang ekstensi yang hasilnya masih yang terbaru. Jika informasi yang hilang, informasi akan ditambahkan ke {i>lockfile<i}. Dalam mode ini, Bazel juga menghindari memuat ulang informasi yang dapat diubah, seperti versi yang ditautkan, untuk dependensi yang tidak berubah.
  • refresh: Seperti update, tetapi informasi yang dapat diubah selalu diperbarui saat beralih ke mode ini dan kira-kira setiap jam saat dalam mode ini.
  • error: Seperti update, tetapi jika ada informasi yang hilang atau tidak berlaku lagi, Bazel akan gagal dengan error. Mode ini tidak pernah mengubah lockfile atau melakukan permintaan jaringan selama resolusi. Ekstensi modul yang menandainya sebagai reproducible mungkin masih menjalankan permintaan jaringan, tetapi diperkirakan selalu memberikan hasil yang sama.
  • off: Lockfile tidak diperiksa atau diperbarui.

Manfaat Lockfile

Lockfile ini menawarkan beberapa manfaat dan dapat digunakan dengan berbagai cara:

  • Build yang dapat direproduksi. Dengan merekam versi atau dependensi library software tertentu, lockfile 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. Dengan lockfile ini, Bazel dapat menghindari download file registry yang sudah digunakan di build sebelumnya. Hal ini meningkatkan efisiensi build secara signifikan, terutama dalam skenario yang memerlukan waktu lama.

  • Stabilitas dan pengurangan risiko. Lockfile membantu mempertahankan stabilitas dengan mencegah update yang tidak terduga atau perubahan yang dapat menyebabkan gangguan di library eksternal. Dengan mengunci dependensi ke versi tertentu, risiko munculnya bug karena update yang tidak kompatibel atau belum diuji akan berkurang.

Konten Lockfile

Lockfile berisi semua informasi yang diperlukan untuk menentukan apakah status project telah berubah. Hal ini juga mencakup hasil build project dalam status saat ini. Lockfile terdiri dari dua bagian utama:

  1. Hash dari semua file jarak jauh yang merupakan input ke resolusi modul.
  2. Untuk setiap ekstensi modul, lockfile menyertakan input yang memengaruhinya, yang diwakili oleh bzlTransitiveDigest, usagesDigest, dan kolom lainnya, serta output menjalankan ekstensi tersebut, yang disebut sebagai generatedRepoSpecs

Berikut adalah contoh yang menunjukkan struktur lockfile, 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 Registry

Bagian registryFileHashes berisi hash semua file dari registry jarak jauh yang diakses selama resolusi modul. Karena algoritma resolusi sepenuhnya determenistik saat diberi input yang sama dan semua input jarak jauh di-hash, hal ini memastikan hasil resolusi yang dapat direproduksi sepenuhnya sekaligus menghindari duplikasi informasi jarak jauh yang berlebihan dalam lockfile. Perlu diperhatikan bahwa proses ini juga memerlukan pencatatan saat registry tertentu tidak berisi modul tertentu, tetapi registry dengan prioritas lebih rendah memilikinya (lihat entri "tidak ditemukan" dalam contoh). Informasi yang secara inheren dapat diubah ini dapat diperbarui melalui bazel mod deps --lockfile_mode=refresh.

Bazel menggunakan hash dari lockfile untuk mencari file registry di cache repositori sebelum mendownloadnya, sehingga mempercepat resolusi berikutnya.

Versi Yanked yang Dipilih

Bagian selectedYankedVersions berisi versi modul yang ditarik yang dipilih oleh resolusi modul. Karena hal ini biasanya mengakibatkan error saat mencoba membangun, bagian ini hanya tidak kosong ketika versi yang ditarik diizinkan secara eksplisit melalui --allow_yanked_versions atau BZLMOD_ALLOW_YANKED_VERSIONS.

Kolom ini diperlukan karena, dibandingkan dengan file modul, informasi versi yang ditarik secara inheren dapat diubah sehingga tidak dapat direferensikan 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 panggilan saat ini atau yang sebelumnya dipanggil, sekaligus mengecualikan ekstensi apa pun yang tidak lagi digunakan. Dengan kata lain, jika ekstensi tidak digunakan lagi 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 akan disertakan, yang diberi nama berdasarkan OS, arsitektur, atau keduanya, dan setiap entri akan sesuai dengan hasil evaluasi ekstensi berdasarkan spesifikasi tersebut.

Setiap entri dalam peta ekstensi sesuai dengan ekstensi yang digunakan dan diidentifikasi berdasarkan file dan nama penampungnya. Nilai yang sesuai untuk setiap entri berisi informasi relevan yang terkait dengan ekstensi tersebut:

  1. bzlTransitiveDigest adalah ringkasan implementasi ekstensi dan file .bzl yang dimuat secara transitif olehnya.
  2. usagesDigest adalah ringkasan penggunaan ekstensi dalam grafik dependensi yang mencakup semua tag.
  3. Kolom yang tidak ditentukan lebih lanjut yang melacak input lain ke ekstensi, seperti konten file atau direktori yang dibacanya atau variabel lingkungan yang digunakannya.
  4. generatedRepoSpecs mengenkode repositori yang dibuat oleh ekstensi dengan input saat ini.
  5. Kolom moduleExtensionMetadata opsional berisi metadata yang disediakan oleh ekstensi, seperti apakah repositori tertentu yang dibuatnya harus diimpor melalui use_repo oleh modul root. Informasi ini mendukung perintah bazel mod tidy.

Ekstensi modul dapat memilih untuk tidak disertakan dalam lockfile dengan menyetel metadata yang ditampilkan dengan reproducible = True. Dengan begitu, mereka berjanji bahwa mereka akan selalu membuat repositori yang sama saat diberi input yang sama.

Tips

Untuk memaksimalkan manfaat fitur lockfile, pertimbangkan praktik terbaik berikut:

  • Mengupdate lockfile secara rutin untuk mencerminkan perubahan pada dependensi atau konfigurasi project. Hal ini memastikan bahwa build berikutnya didasarkan pada kumpulan dependensi yang terbaru dan akurat. Untuk mengunci semua ekstensi sekaligus, jalankan bazel mod deps --lockfile_mode=update.

  • Sertakan lockfile dalam kontrol versi untuk memfasilitasi kolaborasi dan memastikan semua anggota tim memiliki akses ke lockfile yang sama, sehingga mendukung lingkungan pengembangan yang konsisten di seluruh project.

  • Gunakan bazelisk untuk menjalankan Bazel, dan sertakan file .bazelversion dalam kontrol versi yang menentukan versi Bazel yang sesuai dengan lockfile. Karena Bazel sendiri merupakan dependensi build Anda, lockfile ini dikhususkan untuk versi Bazel, dan akan berubah bahkan antara rilis Bazel yang kompatibel dengan versi lama. Penggunaan bazelisk akan memastikan bahwa semua developer menggunakan versi Bazel yang cocok dengan file kunci.

Dengan mengikuti praktik terbaik ini, Anda dapat memanfaatkan fitur lockfile di Bazel secara efektif, sehingga menghasilkan alur kerja pengembangan software yang lebih efisien, andal, dan kolaboratif.