From e6e74022b575e5877f3db7272a03093a7202a622 Mon Sep 17 00:00:00 2001 From: lczyk Date: Fri, 3 Jul 2026 11:35:12 +0100 Subject: [PATCH 1/3] feat?: s390x + ppc64le support images, inlined yamls, release binaries. no hosted runners for these arches: images build under qemu and publish untested; tests + demo stay on amd64 / arm64 (NATIVE_ARCHES). docker cli now builds from docker/cli source for all arches -- docker.com static tarballs stopped at 18.06 for s390x / ppc64le. --- .github/workflows/binaries.yaml | 6 +-- .github/workflows/build-oci.yaml | 20 +++++-- .github/workflows/push-ghcr.yaml | 23 ++++---- .github/workflows/release.yaml | 21 ++++---- hack/build_binaries.sh | 53 +++++++++---------- inlined/bread-24.04.yaml | 6 +++ inlined/bread-25.10.yaml | 6 +++ inlined/bread-26.04.yaml | 6 +++ inlined/bread-26.10.yaml | 6 +++ inlined/bread-chisel-releases-24.04.yaml | 6 +++ inlined/bread-chisel-releases-25.10.yaml | 6 +++ inlined/bread-chisel-releases-26.04.yaml | 6 +++ inlined/bread-chisel-releases-26.10.yaml | 6 +++ makefile | 25 +++++---- templates/bread-24.04.yaml.in | 6 +++ templates/bread-25.10.yaml.in | 6 +++ templates/bread-26.04.yaml.in | 6 +++ templates/bread-26.10.yaml.in | 6 +++ templates/bread-chisel-releases-24.04.yaml.in | 6 +++ templates/bread-chisel-releases-25.10.yaml.in | 6 +++ templates/bread-chisel-releases-26.04.yaml.in | 6 +++ templates/bread-chisel-releases-26.10.yaml.in | 6 +++ 22 files changed, 175 insertions(+), 69 deletions(-) diff --git a/.github/workflows/binaries.yaml b/.github/workflows/binaries.yaml index 1018edc..f5bbe09 100644 --- a/.github/workflows/binaries.yaml +++ b/.github/workflows/binaries.yaml @@ -1,8 +1,8 @@ name: Binaries -# Reusable. Cross-compiles chisel + spread (via Canonical's -# ubuntu/go:1.25-26.04_edge builder) and fetches the upstream docker -# static CLI for both arches. Uploads cache/binaries/ + the matching +# Reusable. Cross-compiles chisel + spread + the docker CLI (via +# Canonical's ubuntu/go:1.25-26.04_edge builder) for all target +# arches. Uploads cache/binaries/ + the matching # .stamp/binaries so downstream jobs can short-circuit any rebuild. on: diff --git a/.github/workflows/build-oci.yaml b/.github/workflows/build-oci.yaml index 5120e2c..777fcb8 100644 --- a/.github/workflows/build-oci.yaml +++ b/.github/workflows/build-oci.yaml @@ -1,11 +1,14 @@ name: Build OCI image tarballs -# Reusable. Per-arch native runner builds bread + bread-chisel-releases +# Reusable. Per-arch runner builds bread + bread-chisel-releases # images into the local daemon and `docker save`s each to a # docker-archive tarball. Tarballs upload as artefacts -# (images-amd64, images-arm64) so downstream jobs can stitch a multiarch +# (images-) so downstream jobs can stitch a multiarch # manifest or attach to releases without rebuilding. # +# amd64 / arm64 build on native runners; s390x / ppc64le have no hosted +# runners and build under qemu on amd64 (slow, publish-untested). +# # bread-test is intentionally not built here (test-infra-only). on: @@ -24,13 +27,24 @@ jobs: arch: amd64 - runner: ubuntu-24.04-arm arch: arm64 + - runner: ubuntu-24.04 + arch: s390x + qemu: true + - runner: ubuntu-24.04 + arch: ppc64le + qemu: true runs-on: ${{ matrix.runner }} - timeout-minutes: 30 + # NOTE: 90 min covers the qemu lanes; native lanes finish well under 30. + timeout-minutes: 90 steps: - name: Checkout repository uses: actions/checkout@df4cb1c069e1874edd31b4311f1884172cec0e10 # v6.0.3 + - name: Set up qemu (emulated arches only) + if: matrix.qemu + uses: docker/setup-qemu-action@29109295f81e9208d7d86ff1c6c12d2833863392 # v3.6.0 + - name: Restore cached binaries + stamp uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: diff --git a/.github/workflows/push-ghcr.yaml b/.github/workflows/push-ghcr.yaml index 12e62fc..ffb8474 100644 --- a/.github/workflows/push-ghcr.yaml +++ b/.github/workflows/push-ghcr.yaml @@ -4,7 +4,7 @@ name: Push to GHCR # stitches a multiarch manifest list per (flavour, ver) via buildah, and # pushes each to ghcr.io//{bread,bread-chisel-releases}:. # -# Expects images-amd64 + images-arm64 artefacts to already exist (caller +# Expects images- artefacts (one per arch) to already exist (caller # must have run build-oci.yaml in the same workflow run). on: @@ -23,17 +23,12 @@ jobs: id-token: write steps: - - name: Download amd64 image tarballs + # Each images- artefact lands in its own / dir. + - name: Download per-arch image tarballs uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 with: - name: images-amd64 - path: amd64 - - - name: Download arm64 image tarballs - uses: actions/download-artifact@3e5f45b2cfb9172054b4087a40e8e0b5a5461e7c # v8.0.1 - with: - name: images-arm64 - path: arm64 + pattern: images-* + merge-multiple: false - name: Install buildah run: | @@ -53,10 +48,10 @@ jobs: for ver in 24.04 25.10 26.04 26.10; do m="$flavour-$ver-manifest" buildah manifest create "$m" - buildah manifest add --arch amd64 "$m" \ - "docker-archive:amd64/$flavour-$ver-amd64.tar" - buildah manifest add --arch arm64 "$m" \ - "docker-archive:arm64/$flavour-$ver-arm64.tar" + for arch in amd64 arm64 s390x ppc64le; do + buildah manifest add --arch "$arch" "$m" \ + "docker-archive:images-$arch/$flavour-$ver-$arch.tar" + done buildah manifest push --format oci --all "$m" \ "docker://$REGISTRY/${{ github.repository }}/$flavour:$ver" buildah manifest rm "$m" diff --git a/.github/workflows/release.yaml b/.github/workflows/release.yaml index 9bc2b27..c9c0bf2 100644 --- a/.github/workflows/release.yaml +++ b/.github/workflows/release.yaml @@ -65,15 +65,13 @@ jobs: # inlined yamls verbatim cp inlined/*.yaml release-out/ - # spread binaries: rename to canonical go-release-style names - cp cache/binaries/spread-amd64 release-out/spread-linux-amd64 - cp cache/binaries/spread-arm64 release-out/spread-linux-arm64 - chmod +x release-out/spread-linux-* - - # chisel-hacked binaries - cp cache/binaries/chisel-hacked-amd64 release-out/chisel-hacked-linux-amd64 - cp cache/binaries/chisel-hacked-arm64 release-out/chisel-hacked-linux-arm64 - chmod +x release-out/chisel-hacked-linux-* + # spread + chisel-hacked binaries: rename to canonical + # go-release-style names + for arch in amd64 arm64 s390x ppc64le; do + cp "cache/binaries/spread-$arch" "release-out/spread-linux-$arch" + cp "cache/binaries/chisel-hacked-$arch" "release-out/chisel-hacked-linux-$arch" + done + chmod +x release-out/spread-linux-* release-out/chisel-hacked-linux-* # sha256 sidecars (standard sha256sum format) cd release-out @@ -88,7 +86,7 @@ jobs: run: | set -e cd release-out - for f in spread-linux-amd64 spread-linux-arm64 chisel-hacked-linux-amd64 chisel-hacked-linux-arm64; do + for f in spread-linux-{amd64,arm64,s390x,ppc64le} chisel-hacked-linux-{amd64,arm64,s390x,ppc64le}; do cosign sign-blob --yes \ --bundle "$f.cosign.bundle" \ "$f" @@ -132,7 +130,8 @@ jobs: ``` **precompiled spread binaries** -- statically-linked spread CLI - for linux amd64 / arm64, cross-compiled with go 1.25.x. each + for linux amd64 / arm64 / s390x / ppc64le, cross-compiled with + go 1.25.x. each binary ships with a `.sha256` checksum sidecar and a `.cosign.bundle` keyless signature bundle. diff --git a/hack/build_binaries.sh b/hack/build_binaries.sh index 75a9452..0cc08c7 100755 --- a/hack/build_binaries.sh +++ b/hack/build_binaries.sh @@ -1,7 +1,7 @@ #!/usr/bin/env bash -# Cross-compile chisel + spread for both target arches inside a single -# Canonical ubuntu/go:1.25-26.04_edge container. Output binaries land in -# ./cache/binaries/{chisel,chisel-hacked,spread}-{amd64,arm64}. +# Cross-compile chisel + spread + docker cli for all target arches inside a +# single Canonical ubuntu/go:1.25-26.04_edge container. Output binaries land +# in ./cache/binaries/{chisel,chisel-hacked,spread,docker}-. # # Required env vars (set by makefile): # CHISEL_REF git ref (tag, branch, or SHA) for canonical/chisel @@ -32,8 +32,9 @@ docker run --rm \ -e HGID="$HGID" \ "$GO_BUILDER_IMAGE" -ceuo pipefail ' # Builder runs natively on host arch and cross-compiles via GOARCH for -# the other arch. Both binaries are pure Go (no CGO), so cross-compile +# the other arches. Both binaries are pure Go (no CGO), so cross-compile # is clean. +TARGET_ARCHES="amd64 arm64 s390x ppc64le" # Canonical ubuntu/go image has /usr/bin/go as a broken symlink in some # revisions; pick the actual go binary out of /usr/lib/go-*/bin. @@ -58,7 +59,7 @@ build() { git clone "$repo" "/src/$name" cd "/src/$name" git checkout "$ref" - for arch in amd64 arm64; do + for arch in $TARGET_ARCHES; do echo "==> building $name for $arch" CGO_ENABLED=0 GOOS=linux GOARCH="$arch" \ go build -trimpath -ldflags "-s -w $extra_ldflags" \ @@ -97,7 +98,7 @@ for p in "${patches[@]}"; do done CHISEL_HACKED_VERSION_STRING="${CHISEL_VERSION_STRING}-hacked" echo "==> chisel-hacked version string: $CHISEL_HACKED_VERSION_STRING" -for arch in amd64 arm64; do +for arch in $TARGET_ARCHES; do echo "==> building chisel-hacked for $arch" CGO_ENABLED=0 GOOS=linux GOARCH="$arch" \ go build -trimpath -ldflags "-s -w -X github.com/canonical/chisel/cmd.Version=$CHISEL_HACKED_VERSION_STRING" \ @@ -107,29 +108,25 @@ cd / build spread https://github.com/canonical/spread "$SPREAD_REF" ./cmd/spread -# Ensure curl + tar present for the docker download step. -if ! command -v curl >/dev/null; then - apt-get update - DEBIAN_FRONTEND=noninteractive apt-get install -y --no-install-recommends curl -fi - -# Fetch the upstream docker static tarball for each target arch and extract -# only the docker CLI. Upstream binaries are built with a recent go toolchain -# (1.26+) and so dodge the qemu emulation bug that hits Ubuntu apt'\''s docker.io -# (built with go 1.24). docker.com uses uname-style arch names: aarch64, -# x86_64. -for arch in amd64 arm64; do - case "$arch" in - amd64) docker_arch=x86_64 ;; - arm64) docker_arch=aarch64 ;; - esac - url="https://download.docker.com/linux/static/stable/${docker_arch}/docker-${DOCKER_VERSION}.tgz" - echo "==> downloading docker $DOCKER_VERSION for $arch from $url" - tmpdir=$(mktemp -d) - curl -fsSL "$url" | tar -xz -C "$tmpdir" docker/docker - install -m 0755 "$tmpdir/docker/docker" "/out/docker-$arch" - rm -rf "$tmpdir" +# Build the docker CLI from source for each target arch. docker.com'\''s +# static tarballs only cover x86_64 / aarch64 at current versions (s390x / +# ppc64le stopped at 18.06), and Ubuntu apt'\''s docker.io is built with go +# 1.24 and crashes under qemu emulation -- building from source with the +# go 1.25 toolchain covers all arches uniformly. docker/cli has no go.mod +# (vendor.mod + vendor/ instead); the symlink trick puts it in module mode. +git clone https://github.com/docker/cli /src/docker-cli +cd /src/docker-cli +git checkout "v$DOCKER_VERSION" +ln -s vendor.mod go.mod +ln -s vendor.sum go.sum +for arch in $TARGET_ARCHES; do + echo "==> building docker cli for $arch" + CGO_ENABLED=0 GOOS=linux GOARCH="$arch" \ + go build -mod=vendor -trimpath \ + -ldflags "-s -w -X github.com/docker/cli/cli/version.Version=$DOCKER_VERSION" \ + -o "/out/docker-$arch" ./cmd/docker done +cd / # Hand ownership back to the invoking user so make can read/replace later. chown -R "$HUID:$HGID" /out diff --git a/inlined/bread-24.04.yaml b/inlined/bread-24.04.yaml index e2b1553..3c1fe3a 100644 --- a/inlined/bread-24.04.yaml +++ b/inlined/bread-24.04.yaml @@ -86,6 +86,12 @@ backends: - ubuntu-24.04-arm64: password: bread workers: 2 + - ubuntu-24.04-s390x: + password: bread + workers: 2 + - ubuntu-24.04-ppc64le: + password: bread + workers: 2 suites: tests/: diff --git a/inlined/bread-25.10.yaml b/inlined/bread-25.10.yaml index d413ceb..9908925 100644 --- a/inlined/bread-25.10.yaml +++ b/inlined/bread-25.10.yaml @@ -86,6 +86,12 @@ backends: - ubuntu-25.10-arm64: password: bread workers: 2 + - ubuntu-25.10-s390x: + password: bread + workers: 2 + - ubuntu-25.10-ppc64le: + password: bread + workers: 2 suites: tests/: diff --git a/inlined/bread-26.04.yaml b/inlined/bread-26.04.yaml index 6cffe38..23291ed 100644 --- a/inlined/bread-26.04.yaml +++ b/inlined/bread-26.04.yaml @@ -86,6 +86,12 @@ backends: - ubuntu-26.04-arm64: password: bread workers: 2 + - ubuntu-26.04-s390x: + password: bread + workers: 2 + - ubuntu-26.04-ppc64le: + password: bread + workers: 2 suites: tests/: diff --git a/inlined/bread-26.10.yaml b/inlined/bread-26.10.yaml index 536b27c..2407291 100644 --- a/inlined/bread-26.10.yaml +++ b/inlined/bread-26.10.yaml @@ -86,6 +86,12 @@ backends: - ubuntu-26.10-arm64: password: bread workers: 2 + - ubuntu-26.10-s390x: + password: bread + workers: 2 + - ubuntu-26.10-ppc64le: + password: bread + workers: 2 suites: tests/: diff --git a/inlined/bread-chisel-releases-24.04.yaml b/inlined/bread-chisel-releases-24.04.yaml index c1e2eb8..e96c09c 100644 --- a/inlined/bread-chisel-releases-24.04.yaml +++ b/inlined/bread-chisel-releases-24.04.yaml @@ -91,6 +91,12 @@ backends: - ubuntu-24.04-arm64: password: bread workers: 4 + - ubuntu-24.04-s390x: + password: bread + workers: 4 + - ubuntu-24.04-ppc64le: + password: bread + workers: 4 suites: tests/spread/integration/: diff --git a/inlined/bread-chisel-releases-25.10.yaml b/inlined/bread-chisel-releases-25.10.yaml index 359567f..85e8d7c 100644 --- a/inlined/bread-chisel-releases-25.10.yaml +++ b/inlined/bread-chisel-releases-25.10.yaml @@ -91,6 +91,12 @@ backends: - ubuntu-25.10-arm64: password: bread workers: 4 + - ubuntu-25.10-s390x: + password: bread + workers: 4 + - ubuntu-25.10-ppc64le: + password: bread + workers: 4 suites: tests/spread/integration/: diff --git a/inlined/bread-chisel-releases-26.04.yaml b/inlined/bread-chisel-releases-26.04.yaml index 9001286..dc47701 100644 --- a/inlined/bread-chisel-releases-26.04.yaml +++ b/inlined/bread-chisel-releases-26.04.yaml @@ -91,6 +91,12 @@ backends: - ubuntu-26.04-arm64: password: bread workers: 4 + - ubuntu-26.04-s390x: + password: bread + workers: 4 + - ubuntu-26.04-ppc64le: + password: bread + workers: 4 suites: tests/spread/integration/: diff --git a/inlined/bread-chisel-releases-26.10.yaml b/inlined/bread-chisel-releases-26.10.yaml index 576d9b2..bbdb6e9 100644 --- a/inlined/bread-chisel-releases-26.10.yaml +++ b/inlined/bread-chisel-releases-26.10.yaml @@ -91,6 +91,12 @@ backends: - ubuntu-26.10-arm64: password: bread workers: 4 + - ubuntu-26.10-s390x: + password: bread + workers: 4 + - ubuntu-26.10-ppc64le: + password: bread + workers: 4 suites: tests/spread/integration/: diff --git a/makefile b/makefile index 9aac684..eb95c75 100644 --- a/makefile +++ b/makefile @@ -8,13 +8,17 @@ DOCKER ?= docker CHISEL_REF := v1.4.1 SPREAD_REF := 9fdce848027b944a50d25ed2271f17c213b44bd5 GO_BUILDER_IMAGE := ubuntu/go:1.25-26.04_edge -# Docker CLI fetched from docker.com static; ubuntu apt's docker.io is built -# with go 1.24 and crashes under qemu emulation, so we ship upstream's static. +# Docker CLI built from docker/cli source at tag v$(DOCKER_VERSION); ubuntu +# apt's docker.io is built with go 1.24 and crashes under qemu emulation, and +# docker.com's static tarballs don't cover s390x / ppc64le. DOCKER_VERSION := 29.5.2 # Full matrix. VERSIONS := 24.04 25.10 26.04 26.10 -ARCHES := amd64 arm64 +ARCHES := amd64 arm64 s390x ppc64le +# Arches with native runners (local dev + ci). s390x / ppc64le images build +# under qemu and publish untested; tests + demo stay on the native pair. +NATIVE_ARCHES := amd64 arm64 # Optional narrowing via env vars, e.g.: # make build-bread VER=24.04 @@ -37,8 +41,9 @@ FULL_VER_ARCH := $(foreach v,$(VERSIONS),$(foreach a,$(ARCHES),$(v)-$(a))) BREAD_STAMPS := $(addprefix .stamp/bread-,$(SELECTED_VER_ARCH)) CHISEL_STAMPS := $(addprefix .stamp/bread-chisel-releases-,$(SELECTED_VER_ARCH)) -# The test-host image only exists at 26.04. ARCH narrowing applies. -BREAD_TEST_STAMPS := $(addprefix .stamp/bread-test-26.04-,$(SELECTED_ARCHES)) +# The test-host image only exists at 26.04, native arches only. ARCH +# narrowing applies. +BREAD_TEST_STAMPS := $(addprefix .stamp/bread-test-26.04-,$(if $(strip $(ARCH)),$(ARCH),$(NATIVE_ARCHES))) TEMPLATES := $(wildcard templates/*.yaml.in) INLINED := $(patsubst templates/%.yaml.in,inlined/%.yaml,$(TEMPLATES)) @@ -63,7 +68,7 @@ build-bread: $(BREAD_STAMPS) ## Build bread images (narrow via VER=... ARCH=... build-bread-chisel-releases: $(CHISEL_STAMPS) ## Build bread-chisel-releases images (narrow via VER=... ARCH=...) .PHONY: build-bread-test -build-bread-test: $(BREAD_TEST_STAMPS) ## Build the bread-test (26.04 only, both arches) test-host image +build-bread-test: $(BREAD_TEST_STAMPS) ## Build the bread-test (26.04 only, native arches) test-host image # Run the contract/integration spread suite (tests/spread.yaml). Builds the # test-host image + inlined yamls first. Pass extra spread args via SPREAD_ARGS, @@ -90,11 +95,11 @@ check-base: ## Report upstream ubuntu base-image digest drift (non-zero exit on update-base: ## Rewrite base Dockerfile @sha256 pins to the current upstream digests @hack/check_base.sh --write -# Demo runs only on LTS versions (24.04, 26.04) x both arches, regardless of VER/ARCH narrowing. -DEMO_STAMPS := $(foreach a,$(ARCHES),.stamp/bread-24.04-$(a) .stamp/bread-26.04-$(a)) +# Demo runs only on LTS versions (24.04, 26.04) x native arches, regardless of VER/ARCH narrowing. +DEMO_STAMPS := $(foreach a,$(NATIVE_ARCHES),.stamp/bread-24.04-$(a) .stamp/bread-26.04-$(a)) .PHONY: demo -demo: $(DEMO_STAMPS) ## Run the spread demo on LTS systems (24.04 + 26.04, both arches) +demo: $(DEMO_STAMPS) ## Run the spread demo on LTS systems (24.04 + 26.04, native arches) $(MAKE) -C demo run .PHONY: inlined-yaml-files @@ -157,7 +162,7 @@ nuke-spread: ## Kill stray spread processes + force-remove bread containers clean: ## Remove built images, stamps, generated inlined yamls, cached binaries -@$(foreach va,$(FULL_VER_ARCH), \ $(DOCKER) rmi -f bread:$(va) bread-chisel-releases:$(va) 2>/dev/null ; ) - -@$(foreach a,$(ARCHES), \ + -@$(foreach a,$(NATIVE_ARCHES), \ $(DOCKER) rmi -f bread-test:26.04-$(a) 2>/dev/null ; ) rm -rf .stamp rm -rf cache diff --git a/templates/bread-24.04.yaml.in b/templates/bread-24.04.yaml.in index c842294..9f6a798 100644 --- a/templates/bread-24.04.yaml.in +++ b/templates/bread-24.04.yaml.in @@ -23,6 +23,12 @@ backends: - ubuntu-24.04-arm64: password: bread workers: 2 + - ubuntu-24.04-s390x: + password: bread + workers: 2 + - ubuntu-24.04-ppc64le: + password: bread + workers: 2 suites: tests/: diff --git a/templates/bread-25.10.yaml.in b/templates/bread-25.10.yaml.in index 99772ea..8c5219d 100644 --- a/templates/bread-25.10.yaml.in +++ b/templates/bread-25.10.yaml.in @@ -23,6 +23,12 @@ backends: - ubuntu-25.10-arm64: password: bread workers: 2 + - ubuntu-25.10-s390x: + password: bread + workers: 2 + - ubuntu-25.10-ppc64le: + password: bread + workers: 2 suites: tests/: diff --git a/templates/bread-26.04.yaml.in b/templates/bread-26.04.yaml.in index 3a19a1f..9aabed8 100644 --- a/templates/bread-26.04.yaml.in +++ b/templates/bread-26.04.yaml.in @@ -23,6 +23,12 @@ backends: - ubuntu-26.04-arm64: password: bread workers: 2 + - ubuntu-26.04-s390x: + password: bread + workers: 2 + - ubuntu-26.04-ppc64le: + password: bread + workers: 2 suites: tests/: diff --git a/templates/bread-26.10.yaml.in b/templates/bread-26.10.yaml.in index cbd486b..b808a76 100644 --- a/templates/bread-26.10.yaml.in +++ b/templates/bread-26.10.yaml.in @@ -23,6 +23,12 @@ backends: - ubuntu-26.10-arm64: password: bread workers: 2 + - ubuntu-26.10-s390x: + password: bread + workers: 2 + - ubuntu-26.10-ppc64le: + password: bread + workers: 2 suites: tests/: diff --git a/templates/bread-chisel-releases-24.04.yaml.in b/templates/bread-chisel-releases-24.04.yaml.in index fdc12f5..791d80b 100644 --- a/templates/bread-chisel-releases-24.04.yaml.in +++ b/templates/bread-chisel-releases-24.04.yaml.in @@ -30,6 +30,12 @@ backends: - ubuntu-24.04-arm64: password: bread workers: 4 + - ubuntu-24.04-s390x: + password: bread + workers: 4 + - ubuntu-24.04-ppc64le: + password: bread + workers: 4 suites: tests/spread/integration/: diff --git a/templates/bread-chisel-releases-25.10.yaml.in b/templates/bread-chisel-releases-25.10.yaml.in index a6b720b..a461dda 100644 --- a/templates/bread-chisel-releases-25.10.yaml.in +++ b/templates/bread-chisel-releases-25.10.yaml.in @@ -30,6 +30,12 @@ backends: - ubuntu-25.10-arm64: password: bread workers: 4 + - ubuntu-25.10-s390x: + password: bread + workers: 4 + - ubuntu-25.10-ppc64le: + password: bread + workers: 4 suites: tests/spread/integration/: diff --git a/templates/bread-chisel-releases-26.04.yaml.in b/templates/bread-chisel-releases-26.04.yaml.in index d67af0a..2e8940a 100644 --- a/templates/bread-chisel-releases-26.04.yaml.in +++ b/templates/bread-chisel-releases-26.04.yaml.in @@ -30,6 +30,12 @@ backends: - ubuntu-26.04-arm64: password: bread workers: 4 + - ubuntu-26.04-s390x: + password: bread + workers: 4 + - ubuntu-26.04-ppc64le: + password: bread + workers: 4 suites: tests/spread/integration/: diff --git a/templates/bread-chisel-releases-26.10.yaml.in b/templates/bread-chisel-releases-26.10.yaml.in index 60948be..b14aca6 100644 --- a/templates/bread-chisel-releases-26.10.yaml.in +++ b/templates/bread-chisel-releases-26.10.yaml.in @@ -30,6 +30,12 @@ backends: - ubuntu-26.10-arm64: password: bread workers: 4 + - ubuntu-26.10-s390x: + password: bread + workers: 4 + - ubuntu-26.10-ppc64le: + password: bread + workers: 4 suites: tests/spread/integration/: From 2fcb3d07e808b1f89192603c5870f81cf87cccc6 Mon Sep 17 00:00:00 2001 From: lczyk Date: Fri, 3 Jul 2026 11:35:14 +0100 Subject: [PATCH 2/3] docs: s390x + ppc64le in matrix + docker cli source-build --- README.md | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/README.md b/README.md index a4d689e..c26fe80 100644 --- a/README.md +++ b/README.md @@ -33,10 +33,10 @@ anyway, here is this project's pet bread: ## flavours -two image flavours, each for ubuntu 24.04, 25.10, 26.04, 26.10 x amd64 / arm64, published as multiarch tags at `ghcr.io/lczyk/spread-bread/:`: +two image flavours, each for ubuntu 24.04, 25.10, 26.04, 26.10 x amd64 / arm64 / s390x / ppc64le, published as multiarch tags at `ghcr.io/lczyk/spread-bread/:`. heads-up: s390x + ppc64le images build under qemu and ship untested (no native runners); amd64 + arm64 are tested on every release: - **`bread`** -- base: ubuntu + sshd. general-purpose spread system; the test suite installs whatever else it needs. -- **`bread-chisel-releases`** -- bread + `chisel` + the shell + container tooling typically needed by [chisel-releases](https://github.com/canonical/chisel-releases) spread tests (curl, wget, git, jq, file, sudo, tree, docker, skopeo). `chisel` and `docker` are built from source (canonical/chisel pinned by SHA, docker fetched from docker.com static) so the bundled binaries are go 1.25+ and survive qemu emulation. +- **`bread-chisel-releases`** -- bread + `chisel` + the shell + container tooling typically needed by [chisel-releases](https://github.com/canonical/chisel-releases) spread tests (curl, wget, git, jq, file, sudo, tree, docker, skopeo). `chisel` and `docker` are built from source (canonical/chisel pinned by SHA, docker/cli pinned by version tag) so the bundled binaries are go 1.25+ and survive qemu emulation. ## using (the common case) @@ -56,7 +56,7 @@ available yamls in the release: ## install spread -prefer a precompiled spread CLI over `go install`? same release ships statically-linked binaries for linux amd64 / arm64: +prefer a precompiled spread CLI over `go install`? same release ships statically-linked binaries for linux amd64 / arm64 / s390x / ppc64le: ``` curl -fsSL https://github.com/lczyk/spread-bread/releases/latest/download/spread-linux-amd64 -o /usr/local/bin/spread @@ -87,7 +87,7 @@ the cert-identity regex above is approximate; consult the actual issued cert on spread-bread/ makefile # build images + generate inlined yamls + run contract tests hack/ - build_binaries.sh # cross-compile chisel + spread, fetch docker static, in one ubuntu/go builder + build_binaries.sh # cross-compile chisel + spread + docker cli in one ubuntu/go builder build_image.sh # per-image build w/ hash-stamp short-circuit hash_inputs.sh # per-image input hash (drives stamp invalidation) check_base.sh # detect upstream ubuntu base digest drift; rewrite @sha256 pins @@ -150,8 +150,8 @@ the outer spreads a `bread-test` container; that container runs an inner spread `release.yaml` triggers on push of an `r[0-9]+` tag. on success it: -- builds the binary cache + all images on per-arch native runners. -- pushes 6 multiarch manifests to `ghcr.io/lczyk/spread-bread/{bread,bread-chisel-releases}:`. +- builds the binary cache + all images -- amd64 / arm64 on per-arch native runners, s390x / ppc64le under qemu. +- pushes 8 multiarch manifests to `ghcr.io/lczyk/spread-bread/{bread,bread-chisel-releases}:`. - attaches `inlined/*.yaml` to a rolling github release called `yamls`. older `r*` releases are deleted (release objects only; the underlying tags stay). ci (`ci.yaml`) is build + test on every PR + push to main; no publish. From 0300290921d54607b5e96a1535ce69bfefa4424f Mon Sep 17 00:00:00 2001 From: lczyk Date: Fri, 3 Jul 2026 14:36:06 +0100 Subject: [PATCH 3/3] ci: build qemu-arch images at PR time s390x / ppc64le publish untested, so at least prove the images build before release. build-oci gains a matrix input; ci narrows it to the qemu arches (build-and-test covers the native pair). --- .github/workflows/build-oci.yaml | 23 ++++++++++++----------- .github/workflows/ci.yaml | 11 +++++++++++ 2 files changed, 23 insertions(+), 11 deletions(-) diff --git a/.github/workflows/build-oci.yaml b/.github/workflows/build-oci.yaml index 777fcb8..74065c9 100644 --- a/.github/workflows/build-oci.yaml +++ b/.github/workflows/build-oci.yaml @@ -13,6 +13,17 @@ name: Build OCI image tarballs on: workflow_call: + inputs: + # JSON matrix-include list; callers can narrow to a subset of the + # default (e.g. ci builds only the qemu arches to avoid rebuilding + # what build-and-test already builds natively). + matrix: + type: string + default: >- + [{"runner": "ubuntu-24.04", "arch": "amd64"}, + {"runner": "ubuntu-24.04-arm", "arch": "arm64"}, + {"runner": "ubuntu-24.04", "arch": "s390x", "qemu": true}, + {"runner": "ubuntu-24.04", "arch": "ppc64le", "qemu": true}] permissions: contents: read @@ -22,17 +33,7 @@ jobs: strategy: fail-fast: false matrix: - include: - - runner: ubuntu-24.04 - arch: amd64 - - runner: ubuntu-24.04-arm - arch: arm64 - - runner: ubuntu-24.04 - arch: s390x - qemu: true - - runner: ubuntu-24.04 - arch: ppc64le - qemu: true + include: ${{ fromJSON(inputs.matrix) }} runs-on: ${{ matrix.runner }} # NOTE: 90 min covers the qemu lanes; native lanes finish well under 30. timeout-minutes: 90 diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 6d3b894..ef38bee 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -25,3 +25,14 @@ jobs: build-and-test: needs: binaries uses: ./.github/workflows/build-and-test.yaml + + # Also build the qemu-arch images (s390x / ppc64le) so image breakage + # surfaces at PR time, not at release. Native arches are excluded -- + # build-and-test already builds those. + build-oci: + needs: binaries + uses: ./.github/workflows/build-oci.yaml + with: + matrix: >- + [{"runner": "ubuntu-24.04", "arch": "s390x", "qemu": true}, + {"runner": "ubuntu-24.04", "arch": "ppc64le", "qemu": true}]