| --- | |
| title: 'Deploying Rules' | |
| --- | |
| This page is for rule writers who are planning to make their rules available | |
| to others. | |
| ## Hosting and naming rules | |
| New rules should go into their own GitHub repository under your organization. | |
| Contact the [bazel-dev mailing list](https://groups.google.com/forum/#!forum/bazel-dev) | |
| 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 must 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) or platform | |
| (such as Android). | |
| ## 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 | |
| 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 | |
| In the project's `WORKSPACE`, 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_<lang>` (such as `rules_mockascript`). Otherwise, you should name your | |
| repository `<org>_rules_<lang>` (such as `build_stack_rules_proto`). Please contact | |
| [bazel-dev mailing list](https://groups.google.com/forum/#!forum/bazel-dev) | |
| 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. | |
| ``` | |
| workspace(name = "rules_mockascript") | |
| ``` | |
| ### README | |
| At the top level, there should be a `README` that contains (at least) what | |
| users will need to copy-paste into their `WORKSPACE` file to use your rule. | |
| In general, this will be a `http_archive` pointing to your GitHub release and | |
| a macro call that downloads/configures any tools your rule needs. For example, | |
| for the [Go | |
| rules](https://github.com/bazelbuild/rules_go#setup), this | |
| looks like: | |
| ``` | |
| 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() | |
| ``` | |
| If your rules depend on another repository's rules, specify that in the | |
| rules documentation (for example, see the | |
| [Skydoc rules](https://skydoc.bazel.build/docs/getting_started_stardoc.html), | |
| which depend on the Sass rules), and provide a `WORKSPACE` | |
| macro that will download all dependencies (see `rules_go` above). | |
| ### 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](/versions/6.4.0/docs/toolchains) rules, | |
| it's possible that you'll need to define custom `constraint_setting`s and/or | |
| `constraint_value`s. Put these into a `//<LANG>/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](/versions/6.4.0/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 `//<LANG>/runfiles` (an abbreviation | |
| of `//<LANG>/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. To make depending on your rules | |
| simpler, please provide a `WORKSPACE` macro that will declare dependencies on | |
| those external dependencies. Do not declare dependencies of tests there, only | |
| dependencies that rules require to work. Put development dependencies into the | |
| `WORKSPACE` file. | |
| Create a file named `<LANG>/repositories.bzl` and provide a single entry point | |
| macro named `rules_<LANG>_dependencies`. Our directory will look as follows: | |
| ``` | |
| / | |
| mockascript/ | |
| constraints/ | |
| BUILD | |
| BUILD | |
| defs.bzl | |
| repositories.bzl | |
| ``` | |
| #### Registering toolchains | |
| Your rules might also register toolchains. Please provide a separate `WORKSPACE` | |
| macro that registers these toolchains. This way users can decide to omit the | |
| previous macro and control dependencies manually, while still being allowed to | |
| register toolchains. | |
| Therefore add a `WORKSPACE` macro named `rules_<LANG>_toolchains` into | |
| `<LANG>/repositories.bzl` 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 `<LANG>_toolchain` targets. Former will be always fetched, and | |
| the latter will only be fetched when user actually needs to build `<LANG>` code. | |
| #### Release snippet | |
| In your release announcement provide a snippet that your users can copy-paste | |
| into their `WORKSPACE` file. This snippet in general will look as follows: | |
| ``` | |
| 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() | |
| ``` | |
| ### 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. | |
| ## Testing | |
| Set up Travis as described in their [getting started | |
| docs](https://docs.travis-ci.com/user/getting-started/). Then add a | |
| `.travis.yml` file to your repository with the following content: | |
| ``` | |
| dist: xenial # Ubuntu 16.04 | |
| # On trusty (or later) images, the Bazel apt repository can be used. | |
| addons: | |
| apt: | |
| sources: | |
| - sourceline: 'deb [arch=amd64] http://storage.googleapis.com/bazel-apt stable jdk1.8' | |
| key_url: 'https://bazel.build/bazel-release.pub.gpg' | |
| packages: | |
| - bazel | |
| script: | |
| - bazel build //... | |
| - bazel test //... | |
| ``` | |
| 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%5D&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. | |
| ## 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 copy-paste a rule into their `WORKSPACE` file, as shown in the | |
| `README.md` section above. | |
| 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. |