feat(#126b): CI builds evsieve and uploads it as a release asset - #194
Merged
Conversation
New build-evsieve job in release.yml, runs on every v* tag push (#126a's decision: CI cross-build, not a manual build-on-Deck-and-upload — see the issue comment and docs/PLAN.md for the full reasoning). runs-on ubuntu-22.04 deliberately, not -latest: SteamOS currently ships glibc 2.41, newer than even ubuntu-24.04's 2.39; glibc's ABI is backward- compatible, so building on the OLDER 22.04 (2.35) buys the widest margin for Decks that haven't updated recently, at zero cost. The source is fetched, pin/archive-verified, and patched by SOURCING evsieve_management.sh and calling its own _evsieve_acquire_source/ _evsieve_resolve_patch/_evsieve_apply_patch directly — the exact same logic the build-at-install path uses, not a second copy re-typed into YAML (PRINCIPLES #9). Only the distrobox/debian:12 container is skipped (a GH runner already has apt directly; the container exists solely because SteamOS's host does not). Packages the binary + a matching .sha256 + a .stamp (commit=/patch_sha256=, the exact format _evsieve_write_stamp already writes) under the asset names _evsieve_try_prebuilt() (#126c) fetches — EVSIEVE_PREBUILT_BIN_NAME etc., read from the SAME sourced module, so the names can never drift between producer and consumer. Fail-open at the workflow level, matching the module's own contract: if the build fails (upstream unreachable, a future Ubuntu image drops libevdev-dev, whatever), `if: always()` lets the release job continue and ship the installer script alone — a partial release is a supported degrade, not a broken run, since the installer's own _evsieve_try_prebuilt already falls back to build-at-install when no prebuilt asset exists. Split into two separate upload steps rather than one `files:` glob covering both assets: a glob matching zero files (build failed, no evsieve-assets/) risks erroring the whole step, which would take the installer-script upload down with it — exactly the coupling the fail-open design exists to avoid. Added workflow_dispatch as a second trigger, permanently: release.yml only ever ran on an actual v* tag push, so there was no way to test new logic in it without cutting a real release. Both upload-to-GitHub-Releases steps are now guarded to `github.event_name == 'push'`, so a manual dispatch run exercises the build-evsieve job for real (cargo build, patch application, checksum, stamp) without ever touching the Releases page — validated by hand-triggering it before this PR merges. Not yet consumed by anything until #126c (installer fetch, same PR series) also merges. #126d is Deck validation of the fetch + forced-fallback paths once a real tag carries the assets. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01Dru6wVc2ZcjiTpa6p7yJDh
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Part of #126, depends on #193 (merged — this branch is rebased on top of it).
What
New `build-evsieve` job in `release.yml`, runs on every `v*` tag push
(#126a's decision: CI cross-build, not a manual build-on-Deck-and-upload —
full reasoning on the issue and in `docs/PLAN.md`).
`runs-on: ubuntu-22.04` deliberately, not `-latest`: SteamOS currently ships
glibc 2.41, newer than even `ubuntu-24.04`'s 2.39; glibc's ABI is
backward-compatible, so building on the older 22.04 (2.35) buys the widest
margin for Decks that haven't updated recently, at zero cost.
The source is fetched, pin/archive-verified, and patched by sourcing
`evsieve_management.sh` and calling its own `_evsieve_acquire_source`/
`_evsieve_resolve_patch`/`_evsieve_apply_patch` directly — the exact same
logic the build-at-install path uses, not a second copy re-typed into YAML
(PRINCIPLES #9). Only the distrobox/debian:12 container is skipped (a GH
runner already has apt directly; the container exists solely because
SteamOS's host does not).
Packages the binary + a matching `.sha256` + a `.stamp` (the exact
`commit=`/`patch_sha256=` format `_evsieve_write_stamp` already writes)
under the asset names `_evsieve_try_prebuilt()` (#193) fetches — read from
the same sourced module, so producer and consumer can never drift on names.
Fail-open, matching the module's own contract
If the build fails (upstream unreachable, a future Ubuntu image drops
`libevdev-dev`, etc.), `if: always()` lets the release job continue and ship
the installer script alone — a partial release is a supported degrade, not a
broken run, since the installer's own `_evsieve_try_prebuilt` already falls
back to build-at-install when no prebuilt asset exists.
Two separate upload steps, not one `files:` glob covering both assets: a
glob matching zero files (build failed, no `evsieve-assets/`) risks
erroring the whole step, which would take the installer-script upload down
with it too.
Validated for real, not just reviewed
`release.yml` only ever ran on an actual `v*` tag push, so there was no way
to test new logic in it without cutting a real release. Added
`workflow_dispatch` as a permanent second trigger, with both
upload-to-Releases steps guarded to `github.event_name == 'push'` — a manual
dispatch run exercises the build job for real without ever touching the
Releases page.
Ran it twice by hand on this branch:
mainbefore feat(#126c): installer fetches a prebuilt evsieve before ever building #193 merged, so theEVSIEVE_PREBUILT_*constants didn't exist yet. Real bug, real catch.actual artifact and verified: SHA-256 matches the published
.sha256exactly, the
.stampmatches this module's ownEVSIEVE_PINNED_COMMIT/EVSIEVE_PATCH_SHA256exactly, and the binary is avalid dynamically-linked x86_64 ELF that the CI runner itself ran
successfully (
--version→1.4.0) during the build.Not done
Not yet consumed for real — the assets only ship on an actual
v*tag push,and #126d (Deck validation of the fetch + forced-fallback paths) needs a
real published release to fetch from, which happens at the next tagged
release.
🤖 Generated with Claude Code
https://claude.ai/code/session_01Dru6wVc2ZcjiTpa6p7yJDh