-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathDockerfile
More file actions
210 lines (182 loc) · 6.6 KB
/
Dockerfile
File metadata and controls
210 lines (182 loc) · 6.6 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
# Copyright 2026 Docker, Inc.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#syntax=docker/dockerfile:1
ARG ALPINE_VERSION=3.23.3
ARG GO_VERSION=latest
ARG GOLANGCI_LINT_VERSION=v2.2.1
ARG OSXCROSS_VERSION=15.5
ARG ADDLICENSE_VERSION=v1.2.0
ARG LICENSE_ARGS="-c 'Docker, Inc.' -l apache -ignore '**/*.yaml' -ignore '**/*.yml' -ignore '.github/**' -ignore 'store/keychain/internal/go-keychain/**' -ignore 'vendor/**' -ignore '.git/**' ."
FROM ghcr.io/google/addlicense:${ADDLICENSE_VERSION} AS addlicense
FROM --platform=${BUILDPLATFORM} golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS lint-base
FROM --platform=${BUILDPLATFORM} tonistiigi/xx AS xx
# osxcross contains the MacOSX cross toolchain for xx
FROM --platform=${BUILDPLATFORM} crazymax/osxcross:${OSXCROSS_VERSION}-alpine AS osxcross
FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine AS gobase
RUN apk add --no-cache findutils build-base git
FROM alpine:${ALPINE_VERSION} AS license-validate
ARG LICENSE_ARGS
COPY --link --from=addlicense /app/addlicense /usr/bin/addlicense
WORKDIR /src
RUN --mount=type=bind,target=.,ro <<EOT
set -eu
echo "== Checking license headers =="
eval "/usr/bin/addlicense -check $LICENSE_ARGS"
EOT
FROM alpine:${ALPINE_VERSION} AS do-license-update
ARG LICENSE_ARGS
COPY --from=addlicense /app/addlicense /usr/bin/addlicense
RUN mkdir -p /generate/out
WORKDIR /src
RUN apk add --no-cache git
RUN --mount=type=bind,target=.,rw <<EOT
set -eu
echo "== Checking license headers =="
eval "/usr/bin/addlicense -v $LICENSE_ARGS"
./scripts/copy-only-diff /generate/out
EOT
FROM scratch AS license-update
COPY --from=do-license-update /generate/out .
FROM gobase AS linux-base
ARG TARGETARCH
ENV GOOS=linux
ENV GOARCH=${TARGETARCH}
FROM gobase AS windows-base
ARG TARGETARCH
ENV GOOS=windows
ENV GOARCH=${TARGETARCH}
FROM gobase AS darwin-base
COPY --link --from=xx / /
COPY --link --from=osxcross /osxcross /osxcross
RUN apk add --no-cache clang lld musl-dev build-base findutils gcc
ARG TARGETARCH
ENV GOOS=darwin
ENV GOARCH=${TARGETARCH}
ENV PATH="/osxcross/bin:$PATH"
ENV LD_LIBRARY_PATH="/osxcross/lib:${LD_LIBRARY_PATH:-}"
ENV CC=o64-clang
ENV CXX=o64-clang++
ARG TARGETOS
FROM ${TARGETOS}-base AS lint
ENV CGO_ENABLED=1
COPY --link --from=lint-base /usr/bin/golangci-lint /usr/bin/golangci-lint
RUN apk add --no-cache openssh-client
WORKDIR /app
RUN mkdir -p -m 0700 ~/.ssh && ssh-keyscan github.com >> ~/.ssh/known_hosts
RUN --mount=type=bind,target=.,ro \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=ssh <<EOT
set -euo pipefail
# Avoid interactive git prompts in CI
export GIT_TERMINAL_PROMPT=0
# If no token, prefer SSH for GitHub; if token exists, we’ll override below
git config --global url."ssh://git@github.com/".insteadOf "https://github.com/"
for dir in $(go list -f '{{.Dir}}' -m); do
(cd "$dir" && go mod tidy --diff)
done
EOT
RUN --mount=type=bind,target=.,ro \
--mount=type=cache,target=/root/.cache <<EOT
set -euo pipefail
# golangci-lint works mainly like go run/go test, ie., per go module
# https://github.com/golangci/golangci-lint/issues/2654#issuecomment-1606439587
golangci-lint run -v $(go list -f '{{.Dir}}/...' -m | xargs)
EOT
FROM golang AS govulncheck
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=tmpfs,target=/go/src/ \
go install "golang.org/x/vuln/cmd/govulncheck@latest" \
&& govulncheck -version
FROM golang AS do-govulncheck
ARG TARGETARCH
ARG GO_VERSION
COPY --link --from=govulncheck /go/bin/govulncheck /go/bin/govulncheck
WORKDIR /govulncheck
ENV GOARCH=${TARGETARCH}
ENV GOTOOLCHAIN=go${GO_VERSION}
ENV PATH=/go/bin:$PATH
RUN --mount=type=bind,target=.,ro <<EOT
set -euo pipefail
for dir in $(go list -f '{{.Dir}}' -m); do
(cd "$dir" && govulncheck -show=verbose ./...)
done
EOT
FROM golang AS gomodguard
ARG GOMODGUARD_VERSION=v1.4.1
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=tmpfs,target=/go/src/ \
go install "github.com/ryancurrah/gomodguard/cmd/gomodguard@${GOMODGUARD_VERSION}" \
&& gomodguard -help
FROM golang AS do-gomodguard
COPY --link --from=gomodguard /go/bin/gomodguard /go/bin/gomodguard
WORKDIR /modguard
ENV PATH=/go/bin:$PATH
RUN --mount=type=bind,target=.,ro <<EOT
set -euo pipefail
for dir in $(go list -f '{{.Dir}}' -m); do
if [ -f "$dir/.gomodguard.yaml" ]; then
(cd "$dir" && gomodguard)
fi
done
EOT
FROM golang AS gofumpt
ARG GOFUMPT_VERSION=v0.8.0
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=tmpfs,target=/go/src/ \
go install "mvdan.cc/gofumpt@${GOFUMPT_VERSION}" \
&& gofumpt --version
FROM golang AS goimports
ARG GOIMPORTS_VERSION=latest
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=tmpfs,target=/go/src/ \
go install "golang.org/x/tools/cmd/goimports@${GOIMPORTS_VERSION}"
FROM ${TARGETOS}-base AS do-format
COPY --link --from=gofumpt /go/bin/gofumpt /go/bin/gofumpt
COPY --link --from=goimports /go/bin/goimports /go/bin/goimports
COPY --link --from=lint-base /usr/bin/golangci-lint /usr/bin/golangci-lint
WORKDIR /format
RUN mkdir -p /format/out
RUN --mount=type=bind,target=/src,rw <<EOT
set -euo pipefail
cd /src
CGO_ENABLED=1 golangci-lint fmt -v
./scripts/copy-only-diff /format/out
EOT
FROM scratch AS format
COPY --from=do-format /format/out .
FROM gobase AS proto-base
ARG BUF_VERSION
RUN --mount=type=cache,target=/root/.cache/go-build \
--mount=type=cache,target=/go/pkg/mod \
--mount=type=tmpfs,target=/go/src/ \
go install "github.com/bufbuild/buf/cmd/buf@${BUF_VERSION}"
FROM proto-base AS proto-lint
WORKDIR /app
RUN --mount=type=bind,target=. \
buf lint
FROM proto-base AS do-proto-generate
WORKDIR /src
RUN mkdir -p /generate/out
RUN --mount=type=bind,target=.,rw <<EOT
set -euo pipefail
cd /src
buf generate
./scripts/copy-only-diff /generate/out
EOT
FROM scratch AS proto-generate
COPY --from=do-proto-generate /generate/out .