@@ -13,7 +13,15 @@ FROM buildpack-deps:{{ env.variant }}-scm AS build
1313
1414ENV PATH /usr/local/go/bin:$PATH
1515
16+ {{ if env.version != "tip" then ( -}}
1617ENV GOLANG_VERSION {{ .version }}
18+ {{ ) else ( -}}
19+ COPY --from=golang:{{ env.variant }} /usr/local/go /usr/local/goroot-bootstrap
20+
21+ # {{ .version }}: https://github.com/golang/go/tree/{{ .commit.version }}
22+ ARG GOLANG_COMMIT={{ .commit.version | @sh }}
23+ ENV GOLANG_COMMIT $GOLANG_COMMIT
24+ {{ ) end -}}
1725
1826{{
1927 def os_arches:
@@ -54,16 +62,23 @@ RUN set -eux; \
5462 now="$(date '+%s')"; \
5563{{ if is_alpine then ( -}}
5664 apk add --no-cache --virtual .fetch-deps \
65+ {{ if env.version != "tip" then ( -}}
5766 ca-certificates \
5867 gnupg \
5968# busybox's "tar" doesn't handle directory mtime correctly, so our SOURCE_DATE_EPOCH lookup doesn't work (the mtime of "/usr/local/go" always ends up being the extraction timestamp)
6069 tar \
70+ {{ ) else ( -}}
71+ bash \
72+ git \
73+ {{ ) end -}}
6174 ; \
6275 arch="$(apk --print-arch)"; \
6376{{ ) else ( -}}
6477 arch="$(dpkg --print-architecture)"; arch="${arch##*-}"; \
6578{{ ) end -}}
79+ {{ if env.version != "tip" then ( -}}
6680 url=; \
81+ {{ ) else "" end -}}
6782 case "$arch" in \
6883{{
6984 [
@@ -78,8 +93,12 @@ RUN set -eux; \
7893 | (
7994-}}
8095 {{ $osArch | @sh }}) \
96+ {{ if env.version != "tip" then ( -}}
8197 url={{ .url | @sh }}; \
8298 sha256={{ .sha256 | @sh }}; \
99+ {{ ) else ( -}}
100+ export {{ .env | to_entries | sort_by(.key) | map(.key + "=" + (.value | @sh)) | join(" ") }}; \
101+ {{ ) end -}}
83102 ;; \
84103{{
85104 )
@@ -88,6 +107,7 @@ RUN set -eux; \
88107 *) echo >&2 "error: unsupported architecture '$arch' (likely packaging update needed)"; exit 1 ;; \
89108 esac; \
90109 \
110+ {{ if env.version != "tip" then ( -}}
91111 wget -O go.tgz.asc "$url.asc"; \
92112 wget -O go.tgz "$url"{{ if is_alpine then "" else " --progress=dot:giga" end }}; \
93113 echo "$sha256 *go.tgz" | sha256sum -c -; \
@@ -107,14 +127,57 @@ RUN set -eux; \
107127 \
108128# save the timestamp from the tarball so we can restore it for reproducibility, if necessary (see below)
109129 SOURCE_DATE_EPOCH="$(stat -c '%Y' /usr/local/go)"; \
130+ {{ ) else ( -}}
131+ # before we get too far, let's validate that our "bootstrap" Go works
132+ export GOROOT_BOOTSTRAP=/usr/local/goroot-bootstrap; \
133+ # TODO figure out why QEMU's user-mode emulation with Go 1.23.0 causes "can't start telemetry child process: fork/exec /usr/local/go/bin/go: invalid argument" (it works if we run it a second time, but then later "go build" fails to fork/exec the compile process 🙃)
134+ "$GOROOT_BOOTSTRAP/bin/go" version; \
135+ \
136+ git init --quiet /usr/local/go; \
137+ git -C /usr/local/go fetch --depth 1 https://github.com/golang/go.git "$GOLANG_COMMIT:"; \
138+ git -C /usr/local/go checkout --quiet FETCH_HEAD; \
139+ \
140+ # save the Git timestamp so we can use it for reproducibility
141+ SOURCE_DATE_EPOCH="$(git -C /usr/local/go log -1 --format='format:%ct' HEAD)"; \
142+ {{ ) end -}}
110143 export SOURCE_DATE_EPOCH; \
111144 touchy="$(date -d "@$SOURCE_DATE_EPOCH" '+%Y%m%d%H%M.%S')"; \
112145# for logging validation/edification
113146 date --date "@$SOURCE_DATE_EPOCH" --rfc-2822; \
114147# sanity check (detected value should be older than our wall clock)
115148 [ "$SOURCE_DATE_EPOCH" -lt "$now" ]; \
116149 \
117- {{ if .arches["arm32v7"].url // "" | contains("armv6") then ( -}}
150+ {{ if env.version == "tip" then ( -}}
151+ ( \
152+ export \
153+ GOCACHE='/tmp/gocache' \
154+ # set GOHOST* to make sure explicitly 32bit builds on 64bit infra work correctly
155+ GOHOSTOS="$GOOS" \
156+ GOHOSTARCH="$GOARCH" \
157+ ; \
158+ \
159+ cd /usr/local/go/src; \
160+ ./make.bash; \
161+ \
162+ # remove a few intermediate / bootstrapping files the official binary release tarballs do not contain (and ".git" that is hard to make reproducible)
163+ rm -rf \
164+ /usr/local/go/.git* \
165+ /usr/local/go/pkg/*/cmd \
166+ /usr/local/go/pkg/bootstrap \
167+ /usr/local/go/pkg/obj \
168+ /usr/local/go/pkg/tool/*/api \
169+ /usr/local/go/pkg/tool/*/go_bootstrap \
170+ /usr/local/go/src/cmd/dist/dist \
171+ "$GOCACHE" \
172+ ; \
173+ \
174+ # clamp timestamps for reproducibility (allows "COPY --link" to be more clever/useful)
175+ touch -t "$touchy" /usr/local/.go-date-stamp; \
176+ find /usr/local/go -depth -newer /usr/local/.go-date-stamp -exec touch -ht "$touchy" '{}' +; \
177+ rm /usr/local/.go-date-stamp; \
178+ ); \
179+ \
180+ {{ ) elif .arches["arm32v7"].url // "" | contains("armv6") then ( -}}
118181 if [ "$arch" = {{ os_arches["arm32v7"] | @sh }} ]; then \
119182 [ -s /usr/local/go/go.env ]; \
120183 before="$(go env GOARM)"; [ "$before" != {{ .arches["arm32v7"].env["GOARM"] | @sh }} ]; \
@@ -166,8 +229,10 @@ RUN set -eux; \
166229 rm -rf /var/lib/apt/lists/*
167230{{ ) end -}}
168231
232+ {{ if env.version != "tip" then ( -}}
169233ENV GOLANG_VERSION {{ .version }}
170234
235+ {{ ) else "" end -}}
171236# don't auto-upgrade the gotoolchain
172237# https://github.com/docker-library/golang/issues/472
173238ENV GOTOOLCHAIN=local
0 commit comments