From 621545c0257ef01233de0c58c89c4f6ea0750cfd Mon Sep 17 00:00:00 2001 From: Claude Date: Tue, 10 Nov 2026 17:58:14 +0000 Subject: [PATCH] fix(container): drop ldconfig's aux-cache so the image builds reproducibly Container Build Verification fails on main: two --no-cache --timestamp 0 builds of one commit differ in one layer. The per-path fingerprints the build jobs print show the only changed path is /var/cache/ldconfig/aux-cache. Wolfi's apk commit hook runs ldconfig after `apk add` in the runtime stage, and the aux-cache records the build host's inode numbers and timestamps. Remove it in the same RUN; ld.so.cache is deterministic and stays. The drift report never named that path in CI: newer gh releases refuse to print job logs that contain ANSI escape codes ("the response contains terminal escape sequences"), so both fingerprint reads failed. Older gh releases lack the override flag, so fetch the logs with curl instead; only 64-hex digest lines pass the existing grep. Checked against run 42868217511's two build logs: the curl pipeline extracts 4320 fingerprint lines from each, and fs-fingerprint-drift.sh reports exactly var/cache/ldconfig/aux-cache. test-fs-fingerprint.sh passes. The image build itself is checked by this PR's CI. Co-Authored-By: Claude Opus 5.5 Claude-Session: https://claude.ai/code/session_0136P7ZnmBahbhfkFEP6ark4 --- .github/workflows/container-ci.yml | 8 +++++++- Containerfile | 6 +++++- 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/.github/workflows/container-ci.yml b/.github/workflows/container-ci.yml index 007020c4..60cc03fb 100644 --- a/.github/workflows/container-ci.yml +++ b/.github/workflows/container-ci.yml @@ -256,7 +256,13 @@ jobs: id=$(gh api "repos/$GITHUB_REPOSITORY/actions/runs/$GITHUB_RUN_ID/attempts/$GITHUB_RUN_ATTEMPT/jobs" \ --paginate --jq ".jobs[] | select(.name == \"$1\") | .id" | head -n 1) [ -n "$id" ] || { echo "::warning::no job named '$1' in this run attempt"; return 1; } - gh api "repos/$GITHUB_REPOSITORY/actions/jobs/$id/logs" \ + # Job logs carry ANSI colour codes, which newer gh releases refuse + # to print ("terminal escape sequences"), and older ones lack the + # override flag. Fetch them with curl; only 64-hex digest lines + # survive the grep. -L follows the signed redirect without + # forwarding the token to the other host. + curl -fsSL --proto '=https' -H "Authorization: Bearer $GH_TOKEN" \ + "${GITHUB_API_URL:-https://api.github.com}/repos/$GITHUB_REPOSITORY/actions/jobs/$id/logs" \ | sed -E 's/^[0-9]{4}-[0-9]{2}-[0-9]{2}T[0-9:.]+Z //' \ | sed -n '/^FS-FINGERPRINT-BEGIN$/,/^FS-FINGERPRINT-END$/p' \ | grep -E '^[0-9a-f]{64} ' diff --git a/Containerfile b/Containerfile index 16e7a64c..5cf199d5 100644 --- a/Containerfile +++ b/Containerfile @@ -87,11 +87,15 @@ LABEL org.opencontainers.image.licenses="MPL-2.0" LABEL org.opencontainers.image.version="1.5.0" LABEL org.opencontainers.image.vendor="hyperpolymath" +# Wolfi's apk commit hook runs ldconfig, whose aux-cache records the build +# host's inode numbers and timestamps. Drop it so two builds of one commit +# give the same layer; ld.so.cache itself is deterministic and kept. RUN apk add --no-cache \ ca-certificates \ libssl3 \ gmp \ - libstdc++ + libstdc++ \ + && rm -f /var/cache/ldconfig/aux-cache WORKDIR /app