mirror of
https://github.com/Klipper4FlashForge/firmware.git
synced 2026-10-21 21:02:16 -05:00
PR #10 was green on this machine and red on both CI jobs. Three separate faults, none of which a local signed build could show. apk-tools is cloned from gitlab.alpinelinux.org, which answers a GitHub runner with HTTP 418 or with nothing until the connection times out. It clones from the GitHub mirror now. Which host serves it cannot change what is fetched: the pin is a commit sha, and git names a commit by the hash of its content, so a mirror answering with this sha is serving this tree or is not answering. get_git also sets the remote url on every run, so a checkout made before this commit does not keep fetching from the host that refuses. anvil-core's cache key hashed the feed's public key as sha256sum "${APK_SIGN_KEY:-/dev/null}.pub" 2>/dev/null | cut ... With no key that file is absent, sha256sum is non-zero, pipefail makes the pipeline non-zero, and build-packages.sh -- which sources every pkg.conf under `set -euo pipefail` -- died before emitting a single package. The 2>/dev/null ate the reason, so `make packages` exited 1 having said only that it had sealed a cache entry. Every signed build passed. Every CI build is unsigned. It is now pkg_signkey_hash, which answers `unsigned` and succeeds. The build container mounts the checkout and nothing else, so a key at the documented ~/.anvil/anvil.rsa was visible in the developer's shell and invisible to apk. The Makefile reads APK_SIGN_KEY out of $(CONFIG_ENV) and bind-mounts its directory read-only. This survived review because the key used while writing the migration sat under work/, inside the one directory already mounted. Gates for all three, each verified against its own bug by reverting the fix under it. The recipe-reads-unsigned test runs pkg_conf under the same flags build-packages.sh uses -- the existing _conf helper does not, and would have stayed green throughout. Its companion asserts the recipe SET does not change with the key, because pkg_recipes evaluates PKG_WHEN in a subshell and a recipe that fails to source is dropped rather than reported: broken only when unsigned, a package would leave the feed with nothing turning red. Both are scoped to what pkg_recipes lists, so busybox -- gated off whenever there is no stock firmware to take one from -- is not asked a question it cannot answer. release.yml takes the private key PEM from secrets.APK_SIGN_KEY, writes it to $RUNNER_TEMP outside the checkout where no later step can archive it into a release, and derives the public half rather than storing a second secret that could drift out of step with the first. Unset, the release builds unsigned with a warning: a fork has no such secret, and firmware nobody else can build is worse than a feed untrusted on a stick the printer was handed by hand. Verified from a cold work/host and work/packages, three ways: no key (the CI case), a key inside the tree, and a key outside it at the documented location. Each gives 47 packages plus the index, a payload, 286 static and 135 replica tests. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_013rbKEyLXrzSE6wm3iNApVp