การโต้ตอบแบบวันต่อวันกับ Bazel จะเกิดขึ้นผ่านคำสั่ง 2-3 อย่างหลักๆ ดังนี้
build
, test
และ run
แต่ในบางครั้ง อาจมีข้อจำกัดต่อไปนี้:
ต้องการพุชแพ็กเกจไปยังที่เก็บ เผยแพร่เอกสารสำหรับผู้ใช้ปลายทาง หรือ
ทำให้แอปพลิเคชันใช้งานได้ด้วย Kubernetes แต่ Bazel ไม่มี publish
หรือ
คำสั่ง deploy
– การดำเนินการเหล่านี้เหมาะกับตำแหน่งใด
คำสั่งเรียกใช้ Bazel
การมุ่งเน้นของ Bazel ในด้านความต่อเนื่อง การทำซ้ำ และส่วนเพิ่มหมายถึง
คำสั่ง build
และ test
ไม่มีประโยชน์ต่องานด้านบน การดำเนินการเหล่านี้
อาจทำงานในแซนด์บ็อกซ์โดยมีการจำกัดการเข้าถึงเครือข่าย และไม่รับประกันว่า
ให้เรียกใช้ทุก bazel build
อีกครั้ง
แต่ให้อาศัย bazel run
แทน ซึ่งเป็นภาระงานที่ต้องการมี
ของ Google ผู้ใช้ Bazel คุ้นเคยกับกฎที่สร้างไฟล์ที่เรียกใช้งานได้ และ
ผู้เขียนกฎสามารถทำตามชุดรูปแบบทั่วไปเพื่อขยาย
"คำกริยาที่กำหนดเอง"
ป่าเถื่อน: rules_k8s
ตัวอย่างเช่น ลองพิจารณา rules_k8s
กฎ Kubernetes สำหรับ Bazel สมมติว่าคุณมีเป้าหมายต่อไปนี้
# BUILD file in //application/k8s
k8s_object(
name = "staging",
kind = "deployment",
cluster = "testing",
template = "deployment.yaml",
)
กฎ k8s_object
จะสร้าง
ไฟล์ Kubernetes YAML มาตรฐานเมื่อใช้ bazel build
ใน staging
เป้าหมาย อย่างไรก็ตาม เป้าหมายเพิ่มเติมก็สร้างขึ้นโดย k8s_object
เช่นกัน
ที่มีชื่ออย่างเช่น staging.apply
และ :staging.delete
บิลด์เหล่านี้
สคริปต์เพื่อดำเนินการดังกล่าว และเมื่อเรียกใช้ด้วย bazel run
staging.apply
สคริปต์เหล่านี้จะทำงานเหมือนคำสั่ง bazel k8s-apply
หรือ bazel
k8s-delete
ของเราเอง
อีกตัวอย่างหนึ่ง: ts_api_guardian_test
รูปแบบนี้สามารถดูในโปรเจ็กต์ Angular ได้ด้วย
มาโคร ts_api_guardian_test
จะสร้างเป้าหมาย 2 อย่าง รายการแรกคือเป้าหมาย nodejs_test
มาตรฐานซึ่งเปรียบเทียบ
เอาต์พุตบางส่วนที่สร้างขึ้นสำหรับ "ทอง" (ซึ่งก็คือ ไฟล์ที่มีองค์ประกอบ
เอาต์พุตที่คาดหวัง) ซึ่งสร้างและเรียกใช้ได้ด้วยการเรียกใช้ bazel
test
ปกติ ใน angular-cli
คุณสามารถเรียกใช้ประเภท
เป้าหมาย
ด้วย bazel test //etc/api:angular_devkit_core_api
เมื่อเวลาผ่านไป คุณอาจต้องอัปเดตไฟล์ทองคำนี้ด้วยเหตุผลที่เหมาะสม
การอัปเดตด้วยตนเองนี้น่าเบื่อและเกิดข้อผิดพลาดได้ง่าย ดังนั้นมาโครนี้ยังมี
เป้าหมาย nodejs_binary
ที่อัปเดตไฟล์ทองคำแทนการเปรียบเทียบ
แข่งกับสิ่งนั้น สามารถเขียนสคริปต์การทดสอบเดียวกันเพื่อทำงานใน "ยืนยัน" ได้อย่างมีประสิทธิภาพ
หรือ "ยอมรับ" ตามวิธีที่ระบบเรียกใช้ ซึ่งจะเป็นไปตามรูปแบบเดียวกัน
ที่คุณได้เรียนรู้แล้ว ไม่มีคำสั่ง bazel test-accept
แบบเนทีฟ แต่
และจะให้ผลลัพธ์แบบเดียวกัน
bazel run //etc/api:angular_devkit_core_api.accept
รูปแบบนี้อาจใช้ได้ผลดีมาก และกลายเป็นรูปแบบที่พบได้บ่อยเมื่อคุณ เรียนรู้ที่จะจดจำ
การปรับกฎของคุณเอง
มาโครคือหัวใจของรูปแบบนี้ มาโครใช้ในลักษณะ แต่สามารถสร้างเป้าหมายหลายรายการได้ โดยทั่วไปพวกเขาจะสร้าง เป้าหมายด้วยชื่อที่ระบุซึ่งดำเนินการบิลด์หลัก: บางที โมเดลจะสร้างไบนารีปกติ อิมเมจ Docker หรือซอร์สโค้ดที่เก็บถาวร ใน รูปแบบนี้ เป้าหมายเพิ่มเติมจะถูกสร้างขึ้นเพื่อสร้างสคริปต์ที่ทำงานด้าน ตามผลลัพธ์ของเป้าหมายหลัก เช่น การเผยแพร่ ผลลัพธ์ไบนารีที่เป็นผลลัพธ์ หรืออัปเดตเอาต์พุตทดสอบที่คาดไว้
เพื่อให้เห็นภาพชัดขึ้น ให้รวมกฎจินตภาพที่สร้างเว็บไซต์ที่มี Sphinx กับมาโครเพื่อสร้าง เป้าหมายที่อนุญาตให้ผู้ใช้เผยแพร่เมื่อพร้อม ลองพิจารณาวิธีต่อไปนี้ กฎที่มีอยู่สำหรับการสร้างเว็บไซต์ที่มี Sphinx มีดังนี้
_sphinx_site = rule(
implementation = _sphinx_impl,
attrs = {"srcs": attr.label_list(allow_files = [".rst"])},
)
ถัดไป ให้พิจารณากฎดังตัวอย่างต่อไปนี้ ซึ่งจะสร้างสคริปต์ที่เมื่อเรียกใช้ เผยแพร่หน้าเว็บที่สร้างขึ้น
_sphinx_publisher = rule(
implementation = _publish_impl,
attrs = {
"site": attr.label(),
"_publisher": attr.label(
default = "//internal/sphinx:publisher",
executable = True,
),
},
executable = True,
)
สุดท้าย ให้กำหนดมาโครต่อไปนี้เพื่อสร้างเป้าหมายสำหรับทั้ง 2 อย่างข้างต้น เข้าด้วยกัน
def sphinx_site(name, srcs = [], **kwargs):
# This creates the primary target, producing the Sphinx-generated HTML.
_sphinx_site(name = name, srcs = srcs, **kwargs)
# This creates the secondary target, which produces a script for publishing
# the site generated above.
_sphinx_publisher(name = "%s.publish" % name, site = name, **kwargs)
ในไฟล์ BUILD
ให้ใช้มาโครเหมือนกับว่าสร้างเฉพาะมาโครหลัก
เป้าหมาย:
sphinx_site(
name = "docs",
srcs = ["index.md", "providers.md"],
)
ในตัวอย่างนี้ "เอกสาร" สร้างเป้าหมายขึ้นมา เช่นเดียวกับที่ว่ามาโคร
กฎมาตรฐานข้อเดียวของ Bazel เมื่อสร้าง กฎจะสร้างการกำหนดค่าบางอย่าง
และเรียกใช้ Sphinx เพื่อสร้างเว็บไซต์ HTML ที่พร้อมสำหรับการตรวจสอบด้วยตนเอง อย่างไรก็ตาม
"docs.publish" เพิ่มเติม ก็จะสร้างสคริปต์
กำลังเผยแพร่ไซต์ เมื่อคุณตรวจสอบเอาต์พุตของเป้าหมายหลักแล้ว คุณจะสามารถทำสิ่งต่อไปนี้
ใช้ bazel run :docs.publish
เพื่อเผยแพร่สำหรับสาธารณะ เช่นเดียวกับ
คำสั่ง bazel publish
ในจินตนาการ
เรายังไม่ทราบโดยทันทีว่าการใช้ _sphinx_publisher
เป็นไปอย่างไร
อาจมีหน้าตาของกฎ การดำเนินการเช่นนี้มักจะเขียนสคริปต์เชลล์ Launcher
โดยทั่วไป วิธีการนี้รวมถึงการใช้
ctx.actions.expand_template
ในการเขียนสคริปต์เชลล์แบบง่ายมาก ซึ่งในกรณีนี้จะเรียกใช้ไบนารีของผู้เผยแพร่โฆษณา
ที่มีเส้นทางไปยังเอาต์พุตของเป้าหมายหลัก วิธีนี้ช่วยให้ผู้เผยแพร่โฆษณา
การใช้งานยังคงเป็นแบบทั่วไป กฎ _sphinx_site
จะทำได้เพียง
HTML และสคริปต์ขนาดเล็กนี้ก็เป็นแค่สิ่งที่จำเป็นในการรวมทั้งสอง
ใน rules_k8s
นี่คือสิ่งที่ .apply
ทำจริงๆ:
expand_template
เขียนสคริปต์ Bash แบบง่ายๆ จาก
apply.sh.tpl
,
ซึ่งเรียกใช้ kubectl
พร้อมเอาต์พุตของเป้าหมายหลัก สคริปต์นี้สามารถ
จะสร้างและเรียกใช้ด้วย bazel run :staging.apply
อย่างมีประสิทธิภาพ
คำสั่ง k8s-apply
สำหรับเป้าหมาย k8s_object