Bazel Lockfile

回報問題 查看原始碼 。 。 。 。 夜間7.3 。 。 7.2 。 。 7.1 。 。 7.0 。 。 6.5

Bazel 的 Lockfile 功能可記錄特定版本的 軟體程式庫或套件的依附元件。這項服務 透過儲存模組解析度和擴充功能的結果 以及成效評估Lockfile 提倡可重現的版本,確保一致性 開發環境此外,生成式 AI 也能提升建構效率 Bazel 能略過解析度程序中未受變更影響的部分 。此外,Lockfile 也透過 防止外部程式庫意外更新或破壞性變更 降低發生錯誤的風險

產生鎖定檔案

這個 Lockfile 會在工作區根目錄下產生,並命名為 MODULE.bazel.lock。會在建構程序中建立或更新 特別是在模組解析和擴充功能評估之後。重要的是 只包含在目前的 建構應用程式

當影響其依附元件的專案發生變更時, Lockfile 會 並自動更新以反映新的狀態。這可確保 Lockfile 仍然專注於目前所需的特定依附元件組合 針對專案的解決狀況提供準確呈現的結果 依附元件

鎖定檔案使用方式

你可以使用旗標控制 Lockfile --lockfile_mode 到 自訂 Bazel 在專案狀態與 鎖定檔案。可用的模式如下:

  • update (預設):將 Lockfile 中顯示的資訊用於 略過已知登錄檔案的下載,並避免重新評估擴充功能 的結果仍為最新如果缺少資訊 加入到 Lockfile 中在這個模式下,Bazel 也會避免重新整理 適用於沒有任何依附元件的可變動資訊,例如易變版本 已變更。
  • refresh:與 update 一樣,但可變動資訊一律會在以下情況下重新整理 在進入此模式時,大約每小時。
  • error:就像 update,但如果有任何資訊缺漏或過時 Bazel 會執行失敗並顯示錯誤。這個模式絕對不會變更鎖定檔案,或 並在解析期間執行網路要求標有 因為 reproducible 本身仍會執行網路要求,但 和預期都會產生相同結果
  • off:未檢查也未更新 Lockfile。

鎖定檔案的優點

Lockfile 提供多項優點,且可多種運用方式:

  • 可重現的版本。擷取特定版本或依附元件 軟體程式庫的安全漏洞,鎖檔可確保版本可重現 在不同環境之間執行不斷變化開發人員可以放心 確保專案建構過程一致且可預測。

  • 快速漸進式解析度。Lockfile 可讓 Bazel 避免 下載先前版本中使用的登錄檔案。 這麼做可大幅提升建構效率,尤其是在 因此相當耗時

  • 穩定性與風險降低:Lockfile 透過 防止外部程式庫意外更新或破壞性變更變更者: 將依附元件鎖定在特定版本,可能會導致發生錯誤的風險 因為不相容或未經測試的更新,也會減少。

Lockfile 內容

Lockfile 包含判斷 專案狀態已變更其中也包括專案建構的結果 維持目前狀態Lockfile 包含兩個主要部分:

  1. 所有屬於模組解析度的遠端檔案,其雜湊值。
  2. 針對每個模組擴充功能,鎖定檔案會包含會影響模組的輸入內容, 由 bzlTransitiveDigestusagesDigest 及其他欄位表示 以及執行該擴充功能的輸出內容 generatedRepoSpecs

以下示範鎖定檔案的結構,並 各部分的說明:

{
  "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",
            ...
          }
        }
      }
    }
  }
}

登錄檔案雜湊

registryFileHashes 區段包含來自 取得模組解析期間存取的遠端註冊資料庫。因為解析度 演算法相同時 輸入內容經過雜湊處理,確保能完整重現問題, 避免 Lockfile 中過多重複的遠端資訊。請注意, 而如果特定的登錄檔不包含 但優先順序較低的登錄檔 (請參閱 範例)。這項可變動的資訊可以透過以下方法更新: bazel mod deps --lockfile_mode=refresh

Bazel 會使用 Lockfile 中的雜湊來查詢 先下載存放區快取 解析度。

已選取的 Yanked 版本

