Skip to content

Fix ci - #2

Merged
sittner merged 6 commits into
mainfrom
fix-ci
Aug 3, 2026
Merged

Fix ci#2
sittner merged 6 commits into
mainfrom
fix-ci

Conversation

@sittner

@sittner sittner commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

No description provided.

sittner and others added 6 commits August 3, 2026 15:35
Both boards compiled for over an hour and then failed in binary-headers:

  HOSTCC  debian/linux-headers-.../scripts/basic/fixdep
  fixdep.c:92:10: fatal error: sys/types.h: No such file or directory

install_kernel_headers in scripts/package/builddeb deliberately overrides
CC with <target>-gcc when cross compiling, so the fixdep and modpost
shipped in linux-headers are arm64 binaries that run on the Pi. That is
the only step in the whole build that compiles userspace code for the
target, and it needs libc6-dev-arm64-cross - kernel code is freestanding
and never includes libc headers, so an hour of successful kernel
compilation says nothing about it. --no-install-recommends kept it off
the runner.

Add a preflight probe that compiles a trivial program including
<sys/types.h> with the cross toolchain, which reproduces the exact error
in about a second and names the missing package. Verified both ways: it
passes with a real toolchain and fails with a stub cross gcc.

Not a problem, checked while here: the headers package also ships
resolve_btfids built for the build machine, but cmd_btf_ko skips BTF
generation when vmlinux is absent, which it is in a headers package, so
out-of-tree module builds on the Pi never execute it.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
`./scripts/build.sh smoke` builds a tinyconfig kernel through the
complete bindeb-pkg path in ~7 minutes cold, ~2 incremental, and then
checks what came out: the image package carries vmlinuz and a .ko, and
the headers package's fixdep is an AArch64 binary. That last assertion is
the one that was worth writing - if it ever regresses, out-of-tree module
builds on the Pi break and nothing else in the pipeline notices.

It immediately earned its keep by exposing a much worse bug in
resolve-kernel-ref.sh. The GitHub commit listing spans the whole
reachable history, so with the branch tip now at 6.18.42, v6.18.40
resolved to 6a7ecc25 - an upstream stable commit with none of the Pi
patches: no bcm2711_defconfig, no Pi drivers. The v6.18.34 resolution
reported earlier was wrong the same way. Only the fast path, where the
requested version is still at the branch tip, was ever correct.

Resolution now runs over the branch's first-parent history, every
ancestor of which is a Pi-branch commit by construction, via a
commits-only fetch (--filter=tree:0) and a binary search over the
version, and the result must contain bcm2711_defconfig. v6.18.40 now
resolves to 1047a719 ("usb: xhci: Partial revert to upstream", 6.18.40,
defconfig present) and both boards configure cleanly against it again.

The CI gates deliberately run against rpi-6.18.y rather than a pinned
version: they check that these scripts still work against the current
branch, and it avoids a history fetch in three jobs.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The v6.18.40-4 build died three seconds in, before any real work, with
exit code 23. That is curl's CURLE_WRITE_ERROR: parse_makefile_version
was an awk that exits at EXTRAVERSION, line 5, which closes the pipe
while curl is still writing the ~70 KB Makefile, and set -o pipefail
turns the writer's failure into a failure of the whole script. Whether it
bites depends on who wins the pipe-buffer race, which is why it passed
here every time - five straight attempts against the real URL - and
failed on the runner.

The Makefile is now downloaded to a file and read from it, the git probe
uses command substitution instead of a pipe, and the parser reads to EOF
in an END block. Any one of those three fixes it; all three are cheap.

Same class of bug as the dpkg-deb | grep -q in the package verification,
so the remaining pipelines were audited too: build.sh's pahole version
check (sort | head -1) and ci.yml's shellcheck --version | head -2 are
the only other consumers that could exit early, and both are now safe.
Everything else pipes into tail, cut, tr or sed without q, which drain
their input.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The release job is the one step nothing has ever run: it only executes
after a successful build, so any mistake in it costs a full build to
discover. Its release notes were a multi-line shell string, which put
shell quoting rules on markdown backticks for no reason.

Notes now go through a quoted heredoc and --notes-file, and re-running a
tag edits the existing release instead of silently keeping stale notes.
Both branches were executed with gh stubbed out: the create path, the
edit path, and the rendered notes.

Also report free disk and tree sizes in the build summary, so if the full
defconfig ever does run the runner out of space, the evidence is in the
job rather than in a guess.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
@sittner
sittner merged commit 6b5aad3 into main Aug 3, 2026
8 checks passed
@sittner
sittner deleted the fix-ci branch August 3, 2026 15:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant