Open-source project
golang/build avatar
golang/build

golang/build, the machinery behind Go's own releases

[mirror] Go's continuous build and release infrastructure (no stability promises)

744 stars174 forksGoBSD-3-Clause

At a glance

What is it?
golang/build holds the source for the packages and tools that support Go's build system: a coordinator that allocates machines and runs builds, a buildlet agent on every worker, a maintenance daemon that watches GitHub and Gerrit, and the environment scripts that produce the images. The repository carries an explicit warning that its contents may change or disappear without notice.
Who is it for?
Adopt golang/build only if you are working on Go's own toolchain or on infrastructure of the same shape, because the repository says plainly that its packages are internal to Go's build system and may change or disappear. Skip it for ordinary Go development, since the standard toolchain already gives you cross-compilation and the module proxy.
Can I use it commercially?
Yes. BSD-3-Clause is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Yes. The repository received new commits within the last day.
What is it written in?
Mainly Go, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.

Editorial analysis

The compatibility warning that governs everything

This repository holds the source for various packages and tools that support Go's build system and the development of the Go programming language, and it comes with a warning that is unusual to see at the top of a Go repository.

The README says the packages here are internal to Go's build system and its needs, and that some may one day be promoted to another golang.org/x repository, or they may be modified arbitrarily or even disappear altogether. In short, code in this repository is not subject to the Go 1 compatibility promise nor the release policy.

That is a stronger statement than the usual experimental warning. The usual says the API may change; this says a package may be deleted. It is the right warning for the content, because build infrastructure is internal to a release process, and the Go team is explicit that it is not a general purpose build system.

The repository is a mirror, and the canonical home is the git repository at go.googlesource.com/build, with changes going through Gerrit as the README explains. The main issue tracker is at go.dev/issues, with the convention that you prefix your issue with x/build/DIR: in the subject line, where DIR is the directory in the repository.

The package reference is golang.org/x/build, so the code is importable, and the licence is BSD-3-Clause with the last push on 2026-10-19.

So the practical rule is simple. Read this warning, and if your work depends on any of it, you are depending on an internal implementation that can be replaced. If you are contributing to Go's build system, it is the right place and the Gerrit workflow is the process.

The coordinator and the buildlet

The two components that do the actual work are the coordinator and the buildlet, and their relationship is the interesting part of the design.

The coordinator, in cmd/coordinator/, serves farmer.golang.org and build.golang.org. It runs on GKE and coordinates the whole build system: it finds work to do, both pre-submit TryBot work and post-submit work, executes builds, allocates machines to run them, and owns all the machines. It holds the state for which builds passed or failed, and the build logs.

The buildlet, in cmd/buildlet/, is the HTTP server that runs on each worker machine to execute builds on the coordinator's behalf. The README says it runs on every possible GOOS and GOARCH value, and that the buildlet binaries are stored on Google Cloud Storage and fetched per build, so the buildlet binary can be updated independently of the underlying machine images. That decoupling is the point: rebuilding an image for every change to the agent would be slow, and the image is the expensive artefact.

The security description is unusually blunt. The README says the buildlet is the most insecure server possible, with HTTP handlers to read and write arbitrary content to disk and to execute any file on disk, and it also has an SSH tunnel handler. The consequence stated is that the buildlet must never be exposed to the Internet.

There are three ways the coordinator provisions buildlets, and the third is the interesting one. It can create virtual machines on Google Compute Engine with custom images configured to fetch and run the buildlet on boot, listening on port 80 in a private network. It can run Linux containers, on Google Kubernetes Engine or on GCE with the Container-Optimized OS image, with container images configured the same way. And it can take buildlets out of a pool of connected, dedicated machines.

That third mode is where reverse mode comes in. The buildlet can run in listen mode, as on GCE and GKE, or in reverse mode, where the buildlet connects out to farmer.golang.org and registers itself with the coordinator. The TCP connection is then logically reversed using revdial, and when the coordinator needs a build it makes HTTP requests over the already-open connection.

Reverse mode exists because a machine in a restricted network cannot accept an inbound connection but can usually make an outbound one. The three pools are viewable at the coordinator's farmer.golang.org page.

The maintenance daemon and the environment scripts

The rest of the repository is the machinery around the builds.

maintner, in maintner/, is a library for slurping all of Go's GitHub and Gerrit state into memory. The daemon maintnerd, in cmd/maintnerd/, runs on GKE and serves maintner.golang.org, watching GitHub and Gerrit and appending to a mutation log. The point of a separate daemon is that the state is polled and cached rather than fetched per request, and the mutation log is what lets consumers of the state know what changed without re-reading everything.

The env/ directory describes build environments, and it holds scripts to create virtual machine images, Dockerfiles to create Kubernetes containers, and instructions and tools for dedicated machines. This is the part of the system that turns a definition of an environment into something that can be booted, and it is the part with the most accumulated detail, because every new operating system version and every new toolchain has to be encoded there.

There is also a buildenv/ Go package with constants for where the dashboard and coordinator run, for prod, staging and for local development. Constants for hostnames, in a package, is an unusual thing to find and it reflects how many places in the build system need to know the address of a service. Having one package for them means a change of address is a change in one place rather than a search across scripts.

The overall shape of the system is a control plane and a large, heterogeneous, disposable worker fleet, with the control plane holding all the state and the workers being cheap to replace. The three provisioning modes exist because the fleet is not homogeneous: cloud instances for scale, containers for isolation, and dedicated machines for the platforms that cannot be virtualised.

And the piece that ties it together is the coordinator's knowledge of which machine can run which target. The buildlet runs on every possible GOOS and GOARCH value, which means the coordinator is matching a build request to a worker with the right operating system and architecture, and that matching is the scheduling problem the whole design is built around.

How this compares with a conventional CI system

The comparison to make is with a hosted continuous integration service, and the difference in approach is visible in the components.

A hosted CI service gives you a fleet of workers, but they are uniform, disposable and selected by a label you configure. The work is defined by a pipeline file, the state is small, and the logs are the main artefact.

This build system has a fleet that is deliberately heterogeneous, because the thing being tested is a compiler that has to produce working binaries for every operating system and architecture Go supports, including combinations that do not exist in any cloud. A cross-compiling build needs a host with the right target toolchain and libraries, and some of those hosts are hardware that has to be physically present. The buildlet runs on every possible GOOS and GOARCH value, which is a statement about coverage rather than about convenience.

The second difference is the scale of the state. The coordinator holds which builds passed or failed and the build logs, and maintner holds the GitHub and Gerrit state in memory with a mutation log. A hosted CI service has a database of build results; this has a daemon that maintains a cached view of the entire issue and change history of the project, which is a different kind of state with different scaling characteristics.

The third difference is the trust model. The README says the buildlet is the most insecure server possible, with handlers to read and write arbitrary content and execute any file, and that it must never be exposed to the Internet. Every hosted CI worker is also untrusted code execution, but it sits inside a provider's account with the provider's controls. Here the containment is the coordinator's job, and the three provisioning modes, especially reverse mode with a dedicated machine connecting out, are how the team runs untrusted builds without giving the buildlet a public address.

For anyone building CI, the transferable ideas are the buildlet being updated independently of the machine image, the coordinator owning all state, and the reverse dial mechanism for workers behind firewalls. For anyone using Go, none of this is needed, because the standard toolchain and the module proxy already give you cross-compilation and dependency fetching. The repository is best read as a case study in how a language project releases itself, and it is published openly precisely so that it can be.

Editorial conclusion

Adopt golang/build only if you are working on Go's own toolchain or on infrastructure of the same shape, because the repository says plainly that its packages are internal to Go's build system and may change or disappear. Skip it for ordinary Go development, since the standard toolchain already gives you cross-compilation and the module proxy. Verify first by reading the compatibility warning at the top of the README, because it determines whether you can depend on any of this at all.

Frequently asked questions

What is the golang/build repository?

It holds the source for packages and tools that support Go's build system and the development of the language, including the coordinator, the buildlet worker agent, the maintner daemon and the build environment scripts. The licence is BSD-3-Clause and the canonical repository is at go.googlesource.com/build.

Can I depend on packages in golang/build?

Not safely. The README warns that the packages are internal to Go's build system, that some may be promoted elsewhere or modified arbitrarily or even disappear, and that the code is not subject to the Go 1 compatibility promise or the release policy. Contributions go through Gerrit and issues are filed at go.dev/issues with an x/build/DIR prefix.

What does the coordinator do in the Go build system?

It serves farmer.golang.org and build.golang.org, runs on GKE, finds work to do including pre-submit TryBot and post-submit work, executes builds, allocates the machines, owns them, and holds the state for which builds passed or failed along with the build logs.

What is the buildlet and why is it a security concern?

It is the HTTP server that runs on each worker machine to execute builds on the coordinator's behalf, running on every possible GOOS and GOARCH value and fetched per build from Google Cloud Storage so it can be updated independently of the machine images. The README calls it the most insecure server possible, with handlers to read and write arbitrary content to disk and execute any file, so it must never be exposed to the Internet.

What is reverse mode in the Go buildlet?

Instead of listening for connections, the buildlet connects out to farmer.golang.org and registers itself with the coordinator, and the TCP connection is logically reversed using revdial so the coordinator can make HTTP requests over the already-open connection. It exists so that buildlets in restricted networks can still be used. The three provisioning modes are VMs on GCE, containers on GKE or GCE, and dedicated machines from a pool.

Official sources

  1. golang/build on GitHub
  2. Issues
  3. License: BSD-3-Clause
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/golang-build.svg)](https://hysenlabs.com/projects/golang-build)

Was this useful?