Skip to main content

Updates to Buildbarn deployment repo as of June 2026

· 11 min read
Oscar Falk
Oscar Falk

The example configuration for bb-deployments has been updated.

This post will give an overview of what has happened since the last update summary in November 2023, and will cover important changes since then up to 2026-06-12.

Additional Buildbarn changes can be found in the bb-deployments changelog.

Major changes

Upgrade to Bazel 9

The Buildbarn components have been upgraded to use Bazel 9.

Remove tini (Jan 29, 2026)

Buildbarn binaries will now relaunch themselves in a child process, if the PID is 1. This removes the need to run bb_runner through tini because zombie processes in containers are no longer an issue.

Generic gRPC stream forwarding (Jan 19, 2026)

The gRPC servers can now forward incoming streams of specified services. This enables passing Bazel's build event stream to the same DNS name, without having to add an extra L7 router in front of the bb_storage frontend.

grpcServers: [{
...
relays: [
{
endpoint: {
address: 'localhost:1234',
},
services: [
'build.bazel.remote.execution.v2.Execution',
'com.google.devtools.build.v1.PublishBuildEvent',
],
},
],
}],

OAuth Client credentials for HTTP clients (Sep 26, 2025)

Buildbarn's HTTP client now supports OAuth Client Credential flow.

WinFSP virtual file system implementation (Aug 20, 2025)

An implementation of WinFSP VFS has been added, enabling bb_worker to succesfully execute Bazel builds with virtualised file inputs on Windows. See the commit message for more details.

Allow files to be read by JMESPath Expressions (Aug 11, 2025)

Buildbarn has expanded the configuration of JMESPath expressions. Instead of only specifying a string, an optional set of files can be included, whose contents will be available for the expression using the files field. The contents of the file refreshes every 60 seconds. The struct also includes optional test vectors, each test consisting of an input and expected output. The program fails to start if the expression does not produce the expected output from the input.

addMetadataJmespathExpression: {
expression: |||
{
"authorization": [std.format('bearer %s', files.token)]
}
|||,
files: [
{
key: "token",
path: "/tokens/buildbarn",
},
],
},

ZSTD compression

Support has been added for in-transit ZSTD compression in the gRPC ByteStream layer (Jul 15, 2025), used by the CAS. This feature is a pre-requisite for supporting compressed bb_clientd. A pool of decoders and encoders can be configured with an optional upper bound of instances (Mar 12, 2026). See this commit for the gRPC client side configuration (Mar 2, 2026).

Sharding algorithm changes (Apr 8, 2025)

The previous sharding algorithm has been replaced with Rendezvous hashing, making resharding less disruptive. This change is not backwards compatible. See Buildbarn ADR #11 for more details.

Remote authentication and authorization (Feb 20, 2025)

HTTP and gRPC servers can now forward authentication and authorization requests to a remote service. The results are cached for a short while to reduce the load on the remote service.

NFSv4 changes

NFSv4.1 for bb_worker is now supported (Jul 9, 2024) in addition to NFSv4.0. The versions have some substantial protocol differences, as described in the commit message.

NFSv4 has been extended to support named attributes, see the related PR (Oct 5, 2025) for more details.

Permit predeclaring multiple size class queues (Jun 4, 2024)

Predeclared platform queue size classes are now defined by an array of size classes, previously configured by setting the maximum size class. This allows all workers for all sizes to be autoscaled down to zero. When using multiple size classes, the lowest cannot be zero.

{
...
predeclaredPlatformQueues: [
{
instanceNamePrefix: 'testingQueue',
sizeClasses: [1, 2, 3, 4, 5, 6, 7],
},
{
sizeClasses: [1, 2, 3, 4, 5, 6, 7],
},
],
...
}

// If the user does not care about multiple size classes:
{
...
predeclaredPlatformQueues: [
{
sizeClasses: [0],
},
],
}

macOS mount configuration changes

