mirror of
https://github.com/kevinveenbirkenbach/computer-playbook.git
synced 2026-11-08 19:56:53 +00:00
Building every architecture in one job through QEMU took the image job from under ten minutes to over two hours: each arm64 layer after 'COPY .' reran emulated on every commit, on a four-vCPU runner. Each architecture builds on its own runner again, but push.sh now pushes by digest only and records the digest per distro and architecture, so no per-architecture tag exists. A merge job collects every architecture's digests and manifest_all.sh publishes the plain tag as one manifest list, refusing a distro that lacks a digest for any architecture in the pool. The build cache is per architecture again so the two jobs do not overwrite each other's cache. The binfmt mirror entry goes with the emulation, and ADR 0002 records the measured reason. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
79 lines
3.2 KiB
Bash
Executable File
79 lines
3.2 KiB
Bash
Executable File
#!/usr/bin/env bash
|
|
set -euo pipefail
|
|
|
|
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
|
|
|
: "${MATRIX_DISTRO:?Missing MATRIX_DISTRO}"
|
|
IMAGE_ARCH="${IMAGE_ARCH:-$("${script_dir}/../meta/resolve/architecture.sh")}"
|
|
export INFINITO_DISTRO="${MATRIX_DISTRO}"
|
|
|
|
# shellcheck source=scripts/meta/env/load.sh
|
|
source "${script_dir}/../meta/env/load.sh"
|
|
|
|
INFINITO_PARENT_IMAGE="$("${script_dir}/../meta/resolve/image/parent.sh")"
|
|
export INFINITO_PARENT_IMAGE
|
|
|
|
: "${BUILD_CONTEXT_DIR:?Missing BUILD_CONTEXT_DIR}"
|
|
: "${IMAGE_DIGEST_DIR:?Missing IMAGE_DIGEST_DIR}"
|
|
: "${GITHUB_REPOSITORY:?Missing GITHUB_REPOSITORY}"
|
|
: "${USE_NIX_TOKEN:?Missing USE_NIX_TOKEN}"
|
|
: "${INFINITO_PARENT_IMAGE:?Missing INFINITO_PARENT_IMAGE; source scripts/meta/env/load.sh}"
|
|
: "${INFINITO_SRC_DIR:?Missing INFINITO_SRC_DIR; source scripts/meta/env/load.sh}"
|
|
: "${INFINITO_VENV_DIR:?Missing INFINITO_VENV_DIR; source scripts/meta/env/load.sh}"
|
|
ghcr_owner="$(scripts/meta/resolve/repository/owner.sh)"
|
|
repo_name="$("${script_dir}/../meta/resolve/repository/name.sh")"
|
|
|
|
image="ghcr.io/${ghcr_owner}/${repo_name}/${MATRIX_DISTRO}"
|
|
cache_ref="${image}:buildcache-${IMAGE_ARCH}"
|
|
metadata="$(mktemp)"
|
|
|
|
max_attempts="${MAX_ATTEMPTS:-7}"
|
|
retry_delay_seconds="${RETRY_DELAY_SECONDS:-20}"
|
|
attempt=1
|
|
|
|
nix_arg=()
|
|
if [[ "${USE_NIX_TOKEN}" == "true" ]]; then
|
|
: "${NIX_GITHUB_TOKEN:?Missing NIX_GITHUB_TOKEN}"
|
|
nix_arg=(--build-arg "NIX_CONFIG=access-tokens = github.com=${NIX_GITHUB_TOKEN}")
|
|
else
|
|
echo "pull_request_target on fork detected: skipping NIX_CONFIG token build-arg."
|
|
fi
|
|
|
|
while true; do
|
|
echo "=== Build & push attempt ${attempt}/${max_attempts} ==="
|
|
|
|
if docker buildx build \
|
|
--file "${BUILD_CONTEXT_DIR}/Dockerfile" \
|
|
--platform "linux/${IMAGE_ARCH}" \
|
|
--output "type=image,name=${image},push-by-digest=true,name-canonical=true,push=true" \
|
|
--metadata-file "${metadata}" \
|
|
--label "org.opencontainers.image.source=https://github.com/${GITHUB_REPOSITORY}" \
|
|
--build-arg "INFINITO_PARENT_IMAGE=${INFINITO_PARENT_IMAGE}" \
|
|
--build-arg "INFINITO_SRC_DIR=${INFINITO_SRC_DIR}" \
|
|
--build-arg "INFINITO_VENV_DIR=${INFINITO_VENV_DIR}" \
|
|
--build-arg "INFINITO_PACKAGE_INSTALL_SCRIPT=${INFINITO_PACKAGE_INSTALL_SCRIPT:?source scripts/meta/env/load.sh}" \
|
|
--build-arg "INFINITO_PYTHON_INSTALL_SCRIPT=${INFINITO_PYTHON_INSTALL_SCRIPT:?source scripts/meta/env/load.sh}" \
|
|
--build-arg "INFINITO_DOCKER_CLI_INSTALL_SCRIPT=${INFINITO_DOCKER_CLI_INSTALL_SCRIPT:?source scripts/meta/env/load.sh}" \
|
|
"${nix_arg[@]}" \
|
|
--cache-from "type=registry,ref=${cache_ref}" \
|
|
--cache-to "type=registry,mode=max,ref=${cache_ref}" \
|
|
"${BUILD_CONTEXT_DIR}"; then
|
|
echo "Build & push succeeded on attempt ${attempt}/${max_attempts}."
|
|
break
|
|
fi
|
|
|
|
if [[ "${attempt}" -ge "${max_attempts}" ]]; then
|
|
echo "Build & push failed after ${max_attempts} attempts."
|
|
exit 1
|
|
fi
|
|
|
|
echo "Attempt ${attempt} failed. Retrying in ${retry_delay_seconds}s..."
|
|
sleep "${retry_delay_seconds}"
|
|
attempt=$((attempt + 1))
|
|
done
|
|
|
|
mkdir -p "${IMAGE_DIGEST_DIR}"
|
|
jq -er '."containerimage.digest"' "${metadata}" >"${IMAGE_DIGEST_DIR}/${MATRIX_DISTRO}.${IMAGE_ARCH}"
|
|
rm -f "${metadata}"
|
|
echo "Pushed ${image}@$(cat "${IMAGE_DIGEST_DIR}/${MATRIX_DISTRO}.${IMAGE_ARCH}") for linux/${IMAGE_ARCH}."
|