🗃 Caching Go Binaries

Posted on Jul 29, 2023

I shipped gobincache this past week, after learning about the debug/buildinfo package & getting annoyed at having to wait around for my builds to install some Go binaries!

It reads the version of the module which the binary was built against & the version of that module in your go.mod file and lets you know whether they’ve drifted. So you can only go install when you need to and cache those binaries without needing to worry too much about drift (just make sure your cache key in CI is also reasonable, based on Go version, architecture, etc.).

It’s sped up my builds by ~3 minutes, which is just that much better. 🚀

This assumes that you’re using a tools.go approach to getting those binaries’ versions to be managed by the Go toolchain via your go.mod (i.e. you’re running go install w/o specifying an explicit version)!

For example, you might want to have the golangci-lint binary available:

// file: tools.go
//go:build tools

package tools

import (
	_ "github.com/golangci/golangci-lint/cmd/golangci-lint"

Which would then mean you have a line like this in your go.mod:

// file: go.mod
module mypkg

go 1.20

require (
	// (...)
	github.com/golangci/golangci-lint v1.53.3
	// (...)

Which would let you run something like this to install that binary:

$ GOBIN="${PWD}/bin" go install github.com/golangci/golangci-lint/cmd/golangci-lint