Skip to content

feat(ci): gate the size-diff job on UKI .efi sizes - #5111

Merged
Itxaka merged 5 commits into
kairos-io:masterfrom
itxaka-agent:triage/2347-uki-size-check
Oct 7, 2026
Merged

Itxaka merged 5 commits into
kairos-io:masterfrom
itxaka-agent:triage/2347-uki-size-check

Conversation

@itxaka-agent

@itxaka-agent itxaka-agent commented Oct 1, 2026 •

Copy link
Copy Markdown
Collaborator

Automated triage agent (kairos-triage-agent) running as @itxaka-agent.
This comment was generated by software. A human maintainer can override any
action taken here.

Adds a UKI size gate to the existing size-diff CI job.

Today scripts/iso-size-diff.sh only measures the generic (non-UKI) ISO set, and only reports — it never fails the PR. This closes both gaps for UKI artifacts specifically:

  • Extracts efiboot.img from every *-uki.iso with xorriso, pulls EFI/kairos/*.efi out with mtools, and measures each .efi.
  • Fails the job when a .efi exceeds --max-efi-mib (default 1024 MiB) or grows more than --max-efi-growth-pct (default 10%) against the same file in the last green master build. Both defaults are documented at the top of the script.
  • --require-uki fails the job if no UKI ISO is found at all, so a renamed or missing artifact can't pass silently.
  • The generic ISO table stays informational, unchanged.

.github/workflows/pr-full.yaml: widened the artifact download pattern (PR and master baseline) to pick up -uki.iso.zip, added xorriso/mtools install steps, and switched the compare step to shell: bash with --require-uki so a failing UKI check isn't swallowed by tee. The gate lives there because after #5269 the default pr.yaml smoke run builds no UKI ISO. pr.yaml only runs the new test script, so that still happens on every PR.

scripts/iso-size-diff_test.sh is new: 14 cases covering pass, ceiling, growth (with and without baseline), --require-uki, mixed generic+UKI sets, and two distinct broken-ISO shapes (missing efiboot.img, and an efiboot.img present but missing EFI/kairos).

Needs a maintainer call: the 1024 MiB / 10% thresholds are my best guess, not a measured number — I had no way to see real UKI sizes from this environment. Check them against the sizes this PR's own CI run reports, and tune DEFAULT_MAX_EFI_MIB / DEFAULT_MAX_EFI_GROWTH_PCT at the top of scripts/iso-size-diff.sh if they're off.

Fixes: #2347

Test run and lint evidence posted in a separate comment below.

build-uki puts the UKIs in a FAT efiboot.img at the root of the ISO, so
for every *-uki.iso the script now pulls that image out with xorriso,
copies EFI/kairos out with mtools and reports each .efi on its own.

Unlike the ISO table, this one gates. The script exits 1 after printing
the report when a .efi is over 1024 MiB, or grew more than 10% against
the same file in the baseline. Both limits are flags with documented
defaults. --require-uki makes a run with no UKI ISO fail instead of
passing quietly.

iso-size-diff_test.sh builds small ISOs with the same layout and checks
the pass, ceiling, growth, no-baseline and broken-ISO cases.

Part of kairos-io#2347

Signed-off-by: itxaka-agent <itxaka-agent@users.noreply.github.com>
The size-diff job only downloaded the generic non-UKI ISOs, so a UKI
growing out of bounds never showed up anywhere. Widen the artifact
pattern on both the PR and the master side to pick up the -uki.iso.zip
artifacts, install xorriso and mtools to read them, run the script's
tests first, and pass --require-uki.

The compare step now runs with an explicit bash shell, which turns on
pipefail, so a failed UKI check is not swallowed by tee.

Fixes kairos-io#2347

Signed-off-by: itxaka-agent <itxaka-agent@users.noreply.github.com>
The existing broken-ISO case only exercised a missing efiboot.img. A
valid FAT image that lacks EFI/kairos (a different UKI layout, or a
partial build) fails through the mcopy step instead, which was
untested.

Part of kairos-io#2347

Signed-off-by: itxaka-agent <itxaka-agent@users.noreply.github.com>
@itxaka-agent

Copy link
Copy Markdown
Collaborator Author

Automated triage agent (kairos-triage-agent) running as @itxaka-agent.
This comment was generated by software. A human maintainer can override any
action taken here.

test run

Ran scripts/iso-size-diff_test.sh locally at commit 1b81b1c7, 2026-10-01T15:40:57+02:00: 14/14 passed.

test run

blob sha: 00605a4c9f1af86041859fd0b7062f265948f896

Also ran, all clean: shellcheck on both scripts, yamllint --strict on .github/workflows/pr.yaml (default rules and the repo's own .yamllint config), actionlint on the same file.

No QEMU verification needed — this change is CI tooling only (bash script + GitHub Actions YAML), no boot/install/upgrade/reset path touched.

@ci-robbot

Copy link
Copy Markdown
Collaborator

Picking this up for QA.

@ci-robbot

Copy link
Copy Markdown
Collaborator

QA Result: PASS

Check Result
Environment PR head 1b81b1c7. Real UKI ISOs from this PR's run 36871582383 (kairos-hadron-trusted-v0.5.1-{core,standard}-amd64-generic-uki) and the same two from master run 36722603287, the baseline the PR's own job picked. x86_64 devbox, xorriso and mtools from Ubuntu.
Reproduction Ran the new "Compare ISO sizes and check UKI sizes" step body under bash --noprofile --norc -eo pipefail, which is what shell: bash runs, piping into tee the same way. Four inputs: A) real PR ISOs vs real master ISOs. B) the real standard UKI ISO repacked with EFI/kairos/norole.efi padded by 13%. C) real ISOs with --max-efi-mib 200. D) input B under the old default shell (bash -e, no pipefail). Also ran scripts/iso-size-diff_test.sh, checked the new artifact glob against all 104 artifact names in the PR run, and read the ESP of the PR standard ISO with mdir on its own.
Expected Real sizes are measured per .efi and pass. Growth over 10% and a breached ceiling fail the step. BOOTX64.EFI is not gated. The glob picks up the two UKI ISOs and nothing extra.
Actual A: exit 0. core norole.efi/testentry.efi 150.19 to 150.32 MiB (+0.08%), standard 252.23 to 252.36 MiB (+0.05%), all ok. B: exit 1, norole.efi grew +32.93 MiB (+13.06%), over the 10% limit. C: exit 1, both standard .efi over 200 MiB, core ones ok. D: exit 0, so the shell: bash change is what makes the failure stop the job. mdir shows norole.efi at 264615312 bytes, which is the 252.36 MiB the script reports. The glob matches the 3 generic ISOs plus the 2 -uki ones. The unit test script passes 14/14, and it only needs xorriso and mtools, which the job installs first.
Proofs Full reports for A, B, C and the ESP listing: https://gist.github.com/ci-robbot/c690327198120f628ef8cf806b1f92f4

Summary: The UKI gate measures the real .efi files in the CI-built UKI ISOs, matches them to the master baseline, and fails the step on both a ceiling breach and growth over 10%. It does this under the same shell and tee pipe the workflow uses.

Notes, not blockers:

  • This PR's own iso-size-diff job ran master's copy of the job, because the trigger is pull_request_target. Its log shows the old glob and command and no UKI table. So the gate has not run in CI yet. The first PR after merge is the first real CI run.
  • The 1024 MiB default ceiling is about 4x the largest UKI today (252 MiB). The PR asks a maintainer to choose the number. With that default, in practice only the 10% growth check can fail.
  • Each .efi read extracts the whole ISO to the runner's disk (up to 538 MiB per ISO, baseline included). That works, but extracting only /efiboot.img would be cheaper.

Itxaka
Itxaka previously approved these changes Oct 6, 2026
@Itxaka
Itxaka enabled auto-merge (squash) October 6, 2026 10:53
@Itxaka
Itxaka temporarily deployed to fork-pr-builds October 6, 2026 10:53 — with GitHub Actions Inactive
@Itxaka

Itxaka commented Oct 6, 2026

Copy link
Copy Markdown
Member

@copilot resolve the merge conflicts in this pull request

master split the PR pipeline (kairos-io#5269): pr.yaml is now a smoke run that
builds only the amd64 core ISO, and the full matrix with the UKI ISOs
moved to pr-full.yaml. The UKI size gate goes with them into
pr-full.yaml's size-diff job. pr.yaml keeps the script's own test so it
still runs on every PR.

Also picks up 70e24cf, which fixes the edgevpn bundle failure in the
install test.

Co-authored-by: Itxaka <itxakaserrano@gmail.com>
Signed-off-by: itxaka-agent <itxaka-agent@users.noreply.github.com>
@Itxaka
Itxaka merged commit 55164dc into kairos-io:master Oct 7, 2026
25 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add a check for UKI image sizes [retro action item]

3 participants