The support for FUSE mounts on macOS has been removed (Mar 3, 2024) due to OSXFUSE/macFUSE being unstable. macOS users are recommended to instead use NFSv4. However the NFSv4 support for macOS 14 and older has been dropped (May 7, 2026) as macOS 15 has been out for some time.

Add support for uploading output directories as Directory messages (Dec 22, 2023)

REv2 has added the ability to upload output directories as multiple Directory messages instead of a single Tree object, if requested by the client. bb_worker has added support for this feature, and can also force upload Directory messages to the CAS in addition to uploading the Tree object by setting

forceUploadTreesAndDirectories: true;

in the worker configuration. Forcefully uploading Directory messages has several advantages as documented in the worker Proto file:

  • bb_browser is capable of displaying listings of individual directories contained in an output directory without needing to load the full Tree object from the CAS.

  • Root directories of output directories created through bb_clientd's Bazel Output Service feature load slightly faster, as they can be validated without processing full Tree objects.

  • Even for clients that only support output directories in the form of Tree messages, having Directory messages present means that subsequent build actions need to upload fewer objects.

The disadvantage of enabling this option is that a larger number of objects are written into the CAS.

Minor changes

Extended digest algorithm support

The list of supported digest algorithms has been extended with blake3 (Dec 31, 2025) and GITSHA1 (Jan 27, 2026)

Remote Action Router (Dec 8, 2025)

This allows the scheduler to delegate action routing decisions to a remote gRPC service.

gRPC server ALTS Authentication (Nov 7, 2025)

The gRPC server component now supports basic ATLS authentication.

Additional OIDC support

The authenticator has been extended to support PKCE (Oct 31, 2025), and user information claims can now be extracted from an ID token (May 28, 2025) instead of the user info endpoint.

Add support for execution timeout compensation via HTTP (Oct 31, 2025)

A configuration option has been added which allows bb_worker to control of the execution timeout timer via HTTP. It is configured by specifying two URLs which are polled by the worker: a "suspend URL", whose response controls whether the timeout timer is suspended, and a "resume URL" whose response controls whether to resume the timer. This feature is useful for when the worker timeout needs to be compensated for file downloads from outside the input root.

cron job for saving JWKSes to Kubernetes ConfigMap (Aug 19, 2025)

Buildbarn now includes simple program which saves JWKSes in a Kubernetes ConfigMap, which can then be made available to Buildbarn with a volume mount. The program is meant to be run periodically in the cluster.

Synchronize request authorization (Jul 27, 2025)

The scheduler can now be configured with an additional authorizer, to authorize bb_worker synchronize requests.

Add the ability to set owner user/group IDs on directories (Jun 11, 2025)

VFS and FUSE backends now support setting directory ownership. This is useful for when running repo rules as remote actions, as Bonanza will, many of which depend on having ownership.

Deadline enforcing blob access (Feb 17, 2025)

A decorator, DeadlineEnforcingBlobAccess, has been added which sets a configurable timeout duration. This sets an upper limit on the durations for bb_storage's incoming RPCs. For example, this is useful for reject writes that are taking an excessive amouint of time to complete.

Enable custom gRPC connection load balancing method (Jan 23, 2025)

The default gRPC connection load balancing policy is now configurable. This enables using the round-robin strategy. See gRPC service configuration for more information.

The recommended values from keyLocationMapMaximumGetAttempts and keyLocationMapMaximumPutAttempts have been doubled. For more information about the Key Location Map, see our blog post about the topic.

HTTP server TLS support (Jun 12, 2024)

The HTTP server configuration now supports an optional TLS configuration. This is useful when running Buildbarn without an ingress controller, for example in a bare metal environment.

Allow TLS certificate authenticator to validate URI SANs (Apr 10, 2024)

URI subject alternative names can now be matched with JMESPath expressions when validating TLS certificates.

Custom Kubernetes service endpoint connections (Feb 27, 2024)

