PRD: CI artifact-based coverage and local Firecracker candidate flow #447

Merged
didericis merged 5 commits from ci-artifact-coverage into main 2026-07-21 12:59:33 -04:00
Collaborator

Closes #446.

PRD

Summary

  • Each test job (unit, integration-docker, integration-firecracker) runs once under coverage and uploads a small .coverage.* artifact.
  • The coverage job combines them on ubuntu-latest — no test reruns, no KVM dependency on that job.
  • The infra candidate is built directly on the KVM runner in integration-firecracker, eliminating the stage-firecracker-inputs and build-infra jobs and their ~70 s upload + ~83 s combined download overhead.
  • PRs incur no rootfs artifact transfer (~194 MB saved per PR run).
  • Main-branch pushes upload the tested rootfs and matching dropbear so publish-infra publishes the byte-identical artifact that passed integration tests.
  • relative_files = True added to .coveragerc so .coverage.* files from different runners combine without a [paths] remapping section.
  • scripts/coverage.sh aggregate [critical] mode added; existing run mode preserved for local dev.
Closes #446. [PRD](https://gitea.dideric.is/didericis/bot-bottle/src/commit/5940b75bb72d2de30e7bb55775957fa18453454a/docs/prds/prd-new-ci-artifact-coverage.md) ## Summary - Each test job (`unit`, `integration-docker`, `integration-firecracker`) runs once under coverage and uploads a small `.coverage.*` artifact. - The `coverage` job combines them on `ubuntu-latest` — no test reruns, no KVM dependency on that job. - The infra candidate is built directly on the KVM runner in `integration-firecracker`, eliminating the `stage-firecracker-inputs` and `build-infra` jobs and their ~70 s upload + ~83 s combined download overhead. - PRs incur no rootfs artifact transfer (~194 MB saved per PR run). - Main-branch pushes upload the tested rootfs and matching dropbear so `publish-infra` publishes the byte-identical artifact that passed integration tests. - `relative_files = True` added to `.coveragerc` so `.coverage.*` files from different runners combine without a `[paths]` remapping section. - `scripts/coverage.sh aggregate [critical]` mode added; existing run mode preserved for local dev.
didericis added 4 commits 2026-07-21 12:43:34 -04:00
Each test job now runs once under coverage and uploads a small .coverage.*
artifact. The coverage job combines them on ubuntu-latest — no test reruns,
no KVM dependency. The infra candidate is built directly on the KVM runner,
eliminating the build-infra job and the ~70 s upload + ~83 s combined
download. For PRs, no rootfs artifact is transferred at all. Main-branch
pushes upload the tested rootfs and matching dropbear so publish-infra
publishes the byte-identical artifact. relative_files = True in .coveragerc
lets coverage files from different runners combine without path remapping.

Closes #446
The delphi-ci runner resolves relative paths in upload-artifact and
download-artifact from a different CWD than run: shell steps, so
'.coverage.unit' etc. were never found. Using ${{ github.workspace }}
gives an absolute path that does not depend on the JS action's CWD.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
coverage run's --data-file flag can be overridden or ignored in some
runner environments (Nix Python, older act-based runners). Switching to
the COVERAGE_FILE env var with an absolute ${{ github.workspace }} path
ensures coverage.py writes to a known location in every runner context,
so upload-artifact can find the file.

Also adds --reuse-published to the infra build step: if the artifact for
this content hash already exists in the registry, download it instead of
running the full docker build → mke2fs → gzip pipeline.
fix(ci): stage coverage data under non-dot names so upload-artifact uploads them
tracker-policy-pr / check-pr (pull_request) Successful in 12s
test / integration-docker (pull_request) Successful in 18s
lint / lint (push) Successful in 52s
test / unit (pull_request) Successful in 1m59s
test / integration-firecracker (pull_request) Successful in 3m23s
test / coverage (pull_request) Failing after 40s
test / publish-infra (pull_request) Has been skipped
26002b75ca
upload-artifact@v3's glob silently skips hidden files, so uploading a
bare `.coverage.unit` logged "No files were found. No artifacts will be
uploaded" and registered nothing — the coverage job's download then 404'd
("List Artifacts failed: 404"). The coverage report step read the same
file fine, confirming it existed; only the leading dot broke the upload.
The old pipeline's cross-job artifacts (infra-candidate/, firecracker-
inputs) worked precisely because they were non-dotfiles.

Each test job now copies its .coverage.<suffix> to a non-dot
coverage-<suffix>.dat before upload (the cp also fails loudly if coverage
never wrote the file), and the coverage job renames them back to
.coverage.* before `coverage combine`.
didericis force-pushed ci-artifact-coverage from 41e01d745a to 26002b75ca 2026-07-21 12:43:34 -04:00 Compare
didericis added 1 commit 2026-07-21 12:55:14 -04:00
test(firecracker): cover published artifact reuse
tracker-policy-pr / check-pr (pull_request) Successful in 9s
test / integration-docker (pull_request) Successful in 16s
test / unit (pull_request) Successful in 1m37s
test / integration-firecracker (pull_request) Successful in 3m30s
test / coverage (pull_request) Successful in 15s
test / publish-infra (pull_request) Has been skipped
prd-number / assign-numbers (push) Failing after 23s
test / integration-docker (push) Successful in 15s
lint / lint (push) Successful in 58s
test / unit (push) Successful in 38s
Update Quality Badges / update-badges (push) Failing after 1m40s
test / integration-firecracker (push) Successful in 5m9s
test / coverage (push) Successful in 44s
test / publish-infra (push) Successful in 2m7s
8348714e3e
didericis merged commit 8348714e3e into main 2026-07-21 12:59:33 -04:00
didericis deleted branch ci-artifact-coverage 2026-07-21 12:59:38 -04:00
Sign in to join this conversation.