fix(ci): skip the BuildKit check whose warning embedded this Dockerfile in CI output
Lint / hadolint (push) Successful in 10s
Lint / skill-floor (push) Failing after 13s
Lint / doc-drift (push) Successful in 18s
Lint / actionlint (push) Successful in 33s
Publish Docker Image / lint-gate (push) Successful in 32s
Publish Docker Image / resolve-versions (push) Successful in 17s
Publish Docker Image / base-decide (push) Successful in 13s
Publish Docker Image / build-base (push) Has been skipped
Publish Docker Image / smoke-studio (push) Successful in 5m38s
Publish Docker Image / smoke (push) Successful in 8m20s
Publish Docker Image / build-variant-studio (push) Successful in 20m34s
Publish Docker Image / build-variant (push) Successful in 21m5s
Publish Docker Image / update-description (push) Successful in 8s
Publish Docker Image / promote-base-latest (push) Successful in 9s
Lint / hadolint (push) Successful in 10s
Lint / skill-floor (push) Failing after 13s
Lint / doc-drift (push) Successful in 18s
Lint / actionlint (push) Successful in 33s
Publish Docker Image / lint-gate (push) Successful in 32s
Publish Docker Image / resolve-versions (push) Successful in 17s
Publish Docker Image / base-decide (push) Successful in 13s
Publish Docker Image / build-base (push) Has been skipped
Publish Docker Image / smoke-studio (push) Successful in 5m38s
Publish Docker Image / smoke (push) Successful in 8m20s
Publish Docker Image / build-variant-studio (push) Successful in 20m34s
Publish Docker Image / build-variant (push) Successful in 21m5s
Publish Docker Image / update-description (push) Successful in 8s
Publish Docker Image / promote-base-latest (push) Successful in 9s
v1.10.1 (run 707) failed with ZERO failing steps: every step Success, `smoke` printing "101 passed, 0 failed", `smoke-studio` "104 passed, 0 failed", both jobs red. The clipboard fix fromf3b3748worked exactly as predicted; this is a second, independent defect that run 704 had masked. CHAIN, measured end to end rather than reasoned: `ARG BASE_IMAGE` has no default on purpose (the two-phase build always supplies it), which trips BuildKit's InvalidDefaultArgInFrom check. buildx attaches that warning's source context to the build metadata as buildx.build.warnings[].sourceInfo.data — the ENTIRE Dockerfile, base64, on ONE line. docker/build-push-action writes that metadata to $GITHUB_OUTPUT as a `name<<ghadelimiter_<uuid>` heredoc. Gitea's act_runner truncates any single line at exactly 65536 chars, so the closing delimiter was cut off: invalid format delimiter 'ghadelimiter_...' not found before end of file and the runner failed the job while attributing it to no step at all. v1.9.4 run 695 SUCCESS: longest metadata line 56355, 0 delimiter errors v1.10.0 run 704 failed : longest metadata line 65536, 1 delimiter error v1.10.1 run 707 failed : longest metadata line 65536, 1 delimiter error 65536 = 2^16: cut AT the cap, not merely long. Independent route via file size rather than log parsing: 42251 B at v1.9.4 (base64 56335, matching the log) vs 50034 B now (base64 66712, truncated). The cap corresponds to a 49152 B Dockerfile, so this cycle's comment growth crossed it by 882 B. Located by asking which top-level metadata key CONTAINS the base64, instead of assuming: it is buildx.build.warnings -> sourceInfo -> data in BOTH runs. THIS IS THE SECOND FIX FOR THIS BUG. The first, `provenance: false` on the two smoke build steps, was committed as784fad7and is REVERTED here: a real buildx on another host showed provenance metadata present in both modes with a longest string of 71 chars, i.e. the base64 was never in provenance. Shipping it would have left the release broken a third time while looking like a fix. Also rejected, each measured: floating action tags moving (act action-bundle hashes byte-identical between runs 695 and 707, all four) and the build-check annotation text changing (byte-identical). FIX: `# check=skip=InvalidDefaultArgInFrom` as the FIRST line of Dockerfile.variant — BuildKit parses `# check=` only before any other line, so placement is load-bearing. No honest default exists for BASE_IMAGE: `scratch` would satisfy the linter while being a lie, and would convert today's instant "invalid reference format" into a failure deep in the build. Verified against the actual edited file with `docker buildx build --check`: "Check complete, no warnings found." Zero warnings means no sourceInfo, so the longest metadata line drops 65536 -> ~1936 and the file's SIZE stops gating CI. GUARD: scripts/check-dockerfile-directives.sh, wired into BOTH lint.yml and docker-publish.yml's lint-gate, because a check that gates only `push` lets a tag regress — the adoption slip that let doc-drift land 27 h after the v1.9.3 tag. It also fails if ARG BASE_IMAGE gains a default, so the directive cannot rot into guarding a check that can no longer fire. Truth table, exit codes: present 0, removed 1, demoted to line 2 → 1, ARG defaulted 1, file missing 2 (a gate that cannot run must not pass). Release renamed v1.10.1 -> v1.10.2 with both failed tags left standing as tombstones. Docs swept again (README "since" marker, Dockerfile decision comments) because CI reads them from the TAG. Gates: doc-drift 23 OK / 0 DRIFT; base-hash, workflow-shell, skill-floor, lint-shell (17 files now), dockerfile-directives all rc=0.
This commit is contained in:
+66
-12
@@ -11,21 +11,73 @@ Pre-v1.0.0 tags followed the pi npm version (`v{pi_version}[letter]`).
|
||||
|
||||
---
|
||||
|
||||
## v1.10.1 — 2026-10-02
|
||||
## v1.10.2 — 2026-10-02
|
||||
|
||||
**v1.10.0 was tagged and never published.** Its tag build (run 704) failed one
|
||||
assertion out of 104 — a smoke check that required a pi dependency upstream had
|
||||
deliberately deleted — so every publish job skipped and no image, no `latest`,
|
||||
no Hub description was ever written. v1.10.1 is that same release plus the fix
|
||||
to the assertion: **everything described under v1.10.0 below ships here**, and
|
||||
that section remains the content record for this release. Nothing in it changed.
|
||||
**v1.10.0 and v1.10.1 were both tagged and never published.** Neither failure
|
||||
was in the image — both were in the test and CI harness, and each hid the other:
|
||||
|
||||
The tag number moves rather than being re-pointed because CI had already
|
||||
consumed v1.10.0; a version that failed its build should stay failed and
|
||||
readable, not be quietly overwritten with different bytes.
|
||||
| tag | run | symptom | cause |
|
||||
|---|---|---|---|
|
||||
| v1.10.0 | 704 | `smoke` 100 passed / **1 failed**; `smoke-studio` 103 / **1** | a smoke assertion required a pi dependency upstream had deleted |
|
||||
| v1.10.1 | 707 | `smoke` **101 passed / 0 failed**, `smoke-studio` **104 / 0**, and both jobs red anyway with **no failing step** | base64(`Dockerfile.variant`) in buildx's warning metadata crossed act_runner's 64 KiB line cap |
|
||||
|
||||
In both runs every publish job skipped, so no image, no `latest`, and no Hub
|
||||
description was ever written — the gates did their job twice. **Everything
|
||||
described under v1.10.0 below ships here**; that section remains the content
|
||||
record and nothing in it changed.
|
||||
|
||||
The tag number moves each time rather than being re-pointed, because CI had
|
||||
already consumed the previous one. A version that failed its build should stay
|
||||
failed and readable, not be quietly overwritten with different bytes.
|
||||
|
||||
### Fixed
|
||||
|
||||
- **A job can fail with every step green, a smoke suite reporting `0 failed`,
|
||||
and no failing step anywhere — and it cost two tags** — `Dockerfile.variant`
|
||||
now opens with `# check=skip=InvalidDefaultArgInFrom`, and
|
||||
`scripts/check-dockerfile-directives.sh` keeps it there.
|
||||
|
||||
The chain, measured rather than reasoned: `ARG BASE_IMAGE` deliberately has no
|
||||
default (the two-phase build always supplies it), which trips BuildKit's
|
||||
`InvalidDefaultArgInFrom` check. buildx attaches that warning's source context
|
||||
to the build metadata as `buildx.build.warnings[].sourceInfo.data` — **the
|
||||
entire Dockerfile, base64, on one line**. `docker/build-push-action` writes
|
||||
that metadata to `$GITHUB_OUTPUT` as a `name<<ghadelimiter_<uuid>` heredoc,
|
||||
and Gitea's act_runner truncates any single line at exactly 65536 chars. Once
|
||||
base64 of the file passed 64 KiB the closing delimiter was cut off and the
|
||||
runner reported `invalid format delimiter 'ghadelimiter_...' not found before
|
||||
end of file`, then failed the job while attributing it to nothing.
|
||||
|
||||
Numbers: the file was 42251 B at v1.9.4 → base64 56355 chars, fine; it is
|
||||
50034 B now → base64 66712, truncated to exactly 65536 (2^16, i.e. cut *at*
|
||||
the cap, not merely long). The cap corresponds to a 49152 B Dockerfile, so
|
||||
this release's comment growth — much of it comments added while documenting
|
||||
the v1.10.0 round — crossed it by **882 bytes**. Confirmed two ways: by
|
||||
parsing the metadata out of both job logs, and independently by arithmetic on
|
||||
the file size at each tag. Verified fixed by running `docker buildx build
|
||||
--check` against the actual edited file: *"Check complete, no warnings
|
||||
found."* With zero warnings there is no `sourceInfo`, so the longest metadata
|
||||
line drops from 65536 to ~1936 chars and the Dockerfile's **size stops being
|
||||
coupled to whether CI passes**.
|
||||
|
||||
Hypotheses measured and rejected on the way, each of which would have produced
|
||||
a wrong fix: floating action tags moving (the act action-bundle hashes are
|
||||
byte-identical between the green v1.9.4 run and the red one — all four); the
|
||||
build-check annotation text changing (byte-identical); and `provenance: false`,
|
||||
which was written, tested against a real buildx, and **reverted** when the
|
||||
metadata turned out to carry the base64 under `buildx.build.warnings`, not
|
||||
under provenance. The published images are unaffected either way: they are
|
||||
built by raw `docker buildx build --push`, which never writes
|
||||
`$GITHUB_OUTPUT` metadata.
|
||||
|
||||
The new guard runs in **both** `lint.yml` and the publish workflow's
|
||||
`lint-gate`, because a check that gates only `push` lets a tag regress — the
|
||||
same adoption slip that let doc-drift land 27 h after the v1.9.3 tag. It
|
||||
also fails if `ARG BASE_IMAGE` ever gains a default, so the skip directive
|
||||
cannot rot into pointing at a check that can no longer fire. Truth table:
|
||||
directive present → rc=0; removed → rc=1; demoted to line 2 → rc=1; ARG given
|
||||
a default → rc=1; file missing → rc=2 (cannot-run must not pass).
|
||||
|
||||
- **The smoke suite asserted a pi dependency that upstream deleted, and it cost
|
||||
this release its first tag build** — `scripts/smoke-test.sh` required
|
||||
`@mariozechner/clipboard` to be installed and `require()`-able at every install
|
||||
@@ -60,13 +112,15 @@ readable, not be quietly overwritten with different bytes.
|
||||
|
||||
---
|
||||
|
||||
## v1.10.0 — 2026-10-02 (tagged, never published — superseded by v1.10.1)
|
||||
## v1.10.0 — 2026-10-02 (tagged, never published — content shipped as v1.10.2)
|
||||
|
||||
> Tagged 2026-10-02 at commit `12f99c4`. Its build (run 704) went red on the
|
||||
> stale clipboard assertion described under v1.10.1, so `build-variant`,
|
||||
> `build-variant-studio`, `promote-base-latest` and `update-description` all
|
||||
> skipped and nothing reached the Hub. No image carries this tag. The content
|
||||
> below is accurate and shipped as **v1.10.1**.
|
||||
> below is accurate and shipped as **v1.10.2**. v1.10.1 (commit `c2c42c3`,
|
||||
> run 707) was the first attempt at republishing it and died on the separate
|
||||
> act_runner line-cap bug described under v1.10.2.
|
||||
|
||||
Three small fixes found by the v1.9.4 first-boot acceptance and the CI base
|
||||
hash prediction, plus one boot-time wiring fix that stops a recurring `git push`
|
||||
|
||||
Reference in New Issue
Block a user