Triển khai quy tắc

Báo cáo sự cố Xem nguồn

Trang này dành cho người viết quy tắc có ý định cung cấp quy tắc của họ cho những người khác.

Bạn nên bắt đầu một tập hợp 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 và bao gồm việc tạo tài liệu API và thiết lập quy trình CI/CD để việc phân phối tập hợp quy tắc trở nên đơn giản.

Quy tắc lưu trữ và đặt tên

Các quy tắc mới sẽ được chuyển vào kho lưu trữ GitHub riêng trong tổ chức của bạn. Hãy bắt đầu một luồng 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 ví dụ trên GitHub. Để đảm bảo tính nhất quán, bạn nên dùng định dạng này khi xuất bản các quy tắc của Bazel.

Hãy nhớ dùng nội dung mô tả mang tính mô tả về kho lưu trữ GitHub và tiêu đề README.md, ví dụ:

  • Tên kho lưu trữ: bazelbuild/rules_go
  • Mô tả kho lưu trữ: Quy tắc Go cho Bazel
  • Thẻ kho lưu trữ: golang, bazel
  • Tiêu đề README.md: Sử dụng các quy tắc cho Bazel (lưu ý rằng đườ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 nơi)

Các quy tắc có thể được nhóm 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ữ mockascript (giả định), 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

KHÔNG GIAN LÀM VIỆC

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 các quy tắc của bạn thuộc về tổ chức bazelbuild, bạn phải dùng rules_<lang> (chẳng hạn như rules_mockascript). Nếu không, bạn nên đặt tên cho 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 cho rằng các quy tắc của mình phải tuân theo quy ước cho các quy tắc trong tổ chức bazelbuild.

Trong các phần sau, giả sử kho lưu trữ thuộc về tổ chức bazelbuild.

workspace(name = "rules_mockascript")

README

Ở cấp cao nhất, nên có một README chứa (ít nhất) những gì 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. 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 giúp 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, quy tắc 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 các quy tắc của bạn phụ thuộc vào các quy tắc của kho lưu trữ khác, hãy chỉ định điều đó trong tài liệu về quy tắc (ví dụ: xem các quy tắc của Skydoc phụ thuộc vào các quy tắc Sass) và cung cấp một macro WORKSPACE sẽ tải xuống tất cả các phần phụ thuộc (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 (đồng thời đưa vào 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 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ì bạn có thể cần xác định các constraint_setting và/hoặc constraint_value tuỳ chỉnh. Đặt các hàm này vào 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 trang 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 việc đóng góp các quy tắc ràng buộc ở đó nếu chúng không phụ thuộc vào ngôn ngữ. Hãy lưu ý đến việc đư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 các tệp BUILD (ví dụ: sử dụng các lựa chọn). Với các điều kiện 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 Runfiles

Nếu quy tắc của bạn cung cấp một thư viện chuẩn để truy cập vào các tệp runfile, thì thư viện đó phải ở dạng đích thư viện 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 chúng 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. Để việc tuỳ thuộc vào quy tắc trở nên đơn giản hơn, vui lòng cung cấp macro WORKSPACE để khai báo các phần phụ thuộc trên các phần phụ thuộc bên ngoài đó. Không khai báo các phần phụ thuộc của kiểm thử ở đó, chỉ những phần phụ thuộc mà quy tắc cần để 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 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 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 macro trước đó và kiểm soát các phần phụ thuộc theo cách thủ công, trong khi vẫn được phép đăng ký chuỗi công cụ.

Do đó, hãy thêm macro WORKSPACE có tên rules_<LANG>_toolchains vào tệp <LANG>/repositories.bzl.

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 đã được đăng ký. Bazel không cần phân tích mọi 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 các phép tính phức tạp trong kho lưu trữ, hãy cân nhắc chia kho lưu trữ có các mục tiêu toolchain khỏi kho lưu trữ có mục tiêu <LANG>_toolchain. Mã cũ sẽ luôn được tìm nạp và mã thứ hai sẽ chỉ được tìm nạp khi người dùng thực sự cần xây dựng mã <LANG>.

Đ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 và dán vào tệp WORKSPACE. Nhìn 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()

Kiểm thử

Bạn nên kiểm thử để xác minh rằng các quy tắc đang hoạt động như dự kiến. Thư mục này có thể nằm ở vị trí chuẩn cho ngôn ngữ của các quy tắc hoặc trong thư mục tests/ ở cấp cao nhất.

Ví dụ (không bắt buộc)

Người dùng nên có một thư mục examples/ cung cấp cho người dùng một số cách cơ bản để sử dụng các quy tắc.

CI/CD (Chỉ số đo lường mức độ hài lòng của khách hàng)

Nhiều tập hợp quy tắc sử dụng Hành động trên GitHub. Xem cấu hình dùng trong kho lưu trữ Rules-template (mẫu quy tắc). Cấu hình này được đơn giản hoá bằng cách sử dụng "quy trình làm việc có thể tái sử dụng" được lưu trữ trong tổ chức bazel-contrib. ci.yaml chạy kiểm thử trên mỗi PR và main comit, 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ữ mẫu quy tắc để 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 nhận xét các quy tắc để có thể tự động tạo tài liệu.

Tài liệu/ thư mục mẫu quy tắc 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êm được 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 của Bazel nhiều nhất có thể. Rõ ràng hơn người sở hữu từng quy tắc, giúp giảm tải cho nhà phát triển Bazel. Đối với người dùng, việc tách riêng sẽ giúp họ 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 vào 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 gửi quyền truy cập 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 quy tắc vào tệp WORKSPACE, 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òn một vài quy tắc ở đó, nhưng chúng tôi đang nỗ lực chuyển các quy tắc còn lại ra.