部署规则

此页面适用于计划向他人提供规则的规则编写者 。

我们建议您从模板代码库: https://github.com/bazel-contrib/rules-template 开始创建新的规则集。该模板遵循以下建议,并包含 API 文档生成功能, 还设置了 CI/CD 流水线,以便轻松分发规则集。

托管和命名规则

新规则应放入您组织下的专用 GitHub 代码库中。 如果您认为自己的规则应放入 bazelbuild 组织中,请在 GitHub 上发起讨论串。

Bazel 规则的代码库名称采用以下标准化格式: $ORGANIZATION/rules_$NAME. 请参阅 GitHub 上的 示例。 为保持一致性,您在发布 Bazel 规则时应遵循此格式。

请务必使用描述性 GitHub 代码库说明和 README.md 标题,例如:

  • 代码库名称:bazelbuild/rules_go
  • 代码库说明:适用于 Bazel 的 Go 规则
  • 代码库标记:golangbazel
  • README.md 标头:适用于 Bazel 的 Go 规则 (请注意指向 https://bazel.build 的链接,该链接会将不熟悉 Bazel 的用户引导至正确的位置)

规则可以按语言(例如 Scala)、运行时平台 (例如 Android)或框架(例如 Spring)进行分组。

代码库内容

每个规则代码库都应具有一定的布局,以便用户快速 了解新规则。

例如,在为(虚构的) mockascript 语言编写新规则时,规则代码库将具有以下结构:

/
  LICENSE
  README
  MODULE.bazel
  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

MODULE.bazel

在项目的 MODULE.bazel 中,您应定义用户将用于 引用规则的名称。如果您的规则属于 bazelbuild 组织,则必须使用 rules_<lang>(例如 rules_mockascript)。否则,您应将 代码库命名为 <org>_rules_<lang>(例如 build_stack_rules_proto)。如果您认为自己的规则应遵循 bazelbuild 组织中规则的惯例,请在 GitHub 上发起讨论串。

在以下部分中,假设代码库属于 bazelbuild 组织。

module(name = "rules_mockascript")

README

在顶层,应有一个 README,其中包含规则集的简要说明 以及 API 用户应预期的内容。

规则

您的代码库通常会提供多条规则。创建一个以语言命名的目录,并提供一个入口点 - defs.bzl 文件 导出所有规则(还包括一个 BUILD 文件,以便该目录成为软件包)。 对于 rules_mockascript,这意味着将有一个名为 mockascript的目录,以及一个 BUILD 文件和一个 defs.bzl 文件:

/
  mockascript/
    BUILD
    defs.bzl

限制条件

如果您的规则定义了 工具链规则, 则可能需要定义自定义 constraint_setting 和/或 constraint_value。将这些内容放入 //<LANG>/constraints 软件包中。您的 目录结构将如下所示:

/
  mockascript/
    constraints/
      BUILD
    BUILD
    defs.bzl

请参阅 github.com/bazelbuild/platforms ,了解最佳实践,查看已有的限制条件,并 考虑在此处贡献您的限制条件(如果它们与语言无关)。 请注意引入自定义限制条件,您的规则的所有用户都将 使用这些限制条件在其 BUILD 文件中执行特定于平台的逻辑(例如, 使用 选择器)。 借助自定义限制条件,您可以定义整个 Bazel 生态系统 将使用的语言。

Runfiles 库

如果您的规则提供用于访问 runfiles 的标准库,则该规则应采用位于 //<LANG>/runfiles 的库目标的形式(//<LANG>/runfiles:runfiles 的缩写)。需要访问其数据依赖项的用户目标通常会将此目标添加到其 deps 属性中。

代码库规则

依赖项

您的规则可能具有外部依赖项,您需要在 您的 MODULE.bazel 文件中指定这些依赖项。

注册工具链

您的规则可能还会注册工具链,您也可以在 MODULE.bazel 文件中指定这些工具链。

请注意,为了在分析阶段解析工具链,Bazel 需要 分析所有 toolchain 目标。Bazel 不需要 分析 toolchain.toolchain 属性引用的所有目标。如果为了注册工具链,您需要在代码库中执行复杂的计算,请考虑将包含 toolchain 目标的代码库与包含 <LANG>_toolchain 目标的代码库分开。前者将始终被提取,而 后者仅在用户实际需要构建 <LANG> 代码时才会被提取。

发布代码段

在发布公告中,提供一个代码段,供用户复制并粘贴 到其 MODULE.bazel 文件中。此代码段通常如下所示:

bazel_dep(name = "rules_<LANG>", version = "<VERSION>")

测试

应有测试来验证规则是否按预期运行。这 可以位于规则所针对语言的标准位置,也可以位于顶层的 tests/目录中。

示例(可选)

拥有一个 examples/ 目录对用户很有用,该目录向用户展示了使用规则的几种基本方式。

CI/CD

许多规则集都使用 GitHub Actions。请参阅 rules-template 代码库中使用的配置,这些配置使用托管在 bazel-contrib 组织中的“可重复使用的工作流”进行了简化。ci.yaml 会针对每个 PR 和 main 提交运行测试,而 release.yaml 会在您向代码库推送标记时运行。 如需了解详情,请参阅 rules-template 代码库中的注释。

如果您的代码库位于 bazelbuild 组织下, 您可以请求将其添加ci.bazel.build

文档

如需了解如何注释规则以便自动生成文档,请参阅 Stardoc 文档

rules-template docs/ folder 文件夹展示了一种简单的方法,可确保 docs/ 文件夹中的 Markdown 内容始终与 Starlark 文件更新保持同步。

常见问题解答

为什么我们无法将规则添加到主要的 Bazel GitHub 代码库?

我们希望尽可能将规则与 Bazel 版本分离。这样可以更清楚地了解谁拥有各个规则,从而减轻 Bazel 开发者的负担。对于我们的用户来说, 分离可以更轻松地修改、升级、降级和替换规则。 贡献规则可能比贡献 Bazel 更轻松 - 具体取决于规则 -,包括对相应 GitHub 代码库的完整提交访问权限。获取对 Bazel 本身的提交访问权限是一个复杂得多的 过程。

缺点是,对于我们的用户来说,一次性安装过程更加复杂: 他们必须在其 MODULE.bazel 文件中添加对规则集的依赖项。

我们过去将所有规则都放在 Bazel 代码库中(位于 //tools/build_rules//tools/build_defs 下)。我们仍然在那里保留了一些规则 ,但我们正在努力将剩余的规则移出。