1453cfc69b
gates / gates (push) Failing after 50s
Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0159rPz1ZhFKsS53msqPYxtS
57 lines
2.1 KiB
Go
57 lines
2.1 KiB
Go
package main
|
|
|
|
import (
|
|
"os"
|
|
"regexp"
|
|
"strings"
|
|
"testing"
|
|
)
|
|
|
|
// R-208: `ARG VERSION` / `ARG GIT_COMMIT` declared ABOVE `RUN go mod download` put a per-build value
|
|
// into that RUN's cache key, so every release re-downloaded the modules (measured: 208 cache records,
|
|
// every one with usage count 1). The consequence pinned here, in the builder stage: no ARG whose value
|
|
// changes per build is declared before the module-download step, and both are still declared before
|
|
// the `go build` that reads them (or the binary would report "dev"/"unknown").
|
|
func TestR208_DockerfileVersionArgsSitBelowModuleDownload(t *testing.T) {
|
|
src, err := os.ReadFile("../../Dockerfile")
|
|
if err != nil {
|
|
t.Fatal(err)
|
|
}
|
|
lines := strings.Split(string(src), "\n")
|
|
argRe := regexp.MustCompile(`^\s*ARG\s+(VERSION|GIT_COMMIT|BUILD_TIME)\b`)
|
|
download, build := -1, -1
|
|
args := map[string]int{}
|
|
for i, l := range lines {
|
|
if strings.HasPrefix(strings.TrimSpace(l), "FROM ") && i > 0 && download >= 0 && build >= 0 {
|
|
break // the runtime stage: only the builder matters
|
|
}
|
|
if m := argRe.FindStringSubmatch(l); m != nil {
|
|
if _, seen := args[m[1]]; !seen {
|
|
args[m[1]] = i // the FIRST declaration: any one above the download is the defect
|
|
}
|
|
}
|
|
if strings.Contains(l, "go mod download") && download < 0 {
|
|
download = i
|
|
}
|
|
if strings.Contains(l, "go build") && build < 0 {
|
|
build = i
|
|
}
|
|
}
|
|
if download < 0 || build < 0 {
|
|
t.Fatalf("the builder stage no longer has a `go mod download` (%d) or a `go build` (%d) — this test reads the wrong file", download, build)
|
|
}
|
|
for _, name := range []string{"VERSION", "GIT_COMMIT"} {
|
|
at, ok := args[name]
|
|
if !ok {
|
|
t.Errorf("ARG %s is not declared in the builder stage — the binary would be built without it", name)
|
|
continue
|
|
}
|
|
if at < download {
|
|
t.Errorf("R-208: ARG %s (line %d) is declared above `go mod download` (line %d), so every build with a new value re-downloads the modules", name, at+1, download+1)
|
|
}
|
|
if at > build {
|
|
t.Errorf("ARG %s (line %d) is declared after the `go build` that reads it (line %d)", name, at+1, build+1)
|
|
}
|
|
}
|
|
}
|