An experiment in using Bazel.build to build a multi language monorepo.
The build system is BAZEL
To look at some other grate bazel build examples checkout the aspect build bazel examples
The folioing programming language are built int in this monorepo.
- python (PENDING)
- Typescript
Assuming you are running on a Mac
brew install pnpm
brew install bazelisk
pnpm add -g yardman
Visualize your build
If you plan to Visualize your build, then you will also need graphviz
brew install graphviz
To make all the packages available in the editors for code completion run this
pnpm install
To update the aspect presets run
bazel run //.aspect/bazelrc:update_aspect_bazelrc_presets
bazel query //...
bazel query '...'
bazel query 'attr(visibility, "//visibility:public", //packages/npm/one:*)'
Collect the graph for app-1
bazel query 'deps(//app-1:app-1)' --output graph > graph.in
Generate a PNG of the collected graph
dot -Tpng < graph.in > graph.png
bazel query --noimplicit_deps 'deps(//app-1:app-1)' --output graph > simplified_graph.in
dot -Tpng < simplified_graph.in > simplified_graph.png
Interactive view of the graph
xdot <(bazel query --notool_deps --noimplicit_deps "deps(//app-1:app-1)" --output graph)
The Docker containers build in the repo do not have sh or bash so you can´t shell into them to inspect them so you have to use other methods to inspect them
docker create --name="tmp_$$" bazel/app-1:image
# List the fils int container
docker export tmp_$$ | tar t
docker rm tmp_$$
The image to a tar file that can be opend up and inspected.
docker create --name="tmp_$$" bazel/app-1:image
# Exports the image to a tar file
docker export tmp_$$ > tar.tar
docker rm tmp_$$
The sizes are: small, medium, large, enormous
bazel test '//...' --test_size_filters=small
bazel test '//...' --test_size_filters=medium
Using test containers
Testcontainers is a library that supports tests for multiple language (Java, Node.js, Python and more) this library is a wrapper around working with Docker containers in tests.
See the Node.js quick start guide for more information.
All bazel integration test could use this mechanism to run there integration tests and then Bazel can run the integration tests like any other unit test.
But all build agents would need to have docker and the docker images would need to be build need to be build and run before the tests start.
One way to run integration tests using infrastucture like PostgreSQL is to to roll your own like the do at Dataform acording to this post "How to run services for integration tests with Bazel (ActiveMQ, PostgreSQL, MySQL)" on reddit.
Dataform start a new PostgreSQL server inside a docker container in the beginning of the first test using this fixture. The docker image they start is built in the BUILD file.
Then when the tests are finished they shut down the server.
Building python apps in Bazel requires us to have pined version of dependencies and Bazel is doing that using the pip-compile command from pip-tools. This requires the developer to have pip-tools installed when adding or updating dependencies and or there version. Instead of editing the requirements.txt directly, instead edit the requirements.in and then run pip-compile that generates the requirements.txt with pinned dependencies.
This repository has .python-version
file in the project root that configures
what virtualenv pyenv uses. This is a nice way to install the python
dependencies into an isolated environment so that are available to the IDEs like
VScode and vim to provide code completion.
To create the virtual even for this repository run this command:
pyenv virtualenv 3.10.8 monorepo
Then you can install all the dependencies to the virtual even by running this command:
pip install -r requirements.txt