Skip to main content

Continuous Integration and Delivery

We expect Bazel to give us a fast red/green signal for Pull Requests, and deliver artifacts from the main branch.

By the end of this section, you'll have run a PR with your changes against a simple GitHub Actions CI.

Bazel enables Continuous Integration

Most teams who say they have a "CI" are not actually integrating the stack, rather they just have a "continuous build" running their unit tests.

"Integration" ought to mean that we write a test that builds all the components from HEAD, even across languages and frameworks.

Any time the application fails to ship because of a defect only reproducible after everything has been merged, and you have rollbacks and missed delivery deadlines, it's an indication there wasn't true CI.

Example: plain GitHub Actions

The Bazel Rules Authors SIG maintains a shared Action that can setup Bazel: https://github.com/bazel-contrib/setup-bazel

You can see this in action in the bazel-examples repository:

https://github.com/aspect-build/bazel-examples/blob/main/.github/workflows/ci.yaml

Exercise: get a CI status

Try making some edits in the bazel-examples repository.

Now you want to get a status from a remote service:

  1. Create a fork on GitHub
  2. Push your code to a branch
  3. Create a Pull Request. You can make it a Draft, and close it after you're done experimenting.

Because we already have a basic working setup in .github/workflows/ci.yaml, you should get a yellow status icon, with a pending CI run.

Approaches: shared green vs. pipeline-per-project

In a giant repository like Google, there is no snapshot of version control where everything is green. (google3 doesn't even have parse-able Starlark code at a given "commit").

However, there is a lot of extra machinery needed to deal with different teams selecting some "view" over the monorepo that they care about, compute the status for that view, prevent code changes that break it, and determine what is safe to ship.

Moreover, if each team has a different status, then each team needs their own "build cop" which is a drain on them, and if they aren't diligent then existing redness also impacts shared library authors when they trigger that pipeline.

The best answer is to keep it simple: the entire repository is green, or it's not. A single BuildCop can maintain this state across a large repository, provided that you're quick to revert breakages. Have a policy that makes it clear that the revert happens without judgement, and the roll-forward follows the normal process.

Versioning

You can allow engineers to tag the repository if you ship semantic-versioned libraries for use outside the org. Otherwise you're better off with a monorepo version like the following:

Version: 2023.07.123+abc1234

Read as:
[year].[week of year].[# commits so far that week]+[git SHA]

Stamping

Bazel has a facility for adding version control info to binaries. It's a little inconsistent across rules, but there's always a way to do it.

Only stamp when you're delivering. Stamped artifacts are non-deterministic and will cause cache misses.

Selective delivery

What should we deliver from a green build? We recommend delivering artifacts that have changed.