Example Bazel Monorepo
Note: Currently supporting the latest Bazel version as at mid April 2020, 3.0.0
Example Bazel-ified monorepo, supporting Golang, Java, Python, Scala, and Typescript. Ruby and Rust support is in-progress .
I use this project to explore how Bazel works with different languages and developer tools, and keep a record of best-practices I've learnt. So it is a work in progress. Others can use it to check out the Bazel way of doing things and use parts as a reference implementation.
Rather than the typical To-Do list, this project's code uses the contrived scenario of a book shop and reading cataloging website, called Antilibrary.
Getting Started
Prerequisites:
-
Install Bazel (Currently supporting ~=
3.0.0
) - Python 3.6
-
yarn
ornpm
for the NodeJS and Typescript code -
rustc
,cargo
, andrustup
for the Rust code.
Bazel aims to be 'build anything, anywhere' system, so building and testing should be as simple as bazel test //...
. If it's not, create an issue.
Why use a Monorepo?
The following few articles together provide a good overview of the motivations behind maintaining a Monorepo. For heaps more information, korfuri/awesome-monorepo is a good place to go.
- Why Google Stores Billions of Lines in a Single Repository
- Monorepos, please do!, by Adam Jacob, former CTO of Chef
- Advantages of Monorepos, by Dan Luu
Project Structure
Golang Support
There's Golang code in /cli
. It implements a simple CLI for the common 'Blind Date With a
Dependency Management
Third-party dependencies are managed in 3rdparty/go_workspace.bzl
.
Java Support
There's a Spring Boot (with PostGres) application in /store-api
and some other Java code in /store/layoutsolver
.
Dependency Management
Its third-party dependencies are managed by rules_jvm_external
in the WORKSPACE
(See the # JAVA SUPPORT
section).
Ruby Support
⚠️ Note:rules_ruby
is, as of January 2020, actively developed but not yet production ready.
There's Ruby code contained in ruby
.
Dependency Management
Third-party Ruby dependencies are managed by rules_ruby
, which accepts a Gemfile
, located at tools/dependencies/Gemfile
.
A way to easily update (and re-lock) the Gemfile
is coming soon.
Rust Support
There's 'hello world' code contained in rust/hello_world
.
Dependency Management
Its third-party dependencies are managed by google/cargo-raze
. The usage of that tool is wrapped up in a script
as tools/update_rust_dependencies.sh
.
To use it, you update the Cargo.toml
file in 3rdparty/cargo
and then run the script.
Scala Support
There's Scala code contained in scala-book-sorting
.
Dependency Management
Its third-party dependencies are managed
by johnynek/bazel-deps
. The usage of that tool is wrapped up in a script
as tools/update_jvm_dependencies.sh
.
To use it, you update tools/dependencies/jvm_dependencies.yaml
and then run the script.
Python Support
There's Python code in the /book_sorting
and /scraping
.
bazelbuild/rules_python
is used for the core py_*
rules.
Dependency Management
⚠️ Note:rules_python
is currently designated as "ALPHA" software. The UX of managing third-party dependencies is pretty bad. For managing third-party dependencies this project uses https://github.com/dillon-giacoppo/rules_python_external, which I'd recommend you try.
In order to add new third-party packages for Python, add them to tools/dependencies/python_requirements.txt
.
Gradual Type-Checking (MyPy)
thundergolfer/bazel-mypy-integration is used to check any type annotations at bazel build
time.
Development
Continuous Integration (CI)
This repository's CI is managed by Buildkite, the CI platform used by Pinterest and Canva to manage Bazel monorepos, as well as being used by the Bazel open-source project itself.
Build Observability Analysis
This project is using Buildbuddy.IO. Every build run locally or in CI get its own https://app.buildbuddy.io/invocation/xyz123...
URL which analyses and records the build's information.
Linting
./tools/linting/lint.sh
will lint all source-code in the repo and all Bazel files.