Saving the (Production) Environment
Using Bazel to create different environments, and then ensure that targets only build with the correct environment.
Join the DZone community and get the full member experience.Join For Free
You can create different environments (e.g., testing, prod, mobile, rainforest) with Bazel, then use them to make sure that targets only build with the right environment. This is a cool feature that’s undocumented (because it’s still in development, shhhhh, don’t tell anyone I told you about it).
Let’s say you have a prod SSH key that you don’t want used in development or test builds. You could restrict it to only be used in prod builds by defining the following:
environment(name = "dev") environment(name = "prod") environment(name = "testing") environment_group( name = "buildenv", defaults = ["dev"], environments = [ "dev", "prod", "testing", ], ) filegroup( name = "ssh-key", restricted_to = [":prod"], srcs = ["key"], )
Now whenever we use
:ssh-key, it has to be in a
For example, this works:
cc_binary( name = "prod-job", srcs = ["job.cc"], restricted_to = [":prod"], data = ["ssh-key"], )
cc_test( name = "job-test", srcs = ["job_test.cc"], data = [":ssh-key"], )
Building the second one gives:
$ bazel build :job-test ERROR: /Users/kchodorow/test/a/BUILD:34:1: in cc_test rule //:job-test: dependency //:ssh-key doesn't support expected environment: //:dev. ERROR: Analysis of target '//:job-test' failed; build aborted. INFO: Elapsed time: 0.167s
Hopefully, if someone tried to add
restricted_to = [":prod"] to a test, it’d “look wrong” and be easier to catch.
Note that you must set your defaults sanely. When I first tried this, I made the
defaults = ["prod"] and then was confused that I wasn’t getting any errors. Everything is built for the default environments unless specified otherwise!
This lets us say:
bis restricted to a certain environment, then
amust be restricted to the environment.”
However, there is another direction to look at this from: if
a is restricted to an environment,
b must be compatible with that environment. To express this, you can use "
filegroup( name = "dev-key", srcs = ["key.dev"], compatible_with = [ ":dev", ":testing" ], )
Now anything that’s restricted to “:dev” or “:testing” environments can depend on “:dev-key”. For example, these work:
cc_binary( name = "dev-job", srcs = ["job.cc"], data = [":dev-key"], ) cc_test( name = "job-test", srcs = ["job_test.cc"], restricted_to = [":testing"], data = [":dev-key"], )
This does not:
cc_binary( name = "prod-job", srcs = ["job.cc"], restricted_to = [":prod"], data = [":dev-key"], )
The full matrix (assuming
env is an environment) is:
✓ ✗ ✓
✗ ✓ ✓
✗ ✗ ✓
Remember that environments are targets themselves, so avoid proliferating environments that aren’t global to the global scope (don’t make them publicly visible and keep them as private as possible).
Published at DZone with permission of Kristina Chodorow, DZone MVB. See the original article here.
Opinions expressed by DZone contributors are their own.