Simplify the multiarch docker build

Make the binaries build run on the self-hosted runners
This commit is contained in:
Quentin Gliech
2023-09-13 19:58:05 +02:00
parent 37cb0a8e3c
commit 0f5c7db3d4
4 changed files with 177 additions and 176 deletions

View File

@@ -5,8 +5,14 @@ on:
branches: [ main ]
tags:
- 'v*'
# Only run for pull requests if relevant files were changed
pull_request:
branches: [ main ]
paths:
- Dockerfile
- docker-bake.hcl
- .github/workflows/build.yaml
concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
@@ -17,9 +23,10 @@ env:
CARGO_NET_GIT_FETCH_WITH_CLI: "true"
jobs:
build:
build-binaries:
name: Build binaries
runs-on: ubuntu-22.04
runs-on: memory-l-storage
container: docker.io/library/buildpack-deps:bookworm
env:
SDKROOT: /opt/MacOSX11.3.sdk
@@ -42,13 +49,13 @@ jobs:
node-version: 18
- name: Install Rust toolchain
run: |
rustup toolchain install stable
rustup target add x86_64-unknown-linux-musl
rustup target add aarch64-unknown-linux-musl
rustup target add x86_64-apple-darwin
rustup target add aarch64-apple-darwin
rustup default stable
uses: dtolnay/rust-toolchain@stable
with:
targets: |
x86_64-unknown-linux-musl
aarch64-unknown-linux-musl
x86_64-apple-darwin
aarch64-apple-darwin
- name: Setup Rust build cache
uses: Swatinem/rust-cache@v2.7.0
@@ -103,36 +110,157 @@ jobs:
uses: actions/upload-artifact@v3.1.3
with:
path: |
target/x86_64-unknown-linux-musl/release/mas-cli
target/aarch64-unknown-linux-musl/release/mas-cli
target/x86_64-apple-darwin/release/mas-cli
target/aarch64-apple-darwin/release/mas-cli
target/*/release/mas-cli
frontend/dist/
policies/policy.wasm
#release:
# name: Release
# if: startsWith(github.ref, 'refs/tags/')
# runs-on: ubuntu-latest
# needs:
# - build
# steps:
# - name: Download the artifacts from the previous job
# uses: actions/download-artifact@v3
# with:
# path: artifacts
# - name: Create the various archives
# run: |
# mkdir -p dist
# mv artifacts/
build-image:
name: Build and push Docker image
runs-on: ubuntu-latest
env:
IMAGE: ghcr.io/matrix-org/matrix-authentication-service
# - name: Prepare a release
# uses: softprops/action-gh-release@v1
# with:
# files: |
# mas-cli-aarch64-linux.tar.gz
# mas-cli-aarch64-macos.tar.gz
# mas-cli-x86_64-linux.tar.gz
# mas-cli-x86_64-macos.tar.gz
# draft: true
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout the code
uses: actions/checkout@v4.0.0
- name: Docker meta
id: meta
uses: docker/metadata-action@v5.0.0
with:
images: "${{ env.IMAGE }}"
bake-target: docker-metadata-action
flavor: |
latest=auto
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Docker meta (debug variant)
id: meta-debug
uses: docker/metadata-action@v5.0.0
with:
images: "${{ env.IMAGE }}"
bake-target: docker-metadata-action-debug
flavor: |
latest=auto
suffix=-debug,onlatest=true
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Setup Cosign
uses: sigstore/cosign-installer@v3.1.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.0.0
with:
config-inline: |
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# For pull-requests, only read from the cache, do not try to push to the
# cache or the image itself
- name: Build
uses: docker/bake-action@v4.0.0
if: github.event_name == 'pull_request'
with:
files: |
docker-bake.hcl
${{ steps.meta.outputs.bake-file }}
${{ steps.meta-debug.outputs.bake-file }}
set: |
base.context=https://github.com/${{ github.repository }}.git#${{ github.ref }}
base.cache-from=type=registry,ref=${{ env.IMAGE }}:buildcache
- name: Build and push
id: bake
uses: docker/bake-action@v4.0.0
if: github.event_name != 'pull_request'
with:
files: |
docker-bake.hcl
${{ steps.meta.outputs.bake-file }}
${{ steps.meta-debug.outputs.bake-file }}
set: |
base.context=https://github.com/${{ github.repository }}.git#${{ github.ref }}
base.output=type=image,push=true
base.cache-from=type=registry,ref=${{ env.IMAGE }}:buildcache
base.cache-to=type=registry,ref=${{ env.IMAGE }}:buildcache,mode=max
- name: Sign the images with GitHub Actions provided token
# Only sign on tags and on commits on main branch
if: |
github.event_name != 'pull_request'
&& (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
run: |-
cosign sign --yes \
"${{ env.IMAGE }}@${{ fromJSON(steps.bake.outputs.metadata).regular['containerimage.digest'] }}" \
"${{ env.IMAGE }}@${{ fromJSON(steps.bake.outputs.metadata).debug['containerimage.digest'] }}"
release:
name: Release
if: startsWith(github.ref, 'refs/tags/')
runs-on: ubuntu-latest
needs:
- build-binaries
- build-image
steps:
- name: Download the artifacts from the previous job
uses: actions/download-artifact@v3
with:
path: artifacts
- name: Prepare the archive directory
run: |
mkdir -p dist/share/
mv artifacts/policies/policy.wasm dist/share/policy.wasm
mv artifacts/frontend/dist/manifest.json dist/share/manifest.json
mv artifacts/frontend/dist/ dist/share/assets
mv templates/ dist/share/templates
mv LICENSE dist/LICENSE
chmod -R u=rwX,go=rX dist/
- name: Create the archives
run: |
for arch in x86_64 aarch64; do
mv artifacts/${arch}-unknown-linux-musl/release/mas-cli dist/mas-cli
chmod u=rwx,go=rx dist/mas-cli
tar -czvf mas-cli-${arch}-linux.tar.gz --owner=0 --group=0 -C dist/ .
mv artifacts/${arch}-apple-darwin/release/mas-cli dist/mas-cli
chmod u=rwx,go=rx dist/mas-cli
tar -czvf mas-cli-${arch}-macos.tar.gz --owner=0 --group=0 -C dist/ .
done
- name: Prepare a release
uses: softprops/action-gh-release@v1
with:
files: |
mas-cli-aarch64-linux.tar.gz
mas-cli-aarch64-macos.tar.gz
mas-cli-x86_64-linux.tar.gz
mas-cli-x86_64-macos.tar.gz
draft: true

View File

@@ -282,114 +282,6 @@ jobs:
cargo test --workspace
build-image:
name: Build and push Docker image
needs: [rustfmt, opa-lint]
runs-on: ubuntu-latest
env:
IMAGE: ghcr.io/matrix-org/matrix-authentication-service
permissions:
contents: read
packages: write
id-token: write
steps:
- name: Checkout the code
uses: actions/checkout@v4.0.0
- name: Docker meta
id: meta
uses: docker/metadata-action@v5.0.0
with:
images: "${{ env.IMAGE }}"
bake-target: docker-metadata-action
flavor: |
latest=auto
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Docker meta (debug variant)
id: meta-debug
uses: docker/metadata-action@v5.0.0
with:
images: "${{ env.IMAGE }}"
bake-target: docker-metadata-action-debug
flavor: |
latest=auto
suffix=-debug,onlatest=true
tags: |
type=ref,event=branch
type=semver,pattern={{version}}
type=semver,pattern={{major}}.{{minor}}
type=semver,pattern={{major}}
type=sha
- name: Setup Cosign
uses: sigstore/cosign-installer@v3.1.2
- name: Set up Docker Buildx
uses: docker/setup-buildx-action@v3.0.0
with:
config-inline: |
[registry."docker.io"]
mirrors = ["mirror.gcr.io"]
- name: Login to GitHub Container Registry
if: github.event_name != 'pull_request'
uses: docker/login-action@v3.0.0
with:
registry: ghcr.io
username: ${{ github.repository_owner }}
password: ${{ secrets.GITHUB_TOKEN }}
# For pull-requests, only read from the cache, do not try to push to the
# cache or the image itself
# We only build for the amd64 platform in pull-requests to speed-up CI
- name: Build
uses: docker/bake-action@v4.0.0
if: github.event_name == 'pull_request'
with:
files: |
docker-bake.hcl
${{ steps.meta.outputs.bake-file }}
${{ steps.meta-debug.outputs.bake-file }}
set: |
base.context=https://github.com/${{ github.repository }}.git#${{ github.ref }}
base.platform=linux/amd64
base.cache-from=type=registry,ref=${{ env.IMAGE }}:buildcache
- name: Build and push
id: bake
uses: docker/bake-action@v4.0.0
if: github.event_name != 'pull_request'
with:
files: |
docker-bake.hcl
${{ steps.meta.outputs.bake-file }}
${{ steps.meta-debug.outputs.bake-file }}
set: |
base.context=https://github.com/${{ github.repository }}.git#${{ github.ref }}
base.output=type=image,push=true
base.cache-from=type=registry,ref=${{ env.IMAGE }}:buildcache
base.cache-to=type=registry,ref=${{ env.IMAGE }}:buildcache,mode=max
- name: Sign the images with GitHub Actions provided token
# Only sign on tags and on commits on main branch
if: |
github.event_name != 'pull_request'
&& (startsWith(github.ref, 'refs/tags/v') || github.ref == 'refs/heads/main')
run: |-
cosign sign --yes \
"${{ env.IMAGE }}@${{ fromJSON(steps.bake.outputs.metadata).regular['containerimage.digest'] }}" \
"${{ env.IMAGE }}@${{ fromJSON(steps.bake.outputs.metadata).debug['containerimage.digest'] }}"
tests-done:
name: Tests done
if: ${{ always() }}
@@ -402,7 +294,6 @@ jobs:
- clippy
- check-schema
- test
- build-image
runs-on: ubuntu-latest
steps:

View File

@@ -4,10 +4,6 @@
# cross-building to aarch64 and x86_64. When cross-compiling, Docker sets two
# implicit BUILDARG: BUILDPLATFORM being the host platform and TARGETPLATFORM
# being the platform being built.
#
# Docker platform definitions look like this: linux/arm64 and linux/amd64, so
# there is a small script that translates those platforms to LLVM triples,
# respectively x86-64-unknown-linux-musl and aarch64-unknown-linux-musl
# The Debian version and version name must be in sync
ARG DEBIAN_VERSION=11
@@ -20,7 +16,7 @@ ARG NODEJS_VERSION=18.17.1
ARG OPA_VERSION=0.55.0
ARG CARGO_AUDITABLE_VERSION=0.6.1
ARG CARGO_CHEF_VERSION=0.1.62
ARG CARGO_ZIGBUILD_VERSION=0.17.1
ARG CARGO_ZIGBUILD_VERSION=0.17.3
##########################################
## Build stage that builds the frontend ##
@@ -100,9 +96,6 @@ RUN --network=default \
x86_64-unknown-linux-musl \
aarch64-unknown-linux-musl
# Helper script that transforms docker platforms to LLVM triples
COPY ./misc/docker-arch-to-rust-target.sh /
# Set the working directory
WORKDIR /app
@@ -120,8 +113,6 @@ RUN --network=none \
########################
FROM --platform=${BUILDPLATFORM} toolchain AS builder
ARG TARGETPLATFORM
# Build dependencies
COPY --from=planner /app/recipe.json recipe.json
# Network access: cargo-chef cook fetches the dependencies
@@ -133,7 +124,8 @@ RUN --network=default \
--recipe-path recipe.json \
--no-default-features \
--features docker \
--target "$(/docker-arch-to-rust-target.sh "${TARGETPLATFORM}")" \
--target x86_64-unknown-linux-musl \
--target aarch64-unknown-linux-musl \
--package mas-cli
# Build the rest
@@ -148,11 +140,14 @@ RUN --network=default \
--bin mas-cli \
--no-default-features \
--features docker \
--target "$(/docker-arch-to-rust-target.sh "${TARGETPLATFORM}")"
--target x86_64-unknown-linux-musl \
--target aarch64-unknown-linux-musl
# Move the binary to avoid having to guess its name in the next stage
RUN --network=none \
mv "target/$(/docker-arch-to-rust-target.sh "${TARGETPLATFORM}")/release/mas-cli" /usr/local/bin/mas-cli
mv "target/x86_64-unknown-linux-musl/release/mas-cli" /usr/local/bin/mas-cli-amd64
RUN --network=none \
mv "target/aarch64-unknown-linux-musl/release/mas-cli" /usr/local/bin/mas-cli-arm64
#######################################
## Prepare /usr/local/share/mas-cli/ ##
@@ -168,7 +163,8 @@ COPY ./templates/ /share/templates
##################################
FROM --platform=${TARGETPLATFORM} gcr.io/distroless/static-debian${DEBIAN_VERSION}:debug-nonroot AS debug
COPY --from=builder /usr/local/bin/mas-cli /usr/local/bin/mas-cli
ARG TARGETARCH
COPY --from=builder /usr/local/bin/mas-cli-${TARGETARCH} /usr/local/bin/mas-cli
COPY --from=share /share /usr/local/share/mas-cli
WORKDIR /
@@ -179,7 +175,8 @@ ENTRYPOINT ["/usr/local/bin/mas-cli"]
###################
FROM --platform=${TARGETPLATFORM} gcr.io/distroless/static-debian${DEBIAN_VERSION}:nonroot
COPY --from=builder /usr/local/bin/mas-cli /usr/local/bin/mas-cli
ARG TARGETARCH
COPY --from=builder /usr/local/bin/mas-cli-${TARGETARCH} /usr/local/bin/mas-cli
COPY --from=share /share /usr/local/share/mas-cli
WORKDIR /

View File

@@ -1,15 +0,0 @@
#!/bin/sh
if [ "$#" -ne 1 ]; then
echo "usage: $0 [platform]" >&2
exit 1
fi
if [ "$1" = "linux/arm64" ] || [ "$1" = "linux/arm64/v8" ]; then
echo "aarch64-unknown-linux-musl"
elif [ "$1" = "linux/amd64" ]; then
echo "x86_64-unknown-linux-musl"
else
echo "unsupported platform $1" >&2
exit 2
fi