ไฟล์ Bazel Lock

วันที่ รายงานปัญหา ดูแหล่งที่มา ตอนกลางคืน · 7.3 · 7.2 · 7.1 · 7.0 · 6.5

ฟีเจอร์ล็อกไฟล์ใน Bazel จะเปิดใช้การบันทึกเวอร์ชันที่เจาะจงหรือ ทรัพยากร Dependency ของไลบรารีซอฟต์แวร์หรือแพ็กเกจที่โปรเจ็กต์ต้องใช้ ทั้งนี้ บรรลุเป้าหมายนี้โดยการจัดเก็บผลลัพธ์ของความละเอียดและการขยายโมดูล การประเมินมูลค่า ไฟล์ล็อกส่งเสริมงานสร้างที่ทำซ้ำได้เพื่อให้แน่ใจว่ามีความสอดคล้องกัน สภาพแวดล้อมในการพัฒนาซอฟต์แวร์ นอกจากนี้ยังช่วยเพิ่มประสิทธิภาพในการสร้าง โดยทำให้ Bazel ข้ามขั้นตอนการแก้ปัญหาที่ไม่ได้รับผลกระทบจากการเปลี่ยนแปลง ในทรัพยากร Dependency ของโปรเจ็กต์ นอกจากนี้ ไฟล์ล็อกยังมีความเสถียรมากขึ้น เพื่อป้องกันการอัปเดตที่ไม่คาดคิดหรือ ส่งผลต่อการเปลี่ยนแปลงในไลบรารีภายนอก จะช่วยลดความเสี่ยงในการเกิดข้อบกพร่อง

การสร้างไฟล์ล็อก

ไฟล์ล็อกสร้างขึ้นภายใต้รูทของพื้นที่ทำงานโดยใช้ชื่อ MODULE.bazel.lock ระบบจะสร้างหรืออัปเดตในระหว่างขั้นตอนการสร้าง โดยเฉพาะหลังการแก้ปัญหาโมดูลและการประเมินส่วนขยาย ที่สำคัญคือ รวมเฉพาะทรัพยากร Dependency ที่รวมอยู่ในการเรียกใช้ปัจจุบันของ งานสร้าง

เมื่อมีการเปลี่ยนแปลงในโปรเจ็กต์ที่ส่งผลต่อทรัพยากร Dependency ไฟล์ Lockfile จะถูก โดยอัตโนมัติเพื่อให้แสดงถึงสถานะใหม่ วิธีนี้ช่วยให้มั่นใจว่าล็อกไฟล์ จะยังคงมุ่งเน้นที่ชุดทรัพยากร Dependency ที่จำเป็น ทำให้เห็นภาพที่ถูกต้องของผลการแก้ปัญหา ทรัพยากร Dependency

การใช้งาน Lockfile

แฟล็กสามารถควบคุมไฟล์ล็อกได้ --lockfile_mode ถึง ปรับแต่งลักษณะการทำงานของ Bazel เมื่อสถานะของโปรเจ็กต์แตกต่างจาก Lockfile โหมดที่ใช้ได้มีดังนี้

  • update (ค่าเริ่มต้น): ใช้ข้อมูลที่มีอยู่ในล็อกไฟล์เพื่อ ข้ามการดาวน์โหลดไฟล์รีจิสทรีที่รู้จัก และเพื่อหลีกเลี่ยงการประเมินส่วนขยายซ้ำ ที่ผลการค้นหายังคงเป็นปัจจุบัน หากข้อมูลขาดหายไป ระบบจะ เพิ่มลงในไฟล์ล็อกได้ ในโหมดนี้ Bazel จะหลีกเลี่ยงการรีเฟรชด้วย ข้อมูลที่เปลี่ยนแปลงได้ เช่น เวอร์ชันที่หายไป สำหรับทรัพยากร Dependency ที่ไม่มี มีการเปลี่ยนแปลง
  • refresh: เช่นเดียวกับ update แต่ข้อมูลที่เปลี่ยนแปลงจะมีการรีเฟรชเสมอ สลับเป็นโหมดนี้และทุกๆ ชั่วโมงโดยประมาณขณะอยู่ในโหมดนี้
  • error: เช่น update แต่หากข้อมูลขาดหายไปหรือล้าสมัย Bazel จะล้มเหลวเพราะมีข้อผิดพลาด โหมดนี้จะไม่เปลี่ยนล็อกไฟล์หรือ ส่งคำขอเครือข่ายในระหว่างการแก้ปัญหา ส่วนขยายโมดูลที่ทำเครื่องหมาย ตัวเองเป็น reproducible อาจยังดำเนินการตามคำขอเครือข่าย แต่ จะต้องให้ผลลัพธ์เดียวกันเสมอ
  • off: ไม่ได้ตรวจสอบหรืออัปเดตไฟล์ล็อก

ประโยชน์ของไฟล์ล็อก

Lockfile มีข้อดีหลายอย่างและใช้ประโยชน์ได้หลากหลายดังนี้

  • บิลด์ที่ทำซ้ำได้ ด้วยการบันทึกเวอร์ชันหรือทรัพยากร Dependency ที่เฉพาะเจาะจง ของไลบรารีซอฟต์แวร์ ล็อกไฟล์ช่วยให้มั่นใจได้ว่าบิลด์สามารถทำซ้ำได้ จากสภาพแวดล้อมต่างๆ ในช่วงเวลาที่ผ่านมา นักพัฒนาแอปสามารถพึ่งพา ผลลัพธ์ที่สอดคล้องกันและคาดการณ์ได้เมื่อสร้างโปรเจ็กต์

  • ได้ความละเอียดเพิ่มขึ้นอย่างรวดเร็ว ไฟล์ล็อกช่วยให้ Bazel หลีกเลี่ยง การดาวน์โหลดไฟล์รีจิสทรีที่ใช้อยู่แล้วในบิลด์ก่อนหน้า ซึ่งจะช่วยปรับปรุงประสิทธิภาพของการสร้างได้อย่างมาก โดยเฉพาะในสถานการณ์ที่ อาจต้องใช้เวลานาน

  • ความเสถียรและการลดความเสี่ยง ไฟล์ล็อกจะช่วยรักษาความเสถียรโดย เพื่อป้องกันการอัปเดตที่ไม่คาดคิดหรือทำให้การเปลี่ยนแปลงในไลบรารีภายนอกเสียหาย โดย การล็อกทรัพยากร Dependency เป็นเวอร์ชันที่เฉพาะเจาะจง ความเสี่ยงที่จะเกิดข้อบกพร่อง จากการอัปเดตที่ใช้ร่วมกันไม่ได้หรือยังไม่ผ่านการทดสอบจะลดลง

เนื้อหาของ Lockfile

ไฟล์ล็อกประกอบด้วยข้อมูลที่จำเป็นทั้งหมดเพื่อพิจารณาว่า เปลี่ยนสถานะโปรเจ็กต์แล้ว นอกจากนี้ยังรวมถึงผลลัพธ์ของการสร้างโครงการ ในสถานะปัจจุบัน ไฟล์ล็อกประกอบด้วย 2 ส่วนหลักดังนี้

  1. แฮชของไฟล์ระยะไกลทั้งหมดที่เป็นอินพุตสำหรับความละเอียดของโมดูล
  2. สำหรับส่วนขยายโมดูลแต่ละรายการ ไฟล์ล็อกจะมีอินพุตที่ส่งผลต่อ แสดงด้วย bzlTransitiveDigest, usagesDigest และฟิลด์อื่นๆ เป็น รวมถึงเอาต์พุตของการเรียกใช้ส่วนขยายนั้น ซึ่งเรียกว่า 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 มีแฮชของไฟล์ทั้งหมดจาก รีจิสทรีระยะไกลที่มีการเข้าถึงระหว่างการแก้ไขโมดูล ตั้งแต่ความละเอียด อัลกอริทึมสามารถถูกกำหนดได้โดยสมบูรณ์เมื่อได้รับอินพุตเดียวกันและระยะไกลทั้งหมด ระบบจะแฮชข้อมูลเหล่านี้ เพื่อให้แน่ใจว่าผลลัพธ์ของความละเอียดจะ เกิดขึ้นซ้ำได้อย่างสมบูรณ์ หลีกเลี่ยงการใช้ข้อมูลระยะไกลในล็อกไฟล์มากเกินไป โปรดทราบว่า จะต้องมีการบันทึกเมื่อรีจิสทรีรายการหนึ่งไม่มี แต่รีจิสทรีที่มีความสำคัญต่ำกว่า (ดูรายการ "ไม่พบ" ใน ตัวอย่าง) คุณสามารถอัปเดตข้อมูลตามธรรมชาตินี้ได้ผ่านทาง bazel mod deps --lockfile_mode=refresh

Bazel ใช้แฮชจากไฟล์ล็อกเพื่อค้นหาไฟล์รีจิสทรีใน ของที่เก็บแคชไว้ก่อนที่จะดาวน์โหลด ซึ่งทำให้เพิ่มความเร็วขึ้นได้ในเวลาต่อมา ความละเอียดสูงสุด

เวอร์ชัน Yanked ที่เลือก

ส่วน selectedYankedVersions มีโมดูลเวอร์ชันแยก ที่เลือกตามความละเอียดของโมดูล เนื่องจากโดยปกติแล้วมักจะทำให้เกิดข้อผิดพลาด เมื่อพยายามสร้าง ส่วนนี้ไม่ว่างเปล่าเมื่อรุ่นที่แยกออกมา อนุญาตอย่างชัดแจ้งผ่าน --allow_yanked_versions หรือ BZLMOD_ALLOW_YANKED_VERSIONS

จำเป็นต้องมีช่องนี้ เนื่องจากเมื่อเทียบกับไฟล์โมดูล ข้อมูลเวอร์ชันที่ย้ายแล้ว เปลี่ยนแปลงได้อยู่แล้ว จึงอ้างอิงด้วยแฮชไม่ได้ ข้อมูลนี้ สามารถอัปเดตผ่าน bazel mod deps --lockfile_mode=refresh

ส่วนขยายโมดูล

ส่วน moduleExtensions คือแผนที่ที่มีเฉพาะส่วนขยายที่ใช้ ในการเรียกใช้ปัจจุบันหรือที่เรียกใช้ก่อนหน้านี้ ขณะเดียวกันก็ไม่รวมส่วนขยายใดๆ ที่ไม่ได้ใช้งานแล้ว กล่าวคือ หากไม่มีการใช้ส่วนขยาย ในกราฟทรัพยากร Dependency อีกต่อไป โดยจะนำออกจาก moduleExtensions แผนที่

หากส่วนขยายไม่เกี่ยวข้องกับระบบปฏิบัติการหรือประเภทสถาปัตยกรรม ส่วนนี้แสดงเฉพาะ "ทั่วไป" เพียงอย่างเดียว รายการ มิฉะนั้น คูณ แต่ละรายการ โดยตั้งชื่อตามระบบปฏิบัติการ สถาปัตยกรรม หรือทั้งสองอย่าง ซึ่งตรงกับผลการประเมินส่วนขยายสำหรับข้อมูลเหล่านั้นโดยเฉพาะ

แต่ละรายการในแผนที่ส่วนขยายสอดคล้องกับส่วนขยายที่ใช้และ ที่ระบุโดยไฟล์และชื่อไฟล์ที่มี ค่าที่เกี่ยวข้องสำหรับแต่ละค่า รายการจะมีข้อมูลที่เกี่ยวข้องกับส่วนขยายนั้น ดังนี้

  1. bzlTransitiveDigest คือสรุปของการติดตั้งใช้งานส่วนขยาย และไฟล์ .bzl ที่โหลดแบบทรานซิชัน
  2. usagesDigest คือไดเจสต์ของการใช้งานของส่วนขยายใน กราฟทรัพยากร Dependency ซึ่งมีแท็กทั้งหมด
  3. ฟิลด์ที่ไม่ได้ระบุเพิ่มเติม ซึ่งจะติดตามอินพุตอื่นๆ ไปยังส่วนขยาย เช่น เนื้อหาของไฟล์หรือไดเรกทอรีที่อ่าน หรือสภาพแวดล้อม ตัวแปรที่ใช้อยู่
  4. generatedRepoSpecs เข้ารหัสที่เก็บที่สร้างโดย ด้วยอินพุตปัจจุบัน
  5. ช่อง moduleExtensionMetadata ที่ไม่บังคับมีข้อมูลเมตาจาก ส่วนขยาย เช่น ที่เก็บบางรายการที่ส่วนขยายสร้างขึ้นควร นำเข้าผ่าน use_repo โดยโมดูลรูท ข้อมูลนี้ช่วยขับเคลื่อน คำสั่ง bazel mod tidy

ส่วนขยายโมดูลสามารถเลือกไม่ใช้การรวมในไฟล์ล็อกได้โดยการตั้งค่า การแสดงผลข้อมูลเมตาพร้อม reproducible = True ในการทำเช่นนั้น พวกเขาให้สัญญาว่า โมเดลจะสร้างที่เก็บเดียวกันเสมอเมื่อได้รับอินพุตเดียวกัน

แนวทางปฏิบัติแนะนำ

หากต้องการเพิ่มประโยชน์ของฟีเจอร์ล็อกไฟล์ ให้พิจารณาข้อมูลต่อไปนี้ แนวทางปฏิบัติ:

  • อัปเดตล็อกไฟล์เป็นประจำเพื่อให้สอดคล้องกับการเปลี่ยนแปลงทรัพยากร Dependency ของโปรเจ็กต์ หรือ การกำหนดค่า ซึ่งทำให้มั่นใจว่าบิลด์ต่อๆ ไปจะอิงตาม ชุดทรัพยากร Dependency ที่เป็นปัจจุบันและถูกต้อง วิธีล็อกส่วนขยายทั้งหมด ให้เรียกใช้ bazel mod deps --lockfile_mode=update พร้อมกัน

  • รวมไฟล์ล็อกไว้ในการควบคุมเวอร์ชันเพื่ออำนวยความสะดวกในการทำงานร่วมกันและ ให้สมาชิกทุกคนในทีมมีสิทธิ์เข้าถึงล็อกไฟล์เดียวกัน ซึ่งจะโปรโมต สภาพแวดล้อมในการพัฒนาซอฟต์แวร์ที่สอดคล้องกันทั้งโครงการ

  • ใช้ bazelisk เพื่อเรียกใช้ Bazel และใส่ .bazelversion ในการควบคุมเวอร์ชันที่ระบุเวอร์ชัน Bazel ที่สัมพันธ์กับไฟล์ล็อก เนื่องจากบาเซลเองก็เป็นที่พึ่งพิงของ บิลด์ของคุณ ไฟล์ล็อกจะมีเฉพาะสําหรับเวอร์ชัน Bazel และจะ เปลี่ยนแปลงได้แม้ว่าเข้ากันได้แบบย้อนหลัง Bazel เปิดตัว การใช้ bazelisk ช่วยให้นักพัฒนาซอฟต์แวร์ทุกรายใช้งาน เวอร์ชัน Bazel ที่ตรงกับไฟล์ล็อก

การทำตามแนวทางปฏิบัติแนะนำเหล่านี้จะช่วยให้คุณสามารถใช้ล็อกไฟล์ได้อย่างมีประสิทธิภาพ ใน Bazel ที่จะทำให้มีประสิทธิภาพ เชื่อถือได้ และทำงานร่วมกันได้มากขึ้น การพัฒนาซอฟต์แวร์

ความขัดแย้งในการรวม

รูปแบบ Lockfile ได้รับการออกแบบมาเพื่อลดความขัดแย้งในการรวม แต่ก็ยังสามารถ เกิดขึ้น

ความละเอียดอัตโนมัติ

Bazel เพิ่มช่อง git Merge Driver เพื่อช่วยแก้ไขความขัดแย้งเหล่านี้โดยอัตโนมัติ

ตั้งค่าไดรเวอร์โดยเพิ่มบรรทัดนี้ลงในไฟล์ .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"

การแก้ปัญหาด้วยตนเอง

ความขัดแย้งของการรวมอย่างง่ายใน registryFileHashes และ selectedYankedVersions สามารถแก้ช่องได้อย่างปลอดภัยด้วยการเก็บรายการทั้งหมดจากทั้ง 2 ฝั่งของ ความขัดแย้ง

คุณไม่ควรแก้ไขความขัดแย้งของการรวมประเภทอื่นๆ ด้วยตนเอง ให้ดำเนินการต่อไปนี้แทน

  1. กู้คืนสถานะก่อนหน้าของ Lockfile ผ่าน git reset MODULE.bazel.lock && git checkout MODULE.bazel.lock
  2. แก้ไขความขัดแย้งในไฟล์ MODULE.bazel
  3. เรียกใช้ bazel mod deps เพื่ออัปเดตไฟล์ล็อก