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.

Exercise: get a CI status

There's some non-functional code in /tests/ Try adding some code there that actually exercises the application you have working in the language you chose, or checkout the final branch which has all four languages working, and write your test there.

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

  1. Create a fork on GitHub
  2. Push your code to a branch

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 parseable 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 repo 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.


You can allow engineers to tag the repository if you ship semver 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]


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.


  1. Fork the codelabs repository to your own personal GitHub account.
  2. Make a code change in any of the applications.
  3. Send a pull request to your repository, or just push a commit, and watch CI run.