selectedYankedVersions 區段包含模組化版本的模組 是模組解析度挑選出來的。這通常會導致 嘗試建構時,這個部分只有在套用變焦版本的情況下,才不會空白 透過 --allow_yanked_versionsBZLMOD_ALLOW_YANKED_VERSIONS

相較於模組檔案,相較於模組檔案,此為強制性版本資訊 本身可變動,因此無法由雜湊參照。這項資訊 可透過 bazel mod deps --lockfile_mode=refresh 更新。

模組擴充功能

moduleExtensions 部分為僅包含所用擴充功能的地圖 系統在目前的叫用或先前叫用中叫用,同時排除任何擴充功能 不再使用也就是說,未使用擴充功能 從依附元件圖表中移除moduleExtensions

如果擴充功能與作業系統或架構類型無關 這個部分只會顯示一個「一般」項目。否則,如有 應用程式會納入以 OS 和/或架構命名的項目,且每個項目 我們根據這些具體情況評估額外資訊後的結果

擴充功能對應中的每個項目都會對應至使用的擴充功能,且 由包含檔案和名稱識別而成每個指標的對應值 項目包含與該擴充功能相關聯的資訊:

  1. bzlTransitiveDigest 是擴充功能實作的摘要 載入 .bzl 檔案
  2. usagesDigest 依附關係圖,包含所有代碼。
  3. 未指定的其他欄位,用於追蹤擴充功能的其他輸入內容 例如檔案讀取的檔案或目錄 變數。
  4. generatedRepoSpecs 會將由 延伸至目前的輸入內容
  5. 選用的 moduleExtensionMetadata 欄位包含 例如是否應將擴充功能 透過根模組透過 use_repo 匯入。這項資訊是 bazel mod tidy 指令。

透過設定 透過 reproducible = True 傳回中繼資料。這樣一來,他們就會承諾 系統一律會在輸入相同的存放區時,建立相同的存放區。

最佳做法

如果想充分發揮鎖定檔案功能的優點,請參考以下最佳做法 做法:

  • 定期更新 Lockfile,反映專案依附元件的變更,或 此外還會從 0 自動調整資源配置 您完全不必調整資源調度設定這可確保後續建構是以 即時且準確的依附元件組合如何鎖定所有擴充功能 一次執行 bazel mod deps --lockfile_mode=update

  • 在版本管控中納入 Lockfile,促進協作和 確保所有團隊成員都能存取相同的 Lockfile,進而 確保整個專案採用一致的開發環境

  • 使用 bazelisk 執行 Bazel,並加入 版本管控中的 .bazelversion 檔案,指定了 Bazel 版本 對應至鎖定檔案。由於 Bazel 本身是 您的建構作業, Lockfile 只適用於 Bazel 版本 視需要在回溯相容之間變更 Bazel 版本。使用 bazelisk 可確保所有開發人員都採用 與 Lockfile 相符的 Bazel 版本

只要按照下列最佳做法操作,您就能有效利用 Lockfile 提升作業效率、可靠性與協同合作效率 軟體開發工作流程

合併衝突

Lockfile 格式旨在減少合併衝突,但仍可 。

自動解析度

Bazel 提供的 git merge 驅動程式 自動解決這些衝突。

如要設定驅動程式,請將這一行新增至根目錄的 .gitattributes 檔案 下載 Git 存放區

# A custom merge driver for the Bazel lockfile.
# https://bazel.build/external/lockfile#automatic-resolution
MODULE.bazel.lock merge=bazel-lockfile-merge

然後,凡是要使用驅動程式的開發人員,只要在期限前註冊一次 步驟如下:

  1. 安裝 jq (1.5 以上版本)。
  2. 執行下列指令:
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"

手動解決

registryFileHashesselectedYankedVersions 中的簡易合併衝突 但只要保留 衝突。

其他類型的合併衝突則不應手動解決。請改採以下做法:

  1. 還原鎖定檔案先前的狀態 透過 git reset MODULE.bazel.lock && git checkout MODULE.bazel.lock
  2. 解決 MODULE.bazel 檔案中的衝突。
  3. 執行 bazel mod deps 以更新鎖定檔案。