From 784fad78f32d799bfa0341474cf05014f6af9715 Mon Sep 17 00:00:00 2001 From: Joakim Persson Date: Fri, 2 Oct 2026 10:50:16 +0200 Subject: [PATCH] =?UTF-8?q?fix(ci):=20provenance:=20false=20on=20the=20smo?= =?UTF-8?q?ke=20builds=20=E2=80=94=20base64(Dockerfile)=20crossed=2064=20K?= =?UTF-8?q?iB?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit v1.10.1 (run 707) failed with ZERO failing steps: every step reported Success, `smoke` printed "Results: 101 passed, 0 failed", `smoke-studio` printed "104 passed, 0 failed", and both jobs went red anyway. The clipboard fix worked exactly as predicted; this is a second, independent defect that run 704 hid. MECHANISM, measured end to end: buildx writes a provenance attestation into the metadata it returns, and that metadata embeds the ENTIRE Dockerfile as a single base64 "data" field on ONE line. docker/build-push-action writes that metadata to $GITHUB_OUTPUT as a `name<` heredoc. Gitea's act_runner truncates any single line at exactly 65536 chars, so once base64(Dockerfile.variant) crosses 64 KiB the closing delimiter is cut off and the runner reports invalid format delimiter 'ghadelimiter_...' not found before end of file then fails the job while attributing it to no step at all. v1.9.4 run 695 (SUCCESS): longest metadata line 56355 chars, 0 delimiter errors v1.10.0 run 704 (failed) : longest metadata line 65536 chars, 1 delimiter error v1.10.1 run 707 (failed) : longest metadata line 65536 chars, 1 delimiter error 65536 is exactly 2^16 — the line was TRUNCATED at the cap, not merely long. Independent route via file size, not log parsing: Dockerfile.variant was 42251 B at v1.9.4 (base64 56335, matching the log) and is 50034 B at HEAD (base64 66712, cut to 65536). The cap corresponds to a 49152 B Dockerfile, so this cycle's comment growth (+7783 B, mostly comments I wrote) crossed it by 882 B. Hypotheses measured and REJECTED before landing this: - floating action tags moved: the act action-bundle hashes are IDENTICAL between run 695 and run 707 (all four), so no action changed version. - build-check annotation changed: the ::warning text is byte-identical. - stale clipboard assertion again: no, the suites print 0 failed. WHY provenance: false and not shorter comments — trimming would restore the margin and silently re-arm the trap for the next comment, with a failure mode of "job red, no failing step, suite green", which cost most of this session to diagnose once. Dropping the attestation removes the Dockerfile-size coupling entirely. BLAST RADIUS IS NIL for what ships: these two steps build with `load: true` and the images are discarded after the suite runs, so the attestation has no consumer. The PUBLISHED images are built by raw `docker buildx build --push` in run: blocks (three call sites), which never write $GITHUB_OUTPUT metadata and are therefore both unaffected by the bug and unchanged by this fix. Verified: YAML parses; check-workflow-shell rc=0; doc-drift 23 OK / 0 DRIFT. Next step is a `smoke_only=true` dispatch against main — the escape hatch this workflow already documents — so the fix is proven before another tag is cut. --- .gitea/workflows/docker-publish.yml | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/.gitea/workflows/docker-publish.yml b/.gitea/workflows/docker-publish.yml index fa9b8ff..6257531 100644 --- a/.gitea/workflows/docker-publish.yml +++ b/.gitea/workflows/docker-publish.yml @@ -593,6 +593,28 @@ jobs: platforms: linux/amd64 push: false load: true + # provenance: false is LOAD-BEARING, not hygiene. buildx writes a + # provenance attestation into the metadata it hands back, and that + # metadata embeds the ENTIRE Dockerfile as one base64 "data" field on a + # single line. build-push-action writes the metadata to $GITHUB_OUTPUT + # as a `name<` heredoc, and Gitea's act_runner + # truncates any single line at exactly 65536 chars — so once + # base64(Dockerfile.variant) crosses 64 KiB the closing delimiter is + # cut off and the runner fails the job with + # invalid format delimiter 'ghadelimiter_...' not found before end of file + # and NO failing step: every step reports Success, the smoke suite + # reports "0 failed", and the job is red anyway. + # Measured: Dockerfile.variant was 42251 B at v1.9.4 (base64 56355, + # fine) and 50034 B at v1.10.1 (base64 66712, truncated to 65536) — + # the cap corresponds to a 49152 B Dockerfile, so the v1.10.0/v1.10.1 + # comment growth crossed it by 882 B. v1.10.0 run 704 and v1.10.1 + # run 707 both died here; in 704 it hid behind a stale clipboard + # assertion. Trimming comments would "fix" it until the next comment. + # These smoke images are built with load: true and thrown away, so the + # attestation has no consumer. The PUBLISHED images are built by raw + # `docker buildx build --push` in run: blocks, which never writes + # $GITHUB_OUTPUT metadata — so this changes nothing about what ships. + provenance: false tags: pi-devbox:smoke build-args: | BASE_IMAGE=${{ env.IMAGE }}:${{ needs.base-decide.outputs.base_tag }} @@ -658,6 +680,28 @@ jobs: platforms: linux/amd64 push: false load: true + # provenance: false is LOAD-BEARING, not hygiene. buildx writes a + # provenance attestation into the metadata it hands back, and that + # metadata embeds the ENTIRE Dockerfile as one base64 "data" field on a + # single line. build-push-action writes the metadata to $GITHUB_OUTPUT + # as a `name<` heredoc, and Gitea's act_runner + # truncates any single line at exactly 65536 chars — so once + # base64(Dockerfile.variant) crosses 64 KiB the closing delimiter is + # cut off and the runner fails the job with + # invalid format delimiter 'ghadelimiter_...' not found before end of file + # and NO failing step: every step reports Success, the smoke suite + # reports "0 failed", and the job is red anyway. + # Measured: Dockerfile.variant was 42251 B at v1.9.4 (base64 56355, + # fine) and 50034 B at v1.10.1 (base64 66712, truncated to 65536) — + # the cap corresponds to a 49152 B Dockerfile, so the v1.10.0/v1.10.1 + # comment growth crossed it by 882 B. v1.10.0 run 704 and v1.10.1 + # run 707 both died here; in 704 it hid behind a stale clipboard + # assertion. Trimming comments would "fix" it until the next comment. + # These smoke images are built with load: true and thrown away, so the + # attestation has no consumer. The PUBLISHED images are built by raw + # `docker buildx build --push` in run: blocks, which never writes + # $GITHUB_OUTPUT metadata — so this changes nothing about what ships. + provenance: false tags: pi-devbox:smoke-studio build-args: | BASE_IMAGE=${{ env.IMAGE }}:${{ needs.base-decide.outputs.base_tag }}