Table of Contents

DESCRIPTION

Generate reproducible Go binaries.

Use asdf to manage Go versions.

COMMANDS

Version Metadata

Executables generated by the Go compiler can be byte for byte reproduced using metadata embedded in the binary. The metadata includes whether the version control has any local changes:

$ git clone https://github.com/msantos/goreap

$ cd goreap/cmd/goreap

$ git checkout 300f4137a4d9f90c4b41c7997e76a4a15bead740

$ CGO_ENABLED=0 go build -trimpath -ldflags "-s -w"

$ go version -m goreap
goreap: go1.18.1
        path    github.com/msantos/goreap/cmd/goreap
        mod     github.com/msantos/goreap       (devel)
        dep     golang.org/x/sys        v0.0.0-20210113181707-4bcb84eeeb78      h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY=
        build   -compiler=gc
        build   -ldflags="-s -w"
        build   CGO_ENABLED=0
        build   GOARCH=amd64
        build   GOOS=linux
        build   GOAMD64=v1
        build   vcs=git
        build   vcs.revision=300f4137a4d9f90c4b41c7997e76a4a15bead740
        build   vcs.time=2022-04-17T12:29:28Z
        build   vcs.modified=false

$ sha256sum goreap
06780f56efac35dba2ff9ae105b94e97582e6164dc59abf8219c4fb24f11c27a  goreap

Unmanaged files in the git repository change the build metadata and the binary checksum:

$ touch foo

$ git status
...
Untracked files:
        foo

$ CGO_ENABLED=0 go build -trimpath -ldflags "-s -w"

$ go version -m goreap
goreap: go1.18.1
        path    github.com/msantos/goreap/cmd/goreap
        mod     github.com/msantos/goreap       (devel)
        dep     golang.org/x/sys        v0.0.0-20210113181707-4bcb84eeeb78      h1:nVuTkr9L6Bq62qpUqKo/RnZCFfzDBL0bYo6w9OJUqZY=
        build   -compiler=gc
        build   -ldflags="-s -w"
        build   CGO_ENABLED=0
        build   GOARCH=amd64
        build   GOOS=linux
        build   GOAMD64=v1
        build   vcs=git
        build   vcs.revision=300f4137a4d9f90c4b41c7997e76a4a15bead740
        build   vcs.time=2022-04-17T12:29:28Z
        build   vcs.modified=true

$ sha256sum goreap
162479ba1a84fa8a88bc9b72fe1e98bf3f2da565af0bbfb627f3baa1c2cb098c  goreap

Note:

git clean -f -x -d

Compiling

CGO_ENABLED=0 go build -trimpath -ldflags "-s -w"

Versions

Ensure the same Go version is installed:

asdf plugin add go https://github.com/asdf-community/asdf-golang.git
asdf install go $(asdf latest go)

The version for a git repo can be set:

$ asdf local go 1.17.5
$ git add .tool-versions

EXAMPLES

Initialize Git Repository

$ mkdir test
$ git init
$ curl --location https://raw.githubusercontent.com/github/gitignore/main/Go.gitignore > .gitignore

Create Go Modules

$ go mod init test

main.go

package main

import (
	"fmt"
	"os"
)

func main() {
	fmt.Fprintln(os.Stderr, "test")
}

Format and Run Linters

$ go fmt ./...
$ golangci-lint run
$ golangci-lint run --enable-all

Commit Changes

$ git add .
$ git commit

Compile for arm

$ GOARCH=arm CGO_ENABLED=0 go build -trimpath -ldflags "-s -w"

Compare Hash

# asdf install go 1.17.5
$ sha256sum test
7b85cb1914f6cdf34b58de83e0e52c30fcff7e8081824988c7db1c2572b4e0c4  test

(markdown)