Dockerfile 6.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197
  1. # syntax=docker/dockerfile:1
  2. # Copyright 2020 Docker Compose CLI authors
  3. # Licensed under the Apache License, Version 2.0 (the "License");
  4. # you may not use this file except in compliance with the License.
  5. # You may obtain a copy of the License at
  6. # http://www.apache.org/licenses/LICENSE-2.0
  7. # Unless required by applicable law or agreed to in writing, software
  8. # distributed under the License is distributed on an "AS IS" BASIS,
  9. # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
  10. # See the License for the specific language governing permissions and
  11. # limitations under the License.
  12. ARG GO_VERSION=1.21.0
  13. ARG XX_VERSION=1.2.1
  14. ARG GOLANGCI_LINT_VERSION=v1.53.2
  15. ARG ADDLICENSE_VERSION=v1.0.0
  16. ARG BUILD_TAGS="e2e"
  17. ARG DOCS_FORMATS="md,yaml"
  18. ARG LICENSE_FILES=".*\(Dockerfile\|Makefile\|\.go\|\.hcl\|\.sh\)"
  19. # xx is a helper for cross-compilation
  20. FROM --platform=${BUILDPLATFORM} tonistiigi/xx:${XX_VERSION} AS xx
  21. # osxcross contains the MacOSX cross toolchain for xx
  22. FROM crazymax/osxcross:11.3-alpine AS osxcross
  23. FROM golangci/golangci-lint:${GOLANGCI_LINT_VERSION}-alpine AS golangci-lint
  24. FROM ghcr.io/google/addlicense:${ADDLICENSE_VERSION} AS addlicense
  25. FROM --platform=${BUILDPLATFORM} golang:${GO_VERSION}-alpine AS base
  26. COPY --from=xx / /
  27. RUN apk add --no-cache \
  28. clang \
  29. docker \
  30. file \
  31. findutils \
  32. git \
  33. make \
  34. protoc \
  35. protobuf-dev
  36. WORKDIR /src
  37. ENV CGO_ENABLED=0
  38. FROM base AS build-base
  39. COPY go.* .
  40. RUN --mount=type=cache,target=/go/pkg/mod \
  41. --mount=type=cache,target=/root/.cache/go-build \
  42. go mod download
  43. FROM build-base AS vendored
  44. RUN --mount=type=bind,target=.,rw \
  45. --mount=type=cache,target=/go/pkg/mod \
  46. go mod tidy && mkdir /out && cp go.mod go.sum /out
  47. FROM scratch AS vendor-update
  48. COPY --from=vendored /out /
  49. FROM vendored AS vendor-validate
  50. RUN --mount=type=bind,target=.,rw <<EOT
  51. set -e
  52. git add -A
  53. cp -rf /out/* .
  54. diff=$(git status --porcelain -- go.mod go.sum)
  55. if [ -n "$diff" ]; then
  56. echo >&2 'ERROR: Vendor result differs. Please vendor your package with "make go-mod-tidy"'
  57. echo "$diff"
  58. exit 1
  59. fi
  60. EOT
  61. FROM build-base AS build
  62. ARG BUILD_TAGS
  63. ARG BUILD_FLAGS
  64. ARG TARGETPLATFORM
  65. RUN --mount=type=bind,target=. \
  66. --mount=type=cache,target=/root/.cache \
  67. --mount=type=cache,target=/go/pkg/mod \
  68. --mount=type=bind,from=osxcross,src=/osxsdk,target=/xx-sdk \
  69. xx-go --wrap && \
  70. if [ "$(xx-info os)" == "darwin" ]; then export CGO_ENABLED=1; fi && \
  71. make build GO_BUILDTAGS="$BUILD_TAGS" DESTDIR=/out && \
  72. xx-verify --static /out/docker-compose
  73. FROM build-base AS lint
  74. ARG BUILD_TAGS
  75. RUN --mount=type=bind,target=. \
  76. --mount=type=cache,target=/root/.cache \
  77. --mount=type=cache,target=/go/pkg/mod \
  78. --mount=from=golangci-lint,source=/usr/bin/golangci-lint,target=/usr/bin/golangci-lint \
  79. golangci-lint run --build-tags "$BUILD_TAGS" ./...
  80. FROM build-base AS test
  81. ARG CGO_ENABLED=0
  82. ARG BUILD_TAGS
  83. RUN --mount=type=bind,target=. \
  84. --mount=type=cache,target=/root/.cache \
  85. --mount=type=cache,target=/go/pkg/mod \
  86. rm -rf /tmp/coverage && \
  87. mkdir -p /tmp/coverage && \
  88. go test -tags "$BUILD_TAGS" -v -cover -covermode=atomic $(go list $(TAGS) ./... | grep -vE 'e2e') -args -test.gocoverdir="/tmp/coverage" && \
  89. go tool covdata percent -i=/tmp/coverage
  90. FROM scratch AS test-coverage
  91. COPY --from=test --link /tmp/coverage /
  92. FROM base AS license-set
  93. ARG LICENSE_FILES
  94. RUN --mount=type=bind,target=.,rw \
  95. --mount=from=addlicense,source=/app/addlicense,target=/usr/bin/addlicense \
  96. find . -regex "${LICENSE_FILES}" | xargs addlicense -c 'Docker Compose CLI' -l apache && \
  97. mkdir /out && \
  98. find . -regex "${LICENSE_FILES}" | cpio -pdm /out
  99. FROM scratch AS license-update
  100. COPY --from=set /out /
  101. FROM base AS license-validate
  102. ARG LICENSE_FILES
  103. RUN --mount=type=bind,target=. \
  104. --mount=from=addlicense,source=/app/addlicense,target=/usr/bin/addlicense \
  105. find . -regex "${LICENSE_FILES}" | xargs addlicense -check -c 'Docker Compose CLI' -l apache -ignore validate -ignore testdata -ignore resolvepath -v
  106. FROM base AS docsgen
  107. WORKDIR /src
  108. RUN --mount=target=. \
  109. --mount=target=/root/.cache,type=cache \
  110. --mount=type=cache,target=/go/pkg/mod \
  111. go build -o /out/docsgen ./docs/yaml/main/generate.go
  112. FROM --platform=${BUILDPLATFORM} alpine AS docs-build
  113. RUN apk add --no-cache rsync git
  114. WORKDIR /src
  115. COPY --from=docsgen /out/docsgen /usr/bin
  116. ARG DOCS_FORMATS
  117. RUN --mount=target=/context \
  118. --mount=target=.,type=tmpfs <<EOT
  119. set -e
  120. rsync -a /context/. .
  121. docsgen --formats "$DOCS_FORMATS" --source "docs/reference"
  122. mkdir /out
  123. cp -r docs/reference /out
  124. EOT
  125. FROM scratch AS docs-update
  126. COPY --from=docs-build /out /out
  127. FROM docs-build AS docs-validate
  128. RUN --mount=target=/context \
  129. --mount=target=.,type=tmpfs <<EOT
  130. set -e
  131. rsync -a /context/. .
  132. git add -A
  133. rm -rf docs/reference/*
  134. cp -rf /out/* ./docs/
  135. if [ -n "$(git status --porcelain -- docs/reference)" ]; then
  136. echo >&2 'ERROR: Docs result differs. Please update with "make docs"'
  137. git status --porcelain -- docs/reference
  138. exit 1
  139. fi
  140. EOT
  141. FROM scratch AS binary-unix
  142. COPY --link --from=build /out/docker-compose /
  143. FROM binary-unix AS binary-darwin
  144. FROM binary-unix AS binary-linux
  145. FROM scratch AS binary-windows
  146. COPY --link --from=build /out/docker-compose /docker-compose.exe
  147. FROM binary-$TARGETOS AS binary
  148. # enable scanning for this stage
  149. ARG BUILDKIT_SBOM_SCAN_STAGE=true
  150. FROM --platform=$BUILDPLATFORM alpine AS releaser
  151. WORKDIR /work
  152. ARG TARGETOS
  153. ARG TARGETARCH
  154. ARG TARGETVARIANT
  155. RUN --mount=from=binary \
  156. mkdir -p /out && \
  157. # TODO: should just use standard arch
  158. TARGETARCH=$([ "$TARGETARCH" = "amd64" ] && echo "x86_64" || echo "$TARGETARCH"); \
  159. TARGETARCH=$([ "$TARGETARCH" = "arm64" ] && echo "aarch64" || echo "$TARGETARCH"); \
  160. cp docker-compose* "/out/docker-compose-${TARGETOS}-${TARGETARCH}${TARGETVARIANT}$(ls docker-compose* | sed -e 's/^docker-compose//')"
  161. FROM scratch AS release
  162. COPY --from=releaser /out/ /
  163. # docs-reference is a target used as remote context to update docs on release
  164. # with latest changes on docs.docker.com.
  165. # see open-pr job in .github/workflows/docs.yml for more details
  166. FROM scratch AS docs-reference
  167. COPY docs/reference/*.yaml .