Trang này dành cho những người viết quy tắc đang có kế hoạch cung cấp quy tắc của họ cho người khác.
Bạn nên bắt đầu một bộ quy tắc mới từ kho lưu trữ mẫu: https://github.com/bazel-contrib/rules-template Mẫu đó tuân theo các đề xuất bên dưới, đồng thời bao gồm việc tạo tài liệu về API và thiết lập quy trình CI/CD để giúp bạn dễ dàng phân phối bộ quy tắc.
Quy tắc đặt tên và lưu trữ
Các quy tắc mới phải nằm trong kho lưu trữ GitHub riêng trong tổ chức của bạn. Hãy bắt đầu một chuỗi thảo luận trên GitHub nếu bạn cảm thấy các quy tắc của mình thuộc về tổ chức bazelbuild.
Tên kho lưu trữ cho các quy tắc Bazel được chuẩn hoá theo định dạng sau:
$ORGANIZATION/rules_$NAME.
Xem các ví dụ trên GitHub.
Để đảm bảo tính nhất quán, bạn nên tuân theo cùng một định dạng này khi xuất bản các quy tắc Bazel.
Hãy nhớ sử dụng nội dung mô tả kho lưu trữ GitHub mang tính mô tả và README.md
tiêu đề, ví dụ:
- Tên kho lưu trữ:
bazelbuild/rules_go - Nội dung mô tả kho lưu trữ: Quy tắc Go cho Bazel
- Thẻ kho lưu trữ:
golang,bazel README.mdtiêu đề: Quy tắc Go cho Bazel (lưu ý đường liên kết đến https://bazel.build sẽ hướng dẫn những người dùng chưa quen với Bazel đến đúng vị trí)
Bạn có thể nhóm các quy tắc theo ngôn ngữ (chẳng hạn như Scala), nền tảng thời gian chạy (chẳng hạn như Android) hoặc khung (chẳng hạn như Spring).
Nội dung kho lưu trữ
Mỗi kho lưu trữ quy tắc phải có một bố cục nhất định để người dùng có thể nhanh chóng hiểu các quy tắc mới.
Ví dụ: khi viết các quy tắc mới cho ngôn ngữ (giả định)
mockascript, kho lưu trữ quy tắc sẽ có cấu trúc sau:
/
LICENSE
README
WORKSPACE
mockascript/
constraints/
BUILD
runfiles/
BUILD
runfiles.mocs
BUILD
defs.bzl
tests/
BUILD
some_test.sh
another_test.py
examples/
BUILD
bin.mocs
lib.mocs
test.mocs
WORKSPACE
Trong WORKSPACE của dự án, bạn nên xác định tên mà người dùng sẽ sử dụng
để tham chiếu đến các quy tắc của bạn. Nếu các quy tắc của bạn thuộc về tổ chức
bazelbuild, bạn phải sử dụng
rules_<lang> (chẳng hạn như rules_mockascript). Nếu không, bạn nên đặt tên
kho lưu trữ <org>_rules_<lang> của mình (chẳng hạn như build_stack_rules_proto). Vui lòng
bắt đầu một chuỗi thảo luận trên GitHub
nếu bạn cảm thấy các quy tắc của mình nên tuân theo quy ước cho các quy tắc trong tổ chức
bazelbuild.
Trong các phần sau, hãy giả sử kho lưu trữ thuộc về tổ chức bazelbuild.
workspace(name = "rules_mockascript")
README
Ở cấp cao nhất, phải có một README chứa (ít nhất) những nội dung mà
người dùng sẽ cần sao chép-dán vào tệp WORKSPACE của họ để sử dụng quy tắc của bạn.
Nói chung, đây sẽ là một http_archive trỏ đến bản phát hành GitHub và
một lệnh gọi macro tải xuống/định cấu hình mọi công cụ mà quy tắc của bạn cần. Ví dụ:
đối với các quy tắc Go, quy tắc này
có dạng như sau:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_go",
urls = ["https://github.com/bazelbuild/rules_go/releases/download/0.18.5/rules_go-0.18.5.tar.gz"],
sha256 = "a82a352bffae6bee4e95f68a8d80a70e87f42c4741e6a448bec11998fcc82329",
)
load("@rules_go//go:deps.bzl", "go_rules_dependencies", "go_register_toolchains")
go_rules_dependencies()
go_register_toolchains()
Quy tắc
Thông thường, kho lưu trữ của bạn sẽ cung cấp nhiều quy tắc. Tạo một
thư mục được đặt tên theo ngôn ngữ và cung cấp một điểm nhập – tệp defs.bzl xuất tất cả các quy tắc (cũng bao gồm một tệp BUILD để thư mục là một gói).
Đối với rules_mockascript, điều đó có nghĩa là sẽ có một thư mục có tên là
mockascript, một tệp BUILD và một tệp defs.bzl bên trong:
/
mockascript/
BUILD
defs.bzl
Giới hạn
Nếu quy tắc của bạn xác định
chuỗi công cụ quy tắc,
thì có thể bạn sẽ cần xác định constraint_setting tuỳ chỉnh và/hoặc
constraint_value. Đặt các quy tắc này vào một gói //<LANG>/constraints. Cấu trúc thư mục của bạn
sẽ có dạng như sau:
/
mockascript/
constraints/
BUILD
BUILD
defs.bzl
Vui lòng đọc
github.com/bazelbuild/platforms
để biết các phương pháp hay nhất và xem những giới hạn đã có, đồng thời
cân nhắc đóng góp các giới hạn của bạn ở đó nếu các giới hạn đó không phụ thuộc vào ngôn ngữ.
Hãy lưu ý đến việc giới thiệu các giới hạn tuỳ chỉnh, tất cả người dùng quy tắc của bạn sẽ
sử dụng các giới hạn đó để thực hiện logic dành riêng cho nền tảng trong tệp BUILD của họ (ví dụ:
sử dụng lựa chọn).
Với các giới hạn tuỳ chỉnh, bạn xác định một ngôn ngữ mà toàn bộ hệ sinh thái Bazel
sẽ sử dụng.
Thư viện runfiles
Nếu quy tắc của bạn cung cấp một thư viện tiêu chuẩn để truy cập vào runfiles, thì quy tắc đó phải ở dạng mục tiêu thư viện nằm tại //<LANG>/runfiles (viết tắt
của //<LANG>/runfiles:runfiles). Các mục tiêu của người dùng cần truy cập vào các phần phụ thuộc dữ liệu của họ thường sẽ thêm mục tiêu này vào thuộc tính deps.
Quy tắc kho lưu trữ
Phần phụ thuộc
Các quy tắc của bạn có thể có các phần phụ thuộc bên ngoài. Để giúp việc phụ thuộc vào các quy tắc của bạn
trở nên đơn giản hơn, vui lòng cung cấp một macro WORKSPACE sẽ khai báo các phần phụ thuộc vào
những phần phụ thuộc bên ngoài đó. Không khai báo các phần phụ thuộc của bài kiểm thử ở đó, chỉ
các phần phụ thuộc mà quy tắc yêu cầu để hoạt động. Đặt các phần phụ thuộc phát triển vào tệp
WORKSPACE.
Tạo một tệp có tên là <LANG>/repositories.bzl và cung cấp một điểm nhập duy nhất
macro có tên là rules_<LANG>_dependencies. Thư mục của chúng tôi sẽ có dạng như sau:
/
mockascript/
constraints/
BUILD
BUILD
defs.bzl
repositories.bzl
Đăng ký chuỗi công cụ
Các quy tắc của bạn cũng có thể đăng ký chuỗi công cụ. Vui lòng cung cấp một WORKSPACE
macro riêng biệt để đăng ký các chuỗi công cụ này. Bằng cách này, người dùng có thể quyết định bỏ qua macro trước đó và kiểm soát các phần phụ thuộc theo cách thủ công, đồng thời vẫn được phép đăng ký chuỗi công cụ.
Do đó, hãy thêm một WORKSPACE macro có tên là rules_<LANG>_toolchains vào
<LANG>/repositories.bzl tệp.
Xin lưu ý rằng để phân giải các chuỗi công cụ trong giai đoạn phân tích, Bazel cần
phân tích tất cả các mục tiêu toolchain đã đăng ký. Bazel sẽ không cần
phân tích tất cả các mục tiêu được tham chiếu bởi thuộc tính toolchain.toolchain. Nếu để đăng ký chuỗi công cụ, bạn cần thực hiện tính toán phức tạp trong kho lưu trữ, hãy cân nhắc chia kho lưu trữ bằng các mục tiêu toolchain từ kho lưu trữ bằng các mục tiêu <LANG>_toolchain. Kho lưu trữ trước sẽ luôn được tìm nạp và
kho lưu trữ sau sẽ chỉ được tìm nạp khi người dùng thực sự cần tạo mã <LANG> code.
Đoạn mã phát hành
Trong thông báo phát hành, hãy cung cấp một đoạn mã mà người dùng có thể sao chép-dán
vào tệp WORKSPACE của họ. Đoạn mã này nói chung sẽ có dạng như sau:
load("@bazel_tools//tools/build_defs/repo:http.bzl", "http_archive")
http_archive(
name = "rules_<LANG>",
urls = ["<url_to_the_release.zip"],
sha256 = "4242424242",
)
load("@rules_<LANG>//<LANG>:repositories.bzl", "rules_<LANG>_dependencies", "rules_<LANG>_toolchains")
rules_<LANG>_dependencies()
rules_<LANG>_toolchains()
Thử nghiệm
Phải có các bài kiểm thử để xác minh rằng các quy tắc đang hoạt động như mong đợi. Điều này
có thể ở vị trí tiêu chuẩn cho ngôn ngữ mà các quy tắc dành cho hoặc thư mục
tests/ ở cấp cao nhất.
Ví dụ (không bắt buộc)
Người dùng sẽ thấy hữu ích khi có một thư mục examples/ cho thấy một vài cách cơ bản
mà các quy tắc có thể được sử dụng.
CI/CD
Nhiều bộ quy tắc sử dụng GitHub Actions. Xem cấu hình được sử dụng trong kho lưu trữ rules-template, được đơn giản hoá bằng "quy trình làm việc có thể sử dụng lại" được lưu trữ trong tổ chức bazel-contrib. ci.yaml chạy kiểm thử trên mỗi PR và cam kết main, còn release.yaml chạy bất cứ khi nào bạn đẩy một thẻ vào kho lưu trữ.
Xem nhận xét trong kho lưu trữ rules-template để biết thêm thông tin.
Nếu kho lưu trữ của bạn thuộc tổ chức bazelbuild, bạn có thể yêu cầu thêm kho lưu trữ đó vào ci.bazel.build.
Tài liệu
Xem tài liệu Stardoc để biết hướng dẫn về cách nhận xét các quy tắc của bạn để tài liệu có thể được tạo tự động.
Thư mục docs/ của rules-template
cho thấy một cách đơn giản để đảm bảo nội dung Markdown trong thư mục docs/ luôn được cập nhật
khi các tệp Starlark được cập nhật.
Câu hỏi thường gặp
Tại sao chúng ta không thể thêm quy tắc của mình vào kho lưu trữ GitHub Bazel chính?
Chúng tôi muốn tách các quy tắc khỏi các bản phát hành Bazel càng nhiều càng tốt. Việc này giúp xác định rõ hơn ai là chủ sở hữu các quy tắc riêng lẻ, giảm tải cho các nhà phát triển Bazel. Đối với người dùng, việc tách rời giúp họ dễ dàng sửa đổi, nâng cấp, hạ cấp và thay thế các quy tắc hơn. Việc đóng góp cho các quy tắc có thể nhẹ hơn so với việc đóng góp cho Bazel - tuỳ thuộc vào các quy tắc –, bao gồm cả quyền truy cập gửi đầy đủ vào kho lưu trữ GitHub tương ứng. Việc có quyền truy cập gửi vào chính Bazel là một quy trình phức tạp hơn nhiều.
Nhược điểm là quy trình cài đặt một lần phức tạp hơn cho người dùng:
họ phải sao chép-dán một quy tắc vào tệp WORKSPACE của mình, như minh hoạ trong phần
README.md ở trên.
Trước đây, chúng tôi có tất cả các quy tắc trong kho lưu trữ Bazel (trong
//tools/build_rules hoặc //tools/build_defs). Chúng tôi vẫn có một vài quy tắc
ở đó, nhưng đang nỗ lực di chuyển các quy tắc còn lại ra ngoài.