Trang này dành cho những người viết quy tắc dự định 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, bao gồm cả việc tạo tài liệu 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 về việc lưu trữ và đặt tên
Các quy tắc mới phải được đưa vào kho lưu trữ GitHub riêng của họ trong tổ chức của bạn. Bắt đầu một chuỗi trên GitHub nếu bạn cảm thấy các quy tắc của mình thuộc 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 ví dụ trên GitHub.
Để đảm bảo tính nhất quán, bạn nên tuân theo định dạng này khi phát hành quy tắc Bazel.
Hãy nhớ sử dụng nội dung mô tả kho lưu trữ GitHub và tiêu đề README.md
mô tả, 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
- Tiêu đề
README.md
: Quy tắc Go cho Bazel (lưu ý đường liên kết đến https://bazel.build sẽ hướng dẫn người dùng không quen thuộc với Bazel đến đúng nơi)
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ác quy tắc mới.
Ví dụ: khi viết các quy tắc mới cho ngôn ngữ mockascript
(giả sử), kho lưu trữ quy tắc sẽ có cấu trúc như 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 các quy tắc của bạn. Nếu quy tắc của bạn thuộc 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ữ là <org>_rules_<lang>
(chẳng hạn như build_stack_rules_proto
). Vui lòng bắt đầu một chuỗi trên GitHub nếu bạn cảm thấy quy tắc của mình phải tuân theo quy ước cho quy tắc trong tổ chức bazelbuild.
Trong các phần sau, giả sử kho lưu trữ thuộc 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) nội dung mà người dùng cần sao chép và dán vào tệp WORKSPACE
để sử dụng quy tắc của bạn.
Nhìn 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 quy tắc Go, nội dung này sẽ 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()
Nếu quy tắc của bạn phụ thuộc vào quy tắc của một kho lưu trữ khác, hãy chỉ định điều đó trong tài liệu về quy tắc (ví dụ: xem quy tắc Skydoc phụ thuộc vào quy tắc Sass) và cung cấp một macro WORKSPACE
sẽ tải tất cả phần phụ thuộc xuống (xem rules_go
ở trên).
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 truy cập – tệp defs.bzl
xuất tất cả các quy tắc (cũng bao gồm 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 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 các quy tắc chuỗi công cụ, thì có thể bạn sẽ cần xác định constraint_setting
và/hoặc constraint_value
tuỳ chỉnh. Đặt các tệp 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 nội dung tại github.com/bazelbuild/platforms để biết các phương pháp hay nhất và để xem những quy tắc ràng buộc hiện có, đồng thời cân nhắc đóng góp các quy tắc ràng buộc của bạn tại đó nếu chúng độc lập với ngôn ngữ.
Hãy lưu ý khi đưa ra các quy tắc ràng buộc tuỳ chỉnh, tất cả người dùng quy tắc của bạn sẽ sử dụng các quy tắc đó để thực hiện logic dành riêng cho nền tảng trong tệp BUILD
(ví dụ: sử dụng lựa chọn).
Với các quy tắc ràng buộc 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 tệp chạy
Nếu quy tắc của bạn cung cấp một thư viện chuẩn để truy cập vào tệp chạy, 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 người dùng cần truy cập vào 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
Quy tắc của bạn có thể có các phần phụ thuộc bên ngoài. Để đơn giản hoá việc phụ thuộc vào các quy tắc của bạn, vui lòng cung cấp một macro WORKSPACE
sẽ khai báo các phần phụ thuộc trên các phần phụ thuộc bên ngoài đó. Đừng khai báo phần phụ thuộc của kiểm thử ở đó, chỉ khai báo 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 <LANG>/repositories.bzl
và cung cấp một macro điểm truy cập duy nhất có tên rules_<LANG>_dependencies
. Thư mục của chúng ta sẽ có dạng như sau:
/
mockascript/
constraints/
BUILD
BUILD
defs.bzl
repositories.bzl
Đăng ký chuỗi công 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 macro WORKSPACE
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
mã 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 macro WORKSPACE
có tên là rules_<LANG>_toolchains
vào tệp <LANG>/repositories.bzl
.
Xin lưu ý rằng để phân giải 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ằng thuộc tính toolchain.toolchain
. Nếu để đăng ký chuỗi công cụ, bạn cần thực hiện phép tính phức tạp trong kho lưu trữ, hãy cân nhắc việc tách kho lưu trữ có mục tiêu toolchain
khỏi kho lưu trữ có mục tiêu <LANG>_toolchain
. Mã trước sẽ luôn được tìm nạp và mã sau sẽ chỉ được tìm nạp khi người dùng thực sự cần tạo mã <LANG>
.
Phát hành đoạn mã
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 và dán vào tệp WORKSPACE
. Nói chung, đoạn mã này 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
Bạn nên 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. Thư mục này có thể nằm ở vị trí tiêu chuẩn cho ngôn ngữ của quy tắc 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 họ biết một số cách cơ bản để sử dụng các quy tắc.
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 cách sử dụ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 yêu cầu thay đổi và thay đổi main
, còn release.yaml
chạy bất cứ khi nào bạn đẩy thẻ vào kho lưu trữ.
Hãy xem các 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
Hãy xem tài liệu về Stardoc để biết hướng dẫn về cách chú thích quy tắc để có thể tự động tạo tài liệu.
Thư mục rules-template docs/ 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 vào kho lưu trữ GitHub chính của Bazel?
Chúng tôi muốn tách biệt các quy tắc khỏi bản phát hành Bazel càng nhiều càng tốt. Bạn sẽ biết rõ hơn ai sở hữu các quy tắc riêng lẻ, giúp giảm tải cho các nhà phát triển Bazel. Đối với người dùng, việc tách biệt giúp dễ dàng sửa đổi, nâng cấp, hạ cấp và thay thế các quy tắc. 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 gửi đầy đủ vào kho lưu trữ GitHub tương ứng. Việc có quyền gửi vào 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 đối với người dùng: họ phải sao chép và dán một quy tắc vào tệp WORKSPACE
, như minh hoạ trong phần README.md
ở trên.
Chúng tôi từng 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 chúng tôi đang nỗ lực để di chuyển các quy tắc còn lại ra khỏi đó.