Custom Kubernetes resolvers can be configured in the global configuration. The URL schema and Kubernetes API server is specified, whose endpoints are expanded and registered. This is useful in a bare-metal cluster with Buildbarn pods using the host network, where it can be difficult to establish network connections between components.

Delay file uploads until output files are closed (Feb 22, 2024)

Before uploading the output files, bb_worker will now wait for them to be closed, with a user-specified upper bound for the waiting duration. This prevents cases where the output files are still open for writing when they are uploaded, due to the kernel closing files asynchronously.

Add support for capturing server logs (Jan 26, 2024)

Every action now gets its own "server_logs" directory, created by bb_worker. bb_runner doesn't do anything with the directory, but a custom runner can for example use the directory to store core dumps of failed actions, which bb_worker will then include in the upload. For more information on how to configure the directory, see the commit message.

Add option to set resource limits on startup (Jan 8, 2024)

A global option has been added which calls setrlimit(2) with the configured values as arguments. The keys in the configuration correspond to the RLIMIT_* suffixes in the setrlimit resource parameter.

global: {
...
setResourceLimits: {
"NOFILE": {
softLimit: 1024,
hardLimit: 4096,
},
"CPU": {
softLimit: 2,
hardLimit: 4,
},
},
...
}

This feature was introduced because a new version of Go changed the logic for setting RLIMIT_NOFILE as part of child processes, risking build actions to run into file descriptor limits. This change can help avoid this by overriding the resource limits.

ReferenceExpandingBlobAccess CAS reference support (Dec 5, 2023)

ReferenceExpandingBlobAccess has been extended to support request forwarding to a REv2 CAS. This is useful when designing asset storage services that provide direct exposition over bytestream://.

Additional JWT support

JWKs can now optionally be read from a file (Oct 30, 2023), rather than than providing it inline in the configuration.

JWTs can now be signed with the Ed25519 algorithm (Jun 19, 2024), and JWTs signed with RSA-PSS signatures can be validated (May 7, 2026).

Rdeps and Bazel Development Dependencies

· 4 min read
Nils Wireklint
Nils Wireklint

Google test wants to build with cpp17

When reviving an old module that used to build googletest I encountered this error. Likely because I somehow lost the features setup for the code.

