ci: publish cac, cac-fpm and shared-httpd multi-arch (amd64 + arm64)
One job per matrix leg on the trusted x86 runner: amd64 built natively, arm64 under QEMU, each pushed BY DIGEST (untagged), then scripts/assemble-multiarch-index.sh creates the existing tags (:phpNN, :latest for php85 / shared-httpd :latest) from this run's digests. The arm64 step is continue-on-error with its own timeout, so an arm64 failure publishes the usual amd64-only tag and a stale arm64 is never re-attached. Build args, base-image pin, pkg-cache probe, php.net EXPECT_PHP_MIN gate, secrets and the cac-litespeed/cac-lsphp/shared-ols jobs are untouched. No Dockerfile change. Adds scripts/tests/multiarch-workflow.test.py (static wiring + tag-scheme execution) to Shell-Checks, and fixes index-platforms.test.sh line 17 which tripped lsphp-info-probe.test.sh's early-exit-reader scan on trunk. Co-Authored-By: Claude Sonnet 5.5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_0185ukXjXyosSkunDsdWz3mb
This commit is contained in:
1 parent
adf74e2f69
commit
01741e735a
3 files changed
+318
-15
No files matched your search
@@ -76,6 +76,11 @@ jobs:
|
||||
./scripts/tests/image-label-amd64.test.sh
|
||||
./scripts/tests/index-platforms.test.sh
|
||||
|
||||
# Static wiring of the multi-arch publish jobs (cac, cac-fpm, shared-httpd):
|
||||
# by-digest pushes, non-fatal arm64 leg, timeouts, exact tag scheme.
|
||||
- name: multi-arch workflow wiring test
|
||||
run: python3 -I scripts/tests/multiarch-workflow.test.py
|
||||
|
||||
- name: lsphp probe regression test
|
||||
run: ./scripts/tests/lsphp-info-probe.test.sh
|
||||
|
||||
@@ -92,6 +97,7 @@ jobs:
|
||||
|
||||
Build-and-Push:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 75
|
||||
strategy:
|
||||
# One PHP version failing (e.g. an EOL stream) must not cancel the
|
||||
# security builds of the others.
|
||||
@@ -143,6 +149,8 @@ jobs:
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
# BuildKit (docker-container driver) ignores dockerd's registry-mirrors,
|
||||
# so the mirror is configured on the builder; BuildKit itself still falls
|
||||
@@ -197,23 +205,64 @@ jobs:
|
||||
username: ${{ secrets.CI_USER }}
|
||||
password: ${{ secrets.CI_TOKEN }}
|
||||
|
||||
- name: Build and Push Image
|
||||
# amd64: required. Pushed untagged BY DIGEST (no tag); failure fails the
|
||||
# job and publishes nothing, exactly as before multi-arch. The tags are only
|
||||
# created by the assemble step below.
|
||||
- name: Build amd64 (push by digest)
|
||||
id: amd64
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
build-args: |
|
||||
PHPVER=${{ matrix.phpver }}
|
||||
CACHE_BUST=${{ steps.bust.outputs.value }}
|
||||
BASE_IMAGE=${{ steps.base.outputs.image }}
|
||||
PKG_CACHE=${{ steps.pkgcache.outputs.url }}
|
||||
EXPECT_PHP_MIN=${{ steps.phpmin.outputs.min }}
|
||||
tags: |
|
||||
repo.anhonesthost.net/cloud-hosting-platform/cac:php${{ matrix.phpver }}
|
||||
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac:latest' || '' }}
|
||||
outputs: type=image,name=repo.anhonesthost.net/cloud-hosting-platform/cac,push-by-digest=true,name-canonical=true,push=true
|
||||
|
||||
# arm64: best effort, built under QEMU on this same trusted x86 runner (no
|
||||
# secret ever leaves it). Same Dockerfile, same build-args (incl. the php.net
|
||||
# EXPECT_PHP_MIN gate, which runs `php -r` on the arm64 binary). Must never
|
||||
# block or alter the amd64 tag: on failure/timeout the tag is published
|
||||
# amd64-only, as before multi-arch.
|
||||
- name: Build arm64 (push by digest)
|
||||
id: arm64
|
||||
continue-on-error: true
|
||||
timeout-minutes: 45
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
platforms: linux/arm64
|
||||
build-args: |
|
||||
PHPVER=${{ matrix.phpver }}
|
||||
CACHE_BUST=${{ steps.bust.outputs.value }}
|
||||
BASE_IMAGE=${{ steps.base.outputs.image }}
|
||||
PKG_CACHE=${{ steps.pkgcache.outputs.url }}
|
||||
EXPECT_PHP_MIN=${{ steps.phpmin.outputs.min }}
|
||||
outputs: type=image,name=repo.anhonesthost.net/cloud-hosting-platform/cac,push-by-digest=true,name-canonical=true,push=true
|
||||
|
||||
# Creates the index tag(s) from THIS run's digests only (a previous run's
|
||||
# arm64 is never re-attached). scripts/assemble-multiarch-index.sh.
|
||||
- name: Assemble index tag(s)
|
||||
env:
|
||||
AMD64_DIGEST: ${{ steps.amd64.outputs.digest }}
|
||||
ARM64_DIGEST: ${{ steps.arm64.outputs.digest }}
|
||||
ARM64_OUTCOME: ${{ steps.arm64.outcome }}
|
||||
PHPVER: ${{ matrix.phpver }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tags=(--tag "php${PHPVER}")
|
||||
# :latest tracks php85 (unchanged tag scheme).
|
||||
[ "$PHPVER" = 85 ] && tags+=(--tag latest)
|
||||
scripts/assemble-multiarch-index.sh \
|
||||
--amd64 "$AMD64_DIGEST" \
|
||||
--arm64 "$ARM64_DIGEST" --arm64-outcome "$ARM64_OUTCOME" \
|
||||
--repo repo.anhonesthost.net/cloud-hosting-platform/cac \
|
||||
"${tags[@]}"
|
||||
|
||||
Build-FPM-Images:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 75
|
||||
strategy:
|
||||
# One PHP version failing (e.g. an EOL stream) must not cancel the
|
||||
# security builds of the others.
|
||||
@@ -265,6 +314,8 @@ jobs:
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
# BuildKit (docker-container driver) ignores dockerd's registry-mirrors,
|
||||
# so the mirror is configured on the builder; BuildKit itself still falls
|
||||
@@ -319,21 +370,62 @@ jobs:
|
||||
username: ${{ secrets.CI_USER }}
|
||||
password: ${{ secrets.CI_TOKEN }}
|
||||
|
||||
- name: Build and Push FPM Image
|
||||
# amd64: required. Pushed untagged BY DIGEST (no tag); failure fails the
|
||||
# job and publishes nothing, exactly as before multi-arch. The tags are only
|
||||
# created by the assemble step below.
|
||||
- name: Build amd64 (push by digest)
|
||||
id: amd64
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
file: ./Dockerfile.fpm
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
build-args: |
|
||||
PHPVER=${{ matrix.phpver }}
|
||||
CACHE_BUST=${{ steps.bust.outputs.value }}
|
||||
BASE_IMAGE=${{ steps.base.outputs.image }}
|
||||
PKG_CACHE=${{ steps.pkgcache.outputs.url }}
|
||||
EXPECT_PHP_MIN=${{ steps.phpmin.outputs.min }}
|
||||
tags: |
|
||||
repo.anhonesthost.net/cloud-hosting-platform/cac-fpm:php${{ matrix.phpver }}
|
||||
${{ matrix.phpver == '85' && 'repo.anhonesthost.net/cloud-hosting-platform/cac-fpm:latest' || '' }}
|
||||
outputs: type=image,name=repo.anhonesthost.net/cloud-hosting-platform/cac-fpm,push-by-digest=true,name-canonical=true,push=true
|
||||
|
||||
# arm64: best effort, built under QEMU on this same trusted x86 runner (no
|
||||
# secret ever leaves it). Same Dockerfile, same build-args (incl. the php.net
|
||||
# EXPECT_PHP_MIN gate, which runs `php -r` on the arm64 binary). Must never
|
||||
# block or alter the amd64 tag: on failure/timeout the tag is published
|
||||
# amd64-only, as before multi-arch.
|
||||
- name: Build arm64 (push by digest)
|
||||
id: arm64
|
||||
continue-on-error: true
|
||||
timeout-minutes: 45
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
file: ./Dockerfile.fpm
|
||||
platforms: linux/arm64
|
||||
build-args: |
|
||||
PHPVER=${{ matrix.phpver }}
|
||||
CACHE_BUST=${{ steps.bust.outputs.value }}
|
||||
BASE_IMAGE=${{ steps.base.outputs.image }}
|
||||
PKG_CACHE=${{ steps.pkgcache.outputs.url }}
|
||||
EXPECT_PHP_MIN=${{ steps.phpmin.outputs.min }}
|
||||
outputs: type=image,name=repo.anhonesthost.net/cloud-hosting-platform/cac-fpm,push-by-digest=true,name-canonical=true,push=true
|
||||
|
||||
# Creates the index tag(s) from THIS run's digests only (a previous run's
|
||||
# arm64 is never re-attached). scripts/assemble-multiarch-index.sh.
|
||||
- name: Assemble index tag(s)
|
||||
env:
|
||||
AMD64_DIGEST: ${{ steps.amd64.outputs.digest }}
|
||||
ARM64_DIGEST: ${{ steps.arm64.outputs.digest }}
|
||||
ARM64_OUTCOME: ${{ steps.arm64.outcome }}
|
||||
PHPVER: ${{ matrix.phpver }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
tags=(--tag "php${PHPVER}")
|
||||
# :latest tracks php85 (unchanged tag scheme).
|
||||
[ "$PHPVER" = 85 ] && tags+=(--tag latest)
|
||||
scripts/assemble-multiarch-index.sh \
|
||||
--amd64 "$AMD64_DIGEST" \
|
||||
--arm64 "$ARM64_DIGEST" --arm64-outcome "$ARM64_OUTCOME" \
|
||||
--repo repo.anhonesthost.net/cloud-hosting-platform/cac-fpm \
|
||||
"${tags[@]}"
|
||||
|
||||
Build-LiteSpeed-Images:
|
||||
runs-on: ubuntu-latest
|
||||
@@ -647,6 +739,7 @@ jobs:
|
||||
|
||||
Build-Shared-httpd:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 50
|
||||
steps:
|
||||
- name: Checkout
|
||||
uses: actions/checkout@v4
|
||||
@@ -692,6 +785,8 @@ jobs:
|
||||
|
||||
- name: Set up QEMU
|
||||
uses: docker/setup-qemu-action@v3
|
||||
with:
|
||||
platforms: arm64
|
||||
|
||||
# BuildKit (docker-container driver) ignores dockerd's registry-mirrors,
|
||||
# so the mirror is configured on the builder; BuildKit itself still falls
|
||||
@@ -717,17 +812,52 @@ jobs:
|
||||
username: ${{ secrets.CI_USER }}
|
||||
password: ${{ secrets.CI_TOKEN }}
|
||||
|
||||
- name: Build and Push Shared httpd Image
|
||||
# amd64: required. Pushed untagged BY DIGEST (no tag); failure fails the
|
||||
# job and publishes nothing, exactly as before multi-arch. The tags are only
|
||||
# created by the assemble step below.
|
||||
- name: Build amd64 (push by digest)
|
||||
id: amd64
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
file: ./Dockerfile.shared-httpd
|
||||
platforms: linux/amd64
|
||||
push: true
|
||||
build-args: |
|
||||
BASE_IMAGE=${{ steps.base.outputs.image }}
|
||||
PKG_CACHE=${{ steps.pkgcache.outputs.url }}
|
||||
tags: |
|
||||
repo.anhonesthost.net/cloud-hosting-platform/shared-httpd:latest
|
||||
outputs: type=image,name=repo.anhonesthost.net/cloud-hosting-platform/shared-httpd,push-by-digest=true,name-canonical=true,push=true
|
||||
|
||||
# arm64: best effort, built under QEMU on this same trusted x86 runner (no
|
||||
# secret ever leaves it). Same Dockerfile, same build-args (incl. the php.net
|
||||
# EXPECT_PHP_MIN gate, which runs `php -r` on the arm64 binary). Must never
|
||||
# block or alter the amd64 tag: on failure/timeout the tag is published
|
||||
# amd64-only, as before multi-arch.
|
||||
- name: Build arm64 (push by digest)
|
||||
id: arm64
|
||||
continue-on-error: true
|
||||
timeout-minutes: 25
|
||||
uses: docker/build-push-action@v6
|
||||
with:
|
||||
file: ./Dockerfile.shared-httpd
|
||||
platforms: linux/arm64
|
||||
build-args: |
|
||||
BASE_IMAGE=${{ steps.base.outputs.image }}
|
||||
PKG_CACHE=${{ steps.pkgcache.outputs.url }}
|
||||
outputs: type=image,name=repo.anhonesthost.net/cloud-hosting-platform/shared-httpd,push-by-digest=true,name-canonical=true,push=true
|
||||
|
||||
# Creates the index tag(s) from THIS run's digests only (a previous run's
|
||||
# arm64 is never re-attached). scripts/assemble-multiarch-index.sh.
|
||||
- name: Assemble index tag(s)
|
||||
env:
|
||||
AMD64_DIGEST: ${{ steps.amd64.outputs.digest }}
|
||||
ARM64_DIGEST: ${{ steps.arm64.outputs.digest }}
|
||||
ARM64_OUTCOME: ${{ steps.arm64.outcome }}
|
||||
run: |
|
||||
set -euo pipefail
|
||||
scripts/assemble-multiarch-index.sh \
|
||||
--amd64 "$AMD64_DIGEST" \
|
||||
--arm64 "$ARM64_DIGEST" --arm64-outcome "$ARM64_OUTCOME" \
|
||||
--repo repo.anhonesthost.net/cloud-hosting-platform/shared-httpd \
|
||||
--tag latest
|
||||
|
||||
Build-Shared-OLS:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
Reference in new issue
Block a user