Files
computer-playbook/scripts/image/push.sh
kevinveenbirkenbachandClaude Opus 5 7b37a7970f fix(image): let a failed cache export fail the build
ignore-error traded a loud fault for a silent one. The cache writes to
the same GHCR repository as the image and under the same packages:write
token, so every shared failure mode -- permissions, outage, rate limit --
already fails --push. What remains is buildkit's own cache manifest type,
which a registry can reject while accepting an ordinary image push.

That case is exactly the one worth hearing about. Swallowed, it leaves CI
green while the cache never fills and every build silently pays the full
855-899s again; raised, the first run answers it once and for good.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
2026-09-16 21:04:15 +02:00

67 lines
2.6 KiB
Bash
Executable File

#!/usr/bin/env bash
set -euo pipefail
script_dir="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
: "${MATRIX_DISTRO:?Missing MATRIX_DISTRO}"
export INFINITO_DISTRO="${MATRIX_DISTRO}"
# shellcheck source=scripts/meta/env/load.sh
source "${script_dir}/../meta/env/load.sh"
: "${BUILD_CONTEXT_DIR:?Missing BUILD_CONTEXT_DIR}"
: "${IMAGE_TAG:?Missing IMAGE_TAG}"
: "${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")"
cache_ref="ghcr.io/${ghcr_owner}/${repo_name}/${MATRIX_DISTRO}:buildcache"
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" \
--push \
--tag "ghcr.io/${ghcr_owner}/${repo_name}/${MATRIX_DISTRO}:${IMAGE_TAG}" \
--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