aboutsummaryrefslogtreecommitdiffhomepage
diff options
context:
space:
mode:
authorDavid Karlsson <[email protected]>2024-09-29 19:30:04 +0200
committerBjørn Erik Pedersen <[email protected]>2024-10-13 20:01:37 +0200
commit4a79956276e735a4a21e09d134527b3a0247180d (patch)
treee1ab0b05cbda197ca79ac6fe5b0af4ae6706eb62
parent039845804fd545de18a3c4f17f8f7b3ad3bf615b (diff)
downloadhugo-4a79956276e735a4a21e09d134527b3a0247180d.tar.gz
hugo-4a79956276e735a4a21e09d134527b3a0247180d.zip
ci: Build multi-platform image with cross-compilation
The previous build workflow used emulation to build the Docker image, which results in a somewhat complicated push-by-digest and merge workflow to create a multi-platform image. This commit changes the Docker build to use cross-compilation instead, resulting in a faster and more straightforward build. Signed-off-by: David Karlsson <[email protected]>
-rw-r--r--.github/workflows/image.yml83
-rwxr-xr-xDockerfile30
2 files changed, 29 insertions, 84 deletions
diff --git a/.github/workflows/image.yml b/.github/workflows/image.yml
index be128d6fd..95a4ad0b6 100644
--- a/.github/workflows/image.yml
+++ b/.github/workflows/image.yml
@@ -3,6 +3,7 @@ name: Build Docker image
on:
release:
types: [published]
+ pull_request:
permissions:
packages: write
@@ -12,18 +13,8 @@ env:
jobs:
build:
runs-on: ubuntu-latest
- strategy:
- fail-fast: false
- matrix:
- platform:
- - linux/amd64
- - linux/arm64
- steps:
- - name: Prepare
- run: |
- platform=${{ matrix.platform }}
- echo "PLATFORM_PAIR=${platform//\//-}" >> $GITHUB_ENV
+ steps:
- name: Checkout
uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
@@ -33,9 +24,6 @@ jobs:
with:
images: ${{ env.REGISTRY_IMAGE }}
- - name: Set up QEMU
- uses: docker/setup-qemu-action@49b3bc8e6bdd4a60e6116a5414239cba5943d3cf # v3.2.0
-
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
@@ -47,69 +35,14 @@ jobs:
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
- - name: Build and push by digest
+ - name: Build and push
id: build
uses: docker/build-push-action@16ebe778df0e7752d2cfcbd924afdbbd89c1a755 # v6.6.1
with:
context: .
- push: ${{ startsWith(github.ref, 'refs/tags') }}
- platforms: ${{ matrix.platform }}
+ provenance: mode=max
+ sbom: true
+ push: ${{ github.event_name != 'pull_request' }}
+ platforms: linux/amd64,linux/arm64
+ tags: ${{ steps.meta.outputs.tags }}
labels: ${{ steps.meta.outputs.labels }}
- outputs: type=image,name=${{ env.REGISTRY_IMAGE }},push-by-digest=true,name-canonical=true,push=true
-
- - name: Export digest
- run: |
- mkdir -p /tmp/digests
- digest="${{ steps.build.outputs.digest }}"
- touch "/tmp/digests/${digest#sha256:}"
-
- - name: Upload digest
- uses: actions/upload-artifact@834a144ee995460fba8ed112a2fc961b36a5ec5a # v4.3.6
- with:
- name: digests-${{ env.PLATFORM_PAIR }}
- path: /tmp/digests/*
- if-no-files-found: error
- retention-days: 1
-
- merge:
- runs-on: ubuntu-latest
- needs:
- - build
- steps:
- - name: Download digests
- uses: actions/download-artifact@fa0a91b85d4f404e444e00e005971372dc801d16 # v4.1.8
- with:
- path: /tmp/digests
- pattern: digests-*
- merge-multiple: true
-
- - name: Set up Docker Buildx
- uses: docker/setup-buildx-action@988b5a0280414f521da01fcc63a27aeeb4b104db # v3.6.1
-
- - name: Docker meta
- id: meta
- uses: docker/metadata-action@8e5442c4ef9f78752691e2d8f8d19755c6f78e81 # v5.5.1
- with:
- images: ${{ env.REGISTRY_IMAGE }}
-
- flavor: |
- latest=false
-
- - name: Login to GHCR
- uses: docker/login-action@9780b0c442fbb1117ed29e0efdff1e18412f7567 # v3.3.0
- with:
- registry: ghcr.io
- username: ${{ github.repository_owner }}
- password: ${{ secrets.GITHUB_TOKEN }}
-
- - name: Create manifest list and push
- if: ${{ startsWith(github.ref, 'refs/tags') }}
- working-directory: /tmp/digests
- run: |
- docker buildx imagetools create $(jq -cr '.tags | map("-t " + .) | join(" ")' <<< "$DOCKER_METADATA_OUTPUT_JSON") \
- $(printf '${{ env.REGISTRY_IMAGE }}@sha256:%s ' *)
-
- - name: Inspect image
- if: ${{ startsWith(github.ref, 'refs/tags') }}
- run: |
- docker buildx imagetools inspect ${{ env.REGISTRY_IMAGE }}:${{ steps.meta.outputs.version }}
diff --git a/Dockerfile b/Dockerfile
index fb72b77f1..afe5cf132 100755
--- a/Dockerfile
+++ b/Dockerfile
@@ -2,11 +2,17 @@
# Twitter: https://twitter.com/gohugoio
# Website: https://gohugo.io/
-FROM golang:1.22.6-alpine AS build
+FROM --platform=$BUILDPLATFORM tonistiigi/xx:1.5.0 AS xx
+
+FROM --platform=$BUILDPLATFORM golang:1.22.6-alpine AS build
+
+# Set up cross-compilation helpers
+COPY --from=xx / /
+RUN apk add clang lld
# Optionally set HUGO_BUILD_TAGS to "extended" or "nodeploy" when building like so:
# docker build --build-arg HUGO_BUILD_TAGS=extended .
-ARG HUGO_BUILD_TAGS
+ARG HUGO_BUILD_TAGS="none"
ARG CGO=1
ENV CGO_ENABLED=${CGO}
@@ -15,20 +21,26 @@ ENV GO111MODULE=on
WORKDIR /go/src/github.com/gohugoio/hugo
-COPY . /go/src/github.com/gohugoio/hugo/
+RUN --mount=src=go.mod,target=go.mod \
+ --mount=src=go.sum,target=go.sum \
+ --mount=type=cache,target=/go/pkg/mod \
+ go mod download
+ARG TARGETPLATFORM
# gcc/g++ are required to build SASS libraries for extended version
-RUN apk update && \
- apk add --no-cache gcc g++ musl-dev git && \
- go install github.com/magefile/mage
-
-RUN mage hugo && mage install
+RUN xx-apk add --no-scripts --no-cache gcc g++ musl-dev git
+RUN --mount=target=. \
+ --mount=type=cache,target=/go/pkg/mod <<EOT
+ set -ex
+ xx-go build -tags "$HUGO_BUILD_TAGS" -o /usr/bin/hugo
+ xx-verify /usr/bin/hugo
+EOT
# ---
FROM alpine:3.18
-COPY --from=build /go/bin/hugo /usr/bin/hugo
+COPY --from=build /usr/bin/hugo /usr/bin/hugo
# libc6-compat & libstdc++ are required for extended SASS libraries
# ca-certificates are required to fetch outside resources (like Twitter oEmbeds)