ERROR: /home/nils/gits/repo/rule/cc/test/BUILD.bazel:53:8: Compiling rule/cc/test/library_test.cpp failed: (Exit 1): gcc failed: error executing CppCompile command (from target //rule/cc/test:test_binary) external/+gcc+gcc_9.4.0_x86_64_linux_toolchain/usr/bin/gcc @bazel-out/k8-fastbuild/bin/rule/cc/test/_objs/test_binary/library_test.pic.o.params
Remote server execution message: Action details (uncached result): https://buildbarn.example.com/browser/blobs/sha256/historical_execute_response/68a13e98d2231c8055b662fdf84735a648d5c2b074551571b41cccdd70d98f80-1309/
In file included from external/googletest+/googletest/include/gtest/gtest-message.h:57,
from external/googletest+/googletest/include/gtest/gtest-assertion-result.h:46,
from external/googletest+/googletest/include/gtest/gtest.h:63,
from rule/cc/test/library_test.cpp:16:
external/googletest+/googletest/include/gtest/internal/gtest-port.h:273:2: error: #error C++ versions l
ess than C++17 are not supported.
273 | #error C++ versions less than C++17 are not supported.
| ^~~~~
In file included from external/googletest+/googletest/include/gtest/gtest.h:67,
from external/googletest+/googletest/src/gtest.cc:33:
external/googletest+/googletest/include/gtest/gtest-param-test.h:483:56: error: missing template argume
nts before '(' token
483 | typename StdFunction = decltype(std::function(std::declval<Func>()))>
| ^
external/googletest+/googletest/include/gtest/gtest-param-test.h:493:56: error: missing template argume
nts before '(' token
493 | typename StdFunction = decltype(std::function(std::declval<Func>()))>
| ^

While this is a run-of-the-mill error when reviving a project I wanted to take this opportunity to give rdeps and buildozer a spin. So I wouldn't have to update the BUILD files myself.

Patch googletest to use c++17 for its compilation

For this example I don't pay much attention to mixing standards in one compilation. We should seek to make 17 the default for the entire code base.

+single_version_override(
+ module_name = "googletest",
+ patch_cmds = [
+ """echo 'repo(features = ["-c++14", "c++17"])' > REPO.bazel"""
+ ],
+)

Rdeps and Buildozer

Next we must use the header, which carries the #error. So we want to update all users in our repo to use c++17 instead of c++14.

Find all targets in the code that directly depend on googletest stuff:

$ bazel query 'rdeps(//..., @googletest//..., 1) intersect //...'

Then send that to buildozer:

$ buildozer 'add features -c++14 c++17'

Rdeps does not work in the absence of dev dependencies

$ bazel query 'rdeps(//..., @googletest//..., 1) intersect //...'
Starting local Bazel server (8.5.0) and connecting to it...
ERROR: error loading package under directory '': error loading package '@@googletest+//googlemock/test': Unable to find package for @@[unknown repo 'rules_python' requested from @@googletest+]//python:defs.bzl: The repository '@@[unknown repo 'rules_python' requested from @@googletest+]' could not be resolved: No repository visible as '@rules_python' from repository '@@googletest+'.

As rules_python is a dev dependency we cannot use it from a consuming module:

$ bazel mod deps googletest
<root> (rules_vcc@_)
└───googletest@1.17.0.bcr.2
├───abseil-cpp@20240116.2
│ └───googletest@1.17.0.bcr.2 (cycle)
├───platforms@1.0.0
├───re2@2025-08-12.bcr.1
└───rules_cc@0.2.16

Patch the module file?

Will not work, as this is governed by the module file in the registry:

single_version_override(
module_name = "googletest",
patch_cmds = [
"sed -i '/dev_dependency = "True"/d' MODULE.bazel
],
)

If you have your own registry you can patch it there:

We do have our own registry in our monorepo so I can patch it there, notice that this is not a patch file that is applied to the MODULE file, but a change of the MODULE file itself.

bazel_central_registry $ sed -i '/dev_dependency = True/d' registries/bcr.bazel.build/modules/googletest/1.17.0.bcr.2/MODULE.bazel

Shut down Bazel to pick up the change

When working with your own registry one must shut down Bazel between edits for the module dependency data to be updated.

$ bazel shutdown
$ bazel query 'rdeps(//..., @googletest//..., 1) intersect //...'
//rule/cc:runfiles_helper
//rule/cc/test:test_binary
//rule/cc/test:test_cc_legacy_shared

An experimental flag to follow dev dependencies in query?

It would be great if query had a flag to follow all dev dependencies. To make queries like this possible, the cost of downloading more modules than strictly necessary for a build is warranted by enabling Bazel's powerful query system. Which otherwise sadly does not work for modules with dev dependencies.

LiTHe Kod event 2026-02-17

· One min read
Fredrik Medley
Fredrik Medley

Welcome to a joint Meroton and LiTHe Kod evening Tuesday 17 February 2026 at 17:15 in Ada Lovelace, Linköpings Universitet.

Meroton will present how to scale build systems in larger coorperations, with focus on Bazel, Buildbarn and more. After the presentation, you will have the opportunity to try these technologies yourselves.

Please register here, to make sure we have enough food, or just come by and listen.

Bazel, Buildbarn and Bonanza

· 3 min read
Benjamin Ingberg
Benjamin Ingberg

In the Buildbarn event at Snowflake this week, Ed Schouten presented the work on the Bonanza project. Bonanza is a prototype for a drop in replacement Bazel with improvements to its communication protocols and written as a client that performs all of its actions remotely, deduplicated and cacheable.

How is it different from Bazel?

Bazel is written in an interesting manner. It is designed from the ground up to represent a stable description of a build that is reproducible from any developer's machine. Any developer can check out the same source code ask Bazel to analyze it and get the exact commands Bazel would run to perform the build.

This involves a lot of computation: Resolving bazel modules, downloading repository rules, executing them, analyzing the .bzl and BUILD.bazel files, and finally executing the actions themselves.

Bazel internally represents these computation steps as pure functions returning deterministic values from a stable key, internally represented as SkyFunctions returning SkyValues from SkyKeys.

A SkyFunction should return the same SkyValue given the same SkyKey which makes it a good candidate for being computed only once and have the result cached and fed through to the next step. But peculiarly only the action execution itself has been offloaded to remote cache and execution.

cache all the things

This is what Bonanza attempts to resolve. Instead of having all of that state computed and represented locally, repeated by each developer and discarded whenever a flag changes, Bonanza is designed from the ground up to offload all computations, downloads, and analysis to a remote cacheable system. This essentially reduces the client side to a very light weight program with the primary purpose of scanning the source code for modifications and uploading any local changes.

What's the current state?

The project is still in an early state prototype state. In the presentation Ed demonstrated how far the prototype has come, and it was very impressive. The Bonanza client as of today is capable of analyzing the bb-storage codebase.

There is still a lot remaining before it's a production ready system but it is very impressive progress. Bonanza is capable of running the full bzlmod resolution, fetching all relevant repository rules from upstream, run those repository rules, and analyzing the resulting codebase, basically performing everything a Bazel cquery does, all with fully remote and cacheable manner.

For shops which lean heavily on remote caching and execution the remaining local load is often the bottleneck for your builds, the ability to offload the remaining pieces to your build cluster may be the next evolution of your build system.

Understanding the KLM

· 6 min read
Benjamin Ingberg
Benjamin Ingberg

When running a remote cache and execution cluster based on Buildbarn the Key Location Map (KLM) is a term that you will run into and it is important to take proper care when sizing the KLM and the number of KLM attempts.

If you are just looking for a ballpark number to get you started, set the number of get attempts to 16 and the number of put attempts to 64 and use the following table.

CASAC
Average Object Size125KB1KB
Storage Size500GB1GB
KLM Entries16 000 0004 000 000
KLM Size1056MB264MB

These are arbitrarily chosen values which are unlikely to match your actual workload. I recommend reading the rest of the article to understand your settings and how to reason about this. You can then use the prometheus metrics in the end to validate if your settings are a good match for your workload.

How does the KLM work?

The KLM is a hash table which describes the position in your storage layer where your desired data is written and is indexed by hashing the key of your storage data.

Given a limited key space hash functions will have collisions, it is therefore important that the KLM is significantly larger than required for fitting a key for every object. To keep the likelihood of a collision low a naive implementation would require an enourmous hash table but using a technique called Robin Hood hashing this requirement can be kept down to a small factor larger than the size of the key set requirement.

For example, in a blobstore which can fit n objects and that has a KLM which can fit 2n entries every hash would have a 50% chance of corresponding to an already occupied slot. With Robin Hood hashing we can repeat this process multiple times by incrementing an attempts counter giving us multiple possible locations for the same object.

When querying for an object we can then search up to the maximum number of allowed iterations to find our object in one of these slots. When inserting we perform a similar solution, namely incrementing the number of attempts whenever we encounter a collision but taking care to insert the younger of the colliding objects in the colliding slot and pushing the older object forward.

The number of attempts we allow the KLM to look for a free slot is described by the two parameters key_location_map_maximum_get_attempts and the key_location_map_maximum_put_attempts described by the LocalBlobAccessConfiguration.

So, how big should the KLM be?

Given a utilization rate r the chance of finding the object within k iterations is 1-r^k, we can therefore either decrease the utilization rate (by increasing the size of the KLM) or increase the number of attempts.

Due to the random access nature of the KLM the KLM greatly benefits from being small enough to fit in memory, even if the KLM itself is disk backed. Should the KLM be too big to fit in memory it will be constantly paged in and out detrimenting the system performance.

Simularly, there also needs to be a max number of iterations, in the degenerate case where the storage fits more entries than the klm is capable of inserting is full the algorithm would never terminate since every single slot would be occupied.

Having a KLM that is too small for the number of iterations used is bad.

This is somewhat mitigated by the insertion order where the oldest entries get pushed out first, since they are less likely to be relevant. This gives a graceful degradation for when your KLM is too small. You should choose a KLM so that the number of times you reach the maximum number of iterations is acceptably low.

How rare should you keep the maximum number of iterations?

It should be rare, but most objects that get discarded due to the KLM being full will tend to be old and unused. There is however a point where it is no longer meaningful to have a larger KLM.

Ultimately, any time you read or write to a disk there is a risk of failure. Popularly this is described as happening due to cosmic radiation but more realistically it is due random hardware failures from imperfections in the hardware.

Picking k and r values that gives a risk of dataloss below the Uncorrectable Bit Error Rate (UBER) of a disk is simply wasteful, should you wish to reduce the risk below this value you need to look at mirroring data.

Western Digital advertises that their Gold enterprise NVME disks has an UBER rate of 1 in 10^17, i.e. about once per 10 petabytes of read data so will serve as a decent standard.

For a random CAS object of 125KB this corresponds to a failure rate of about 1 in 10^11 reads, giving us this neat graph.

diagram

That is, for a KLM using the recommended 16 iterations giving it more than 5 entries per object in the storage is a waste since you are just as likely to fail to read the object due to disk errors as due to the KLM accidentally pushing it out.

Similarly for 32 iterations there is no point in having more than 2 entries per object, and for 8 iterations there is no point in having more than 20 entries per object.

As for number of put iterations, just keep it at 4x the number of get iterations. There is no fancy math here, it just needs to be bigger than the number of get iterations and it is very cheap since you will only put objects a miniscule fraction of the amount of times you will get objects.

The thought of data randomly getting lost might upset you spiritually, but you can comfort yourself with that you are far more likely to lose due to AWS engineer tripping on a cable in the datacenter.

How do I verify if my KLMs are properly sized?

Buildbarn exposes the behavior of the hashing strategy in it's Prometheus metrics, they are exposed in the following metrics:

  • hashing_key_location_map_get_attempts
  • hashing_key_location_map_get_too_many_attempts_total
  • hashing_key_location_map_put_iterations
  • hashing_key_location_map_put_too_many_iterations_total

These metrics exposes the required number of get and put attempts respectively as well as how many times we exceeded the maximum number of iterations, you can read the ratio between how many iterations were required to figure out how full the klm is. I.e. if you perform half as many attempts with 2 iterations as with 1 iteration this implies the klm is half full.

There are ready made Grafana dashboards which visualizes these metrics in in bb-deployments.

Introducing Meroton’s New Course: Buildbarn Fundamentals

· 2 min read
Benjamin Ingberg
Benjamin Ingberg

At Meroton, we’ve long provided managed Buildbarn environments to help development teams streamline their build processes. Now, we’re excited to take it a step further with the introduction of our latest offering: Buildbarn Fundamentals.

This new course is designed to empower your team with the knowledge and practical skills needed to manage and operate your own Buildbarn environment. Whether you're just getting started with remote build execution or looking to take control of your infrastructure, this hands-on course will provide you with the tools to succeed.

Unlock the Power of Buildbarn with Expert Guidance

Buildbarn Fundamentals is more than just a training session; it’s an opportunity to set up a production-ready Buildbarn reference cluster in your own AWS environment. By participating in the course, your team will not only understand what makes Buildbarn tick but also walk away with a fully functional Remote Build Environment (RBE) cluster, which you can continue to use or adapt to your organization’s needs.

At Meroton, we believe that mastering the management of remote build environments is crucial for modern development workflows. This course is designed to be both comprehensive and practical, offering a deep dive into Buildbarn while equipping your team with the operational knowledge to effectively maintain and scale your infrastructure.

What You'll Learn

Buildbarn Fundamentals is a hands-on course that teaches participants how to:

  • Set up a fully operational Buildbarn cluster in AWS
  • Manage and operate Buildbarn clusters independently
  • Integrate third-party tools to enhance your build environment and understand the needs of consumers
  • Optimize caching, remote execution, and troubleshooting with Buildbarn

By the end of the course, your team will have the skills and confidence to self-manage a Buildbarn environment, enabling you to scale and optimize your development processes independently.

More Information

If you're ready to empower your team with the skills to manage your own Buildbarn infrastructure, get in touch! Contact us at sales@meroton.com to learn more and secure your spot. Or read more at Buildbarn Fundamentals

Summer Buildbar

· One min read
Benjamin Ingberg
Benjamin Ingberg

Before heads out to summer adventures I'd like to invite everyone to a cool summer Buildbar. At the Buildbar we'll eat good food, talk about interesting technical problems, new developments with Bazel and Buildbarn.

And also have a few beers.

Feel welcome to come over on Wednesday 19 June 2024, from 16 to 20.

Directions

You'll find us at our Linköping offices at Fridtunagatan 33. Currently there is some ongoing construction but follow the red lines and you'll be fine.

Fridtunagatan 33 Linköping

Automatically Reformat all Commits on a Branch

· 4 min read
Nils Wireklint
Nils Wireklint

If you have a formatter tool that can rewrite your code you can run it automatically on all unmerged commits. This will show you how to script git-rebase to do so without any conflicts.

There are two ways to do it manually, forward or backward. The forward pass amends each commit and deals with the conflicts when stepping to the next commit. In contrast the backwards pass, formats each commit from the end, which will avoid conflicts but for long commit chains it can be almost as boring.

This pattern comes up when working with long-lived feature branches, or tasks that were almost done, and then pre-empted by other prioritized work. Here are a few oneliners you can run to tidy up your commits.

See also the full technical guide for developing this git-rebase workflow in our documentation. Which contains more details on rebasing with git, using a scriptable editor to automate the git-rebase todo-list, as well as the squashed commit messages.

Example commits

Say you have three unmerged commits:

21cc7b5 My amazing feature e05fd9f Other complimentary work acb9fae Fix annoying bug

They contain important work, but you forgot to run some linters, or the main branch added more lint requirements after the feature work was started. This will run linters that can automatically fix issues on each commit through a scripted git-rebase.

Rebase algorithm

We have a three-step process to update each commit.

  • 1: Create a fixup commit with the applied lint suggestions, which we immediately revert so the next commit still applies

    #!/bin/sh

    # Formatters and fixers go here.
    # Replace with your tools of choice! rustfmt, gofmt, black, ...
    ./run-all-linters-and-autofixers.sh

    # Add a new commit with the changes and revert it again.
    git add -u
    git commit --allow-empty --fixup HEAD
    # 'git-revert' does not support '--allow-empty'.
    git revert --no-commit HEAD
    git commit --allow-empty --no-edit
  • 2: Squash the fixup commit into the original feature commit

  • 3: Squash the revert down into the next feature commit

These tabs show how the commits evolve and are squashed, the extra commits are grouped to indicate the target commit. The revert of the first commit is grouped with the second feature commit, and so on. We discard the final revert.

21cc7b5 My amazing feature
01900c5 fixup! My amazing feature

55feaba Revert "fixup! My amazing feature"
e05fd9f Other complimentary work
d122da7 fixup! Other complimentary work

249b0d3 Revert "fixup! Other complimentary work"
acb9fae Fix annoying bug
50e426a fixup! Fix annoying bug

7e84259 Revert "fixup! Fix annoying bug"

Oneliners

git allows us to set any editor to edit the todo-list, $GIT_SEQUENCE_EDITOR, and the commit message, $EDITOR. We choose vim as it is often available, and easier to use than sed and awk. It is nice to have a scriptable interactive editor to make changes to the workflow and try out the commands.

See the full technical guide for details and more tips on git-rebase and vim.

Reformat:

$ env                          \
GIT_SEQUENCE_EDITOR="true" \
git rebase -i --exec ./reformat.sh origin/main

Fixup (autosquash):

# More robust autosquash, that handles duplicated commit messages.
# If your commit messages are all unique you can use '--autosquash' instead.
# See the technical guide for more details.
$ env \
GIT_SEQUENCE_EDITOR="vim +'g/^\w* \w* \(# \)\?fixup!/s/^pick/fixup/'" \
git rebase -i origin/main

Squash:

$ env                                                                                               \
EDITOR="sed -i '1,9d'" \
GIT_SEQUENCE_EDITOR="vim +'g/^#/d' +'normal! Gdk' +'g/^pick \w* \(# \)\?Revert \"fixup!/normal! j0ces'" \
git rebase -i origin/main
info

We have not developed the incantation, git-rebase command, to preserve the author date from the original commits. We will address that next!

Improved Chroot in Buildbarn

· One min read
Nils Wireklint
Nils Wireklint

We have just started a documentation series describing the Buildbarn chroot runners, and how they can be used for hermetic input roots that contain all the required tools. This includes implementation notes for a "mountat" functionality created through the new Linux mount API, how you can use this under-documented API and its shortcomings. And how this can/will be integrated into Buildbarn, with technical descriptions of the workers and runners.

The first sections are already available, with more to come!

Sections:

Reference code repository:

Updates to Buildbarn as of November 2023

· 2 min read
Benjamin Ingberg
Benjamin Ingberg

This is a continuation of the previous update article and is a high level summary of what has happened in Buildbarn from 2023-02-16 to 2023-11-14.

Added support for JWTs signed with RSA

Support for JWTs signed with RSA has been added. The following JWT signing algorithms are now supported:

  • HS256
  • HS384
  • HS512
  • RS256
  • RS384
  • RS512
  • EdDSA
  • ES256
  • ES384
  • ES512

Generalized tuneables for Linux BDI options

Linux 6.2 added a sysfs attribute for toggling BDI_CAP_STRICTLIMIT on FUSE mounts. If using the FUSE backed virtual file system on Linux 6.2 adding { "strict_limit": "0" } to linux_backing_dev_info_tunables will remove the BDI_CAP_STRICTLIMIT flag from the FUSE mount.

This may improve fileystem performance especially when running build actions which uses mmap'ed files extensively.

Add support for injecting Xcode environment variables

Remote build with macOS may call into locally installed copies of Xcode. The path to the local copy of Xcode may vary and Bazel assumes that the remote execution service is capable of processing Xcode specific environment variables.

See the proto files for details.

Add a minimum timestamp to ActionResultExpiringBlobAccess

A misbehaving worker may polluted the action cache, after fixing the misbehaving worker we would rather not throw away the entire action cache.

A minimum timestamp in ActionResultExpiringBlobAccess allows us to mark a timestamp in the past before which the action should be considered invalid.

Add authentication to HTTP servers

Much like the gRPC servers are capable of authenticated configuration the http servers can now also require authentication.

This allows the bb_browser and bb_scheduler UI to authenticate access using OAuth2 without involving any other middleware.

This also allows us to add authorization configuration for administrative tasks such as draining workers or killing of jobs.

Authentication using a JSON Web Key Set

JSON Web Key Sets (JWKS) is a standard format which allows us to specify multiple different encryption keys that may have been used to sign our JWT authentication.

Buildbarn can load the JWKS specification, either inline or as a file, when specifying trusted encryption keys.

This allows us to have rotation with overlap of encryption keys.