diff --git a/Dockerfile b/Dockerfile index b0f2d07b..2d6fb855 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,9 +27,11 @@ WORKDIR /src COPY go.mod go.sum ./ COPY vendor/ vendor/ +# `COPY . .` brings `.git` along, so Go is told not to stamp the commit: the version is said by -X, and a +# rebuild of an unchanged program is the same bytes (novox/hq ADR 0267 rule 6, issue 363). COPY . . ARG VERSION=development -RUN CGO_ENABLED=0 GOFLAGS=-mod=vendor GOPROXY=off go build -trimpath \ +RUN CGO_ENABLED=0 GOFLAGS=-mod=vendor GOPROXY=off go build -trimpath -buildvcs=false \ -ldflags "-s -w -X main.version=${VERSION}" \ -o /mesh-controller ./cmd/mesh-controller diff --git a/cmd/mesh-builder/Dockerfile b/cmd/mesh-builder/Dockerfile index 3951536d..b639b869 100644 --- a/cmd/mesh-builder/Dockerfile +++ b/cmd/mesh-builder/Dockerfile @@ -11,7 +11,7 @@ WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . -RUN CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' -o /mesh-builder ./cmd/mesh-builder +RUN CGO_ENABLED=0 go build -trimpath -buildvcs=false -ldflags '-s -w' -o /mesh-builder ./cmd/mesh-builder FROM ${ALPINE_BASE} # git to clone what it is asked to build, and the docker client to build and push it. The daemon diff --git a/examples/objectstore-provisioner/Dockerfile b/examples/objectstore-provisioner/Dockerfile index 136a5f1e..d8b2a797 100644 --- a/examples/objectstore-provisioner/Dockerfile +++ b/examples/objectstore-provisioner/Dockerfile @@ -18,7 +18,7 @@ WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . -RUN CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' \ +RUN CGO_ENABLED=0 go build -trimpath -buildvcs=false -ldflags '-s -w' \ -o /mesh-provision-objectstore ./examples/objectstore-provisioner # Pinned like everything else the mesh runs (novox/hq ADR 0006): a tag moves and a digest does not. diff --git a/examples/postgres-provisioner/Dockerfile b/examples/postgres-provisioner/Dockerfile index 585cf08b..1da90266 100644 --- a/examples/postgres-provisioner/Dockerfile +++ b/examples/postgres-provisioner/Dockerfile @@ -11,7 +11,7 @@ WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . -RUN CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' \ +RUN CGO_ENABLED=0 go build -trimpath -buildvcs=false -ldflags '-s -w' \ -o /mesh-provision-postgres ./examples/postgres-provisioner FROM scratch diff --git a/examples/redis-provisioner/Dockerfile b/examples/redis-provisioner/Dockerfile index ade39a7d..edb26134 100644 --- a/examples/redis-provisioner/Dockerfile +++ b/examples/redis-provisioner/Dockerfile @@ -10,7 +10,7 @@ WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . -RUN CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' \ +RUN CGO_ENABLED=0 go build -trimpath -buildvcs=false -ldflags '-s -w' \ -o /mesh-provision-redis ./examples/redis-provisioner FROM scratch diff --git a/examples/route-proxy/Dockerfile b/examples/route-proxy/Dockerfile index 1c036271..03958031 100644 --- a/examples/route-proxy/Dockerfile +++ b/examples/route-proxy/Dockerfile @@ -10,7 +10,7 @@ WORKDIR /src COPY go.mod go.sum ./ RUN go mod download COPY . . -RUN CGO_ENABLED=0 go build -trimpath -ldflags '-s -w' -o /mesh-route-proxy ./examples/route-proxy +RUN CGO_ENABLED=0 go build -trimpath -buildvcs=false -ldflags '-s -w' -o /mesh-route-proxy ./examples/route-proxy FROM scratch COPY --from=build /mesh-route-proxy /mesh-route-proxy diff --git a/internal/builder/reproducible_test.go b/internal/builder/reproducible_test.go index e88851f4..345ce055 100644 --- a/internal/builder/reproducible_test.go +++ b/internal/builder/reproducible_test.go @@ -106,3 +106,40 @@ func TestTheGoToolchainStampsNoVersionControl(t *testing.T) { t.Fatalf("the go toolchain stamps the commit into what it compiles: %q", joined) } } + +// **And so does every recipe in this repository that compiles Go** (review of issue 363's fix): the +// controller's genesis image copies the whole clone, `.git` with it, and the reference images beside it +// are built the same way by the Makefile. +func TestEveryGoRecipeInThisRepositoryStampsNoVersionControl(t *testing.T) { + root := filepath.Join("..", "..") + var recipes []string + err := filepath.WalkDir(root, func(path string, d os.DirEntry, err error) error { + if err != nil { + return err + } + if d.IsDir() && (d.Name() == "vendor" || d.Name() == "testdata" || d.Name() == ".git") { + return filepath.SkipDir + } + if !d.IsDir() && d.Name() == "Dockerfile" { + recipes = append(recipes, path) + } + return nil + }) + if err != nil { + t.Fatal(err) + } + if len(recipes) == 0 { + t.Fatal("no recipe found in this repository") + } + for _, path := range recipes { + body, err := os.ReadFile(path) + if err != nil { + t.Fatal(err) + } + for _, line := range strings.Split(string(body), "\n") { + if strings.Contains(line, "go build") && !strings.Contains(line, "-buildvcs=false") { + t.Errorf("%s compiles Go and stamps the commit into it: %s", path, strings.TrimSpace(line)) + } + } + } +}