Skip to main content

Checks and what a red run means

Required status checks are a GitHub setting outside the repository.

What runs​

WorkflowTriggerProvesKeeps
checks.ymlpull request, main, called by releaseresources validate and render deterministicallyjob log
artifacts.ymlpull request, main, dispatchdeclared URLs resolve and bytes match their checksums; repositories look like repositoriesjob log and summary
image-bootcheck.ymlpull request/main when resources, examples, code, schemas or the harness change; dispatchthe CentOS workstations build into QCOW2 and pass boot, session and first-boot checksbootcheck, session, firstboot, failed-boot journal, frames, serial
image-publish.ymlMondays 06:17 UTC; dispatcha platform builds, scans, compares declared and installed SBOMs, boots, and on the schedule (or a publish=true dispatch from main) pushes, signs and attests one digestSBOMs, Grype report, digest, cosign verification, provenance, Plan, records directory
installer-build.ymlcalled by the weekly build; dispatchthe installer for a published digest is built, signed and tagged sha256-<image digest>; nothing is built from mainartifact digest, iso.sha256, cosign verification
promotion.ymlthe weekly build's success (workflow_run); dispatch:stable moves only to a digest whose signature and every stored record verify, with an approval recordapproval record, job log
release-watchdog.ymldaily 09:17 UTC; dispatch:stable is not older than eight days, and the weekly build is dispatched when it isjob log
lifecycle-test.ymlMondays 04:17 UTC; dispatchinstall, stage B, boot B, roll back to A, interrupt a download and retry, fail a candidate and recover the previous entrylifecycle.json, summary, serial logs, one journal per boot
installer-test.ymldispatchthe test-only ISO installs unattended and writes its completion markerserial log, frames, summary
examples-weekly.ymlWednesdays 06:00 UTC; dispatchAlmaLinux and Fedora examples build and boot; not publishedboot, session and first-boot records
release.ymltag v*CI, release binaries, checksums and the deskosctl tool imageGitHub Release, signatures
tool-image.ymlContainerfile or compiler paths; dispatchthe deskosctl container builds and runsjob log
mirror-fedora.ymldispatcha Fedora base is mirrored to DeskOS Quayjob log
renovate.ymldaily; dispatchopens pin-update pull requests; it never mergespull requests
identity-freeipa.ymldaily 04:23 UTC; dispatch; pull request when the identity fixture or the session harness changesa client image joins a disposable FreeIPA realm and the session proves the loginsummary, frames
identity-ad.ymldaily 04:47 UTC; dispatch; pull request when the identity fixture or the session harness changesthe same, against a disposable Samba AD domain controllersummary, frames
track.ymlMondays 05:17 UTC; dispatchevery checksum-pinned resource still resolves, and moves the ones the curated list covers, as a pull requestpull request
evidence-maintenance.ymldispatchrepairs or prunes the digest-keyed record store; a prefix with an index is refused without forcejob log

A scheduled run has no dispatch inputs. image-publish.yml falls back to fail-on: critical, so the weekly run has a severity threshold, and since 2026-10-28 it publishes: signature, records, promotion. A dispatch with publish=false is the dry run.

Reading a failure​

  • Infrastructure or harness. The job log shows a registry 503/EOF, a full runner disk, a missing firmware path, a permission error or no runner; the image may be untouched. Fix the runner or retry, name the attempt, do not "fix" the image.
  • Image defect. The build finished, then a boot, session or first-boot check failed. Read the serial log, the failed-boot journal, the frames and the summary before rerunning; a retry does not make an image boot.
  • Installer defect. installer-test builds but never finds Install finished, or never reaches GNOME Initial Setup: the ISO, not the image build.
  • Unverified probe. A size above the resolver's bound is not verified, a repository body may be inconclusive, and deskos check reports items as not measurable here. None is a pass; an unobserved target stays red.

The VM harness keeps bootcheck-attempt1 beside the retried bootcheck when the splash retry runs, and artifacts carry the run attempt in their name (…-attempt-2), so a re-run keeps the first attempt's records.

Tested and published identity​

The publish path builds one image, boots it, and pushes it by digest. image.txt holds the local image ID, digest.txt the pushed digest, cosign-verify.txt the verification, identity.json the base and image digests with the Plan and context. A machine reports its boot with bootc status and deskos report. :latest moves after the checks; :<commit> is a naming convention, not registry-enforced immutability.

Workstation behavior matrix​

Ties a promoted image's claims to its probe. Instrumented adds a test user, autologin or a session script; unmodified boots the disk as shipped.

ClaimProbePositiveNegativeKind
Quiet graphical boot and splashbootcheck.py --expect-splashstable graphical frames and splash detectedtext-only, blank or no stable frameunmodified
GNOME Initial Setup on first bootfirstbootcheck.pythe wizard and its session are presentno wizard, or a different sessionunmodified
Declared dconf defaults and vendor overridessessioncheck.pyeach plan key reads back as declared; login-screen keys are read through the greeter's own profilea value differs or cannot be readinstrumented
Declared extensions loadsessioncheck.py, gnome-extensions infostate ACTIVE/ENABLEDmissing or ERRORinstrumented
Tray extension serves the session bussessioncheck.pyStatusNotifierWatcher present and accepts a registrationservice absent or registration rejectedinstrumented
Favorites list matches the plansessioncheck.pyfavorite-apps equals the declared list, in orderdiffersinstrumented
Each favorite resolves to a desktop entrysessioncheck.pyevery id exists in a system or Flatpak application directoryan id has no .desktop entryinstrumented
Each favorite resolves to a commandsessioncheck.pythe entry's Exec names a binary the image shipsthe command is missing, or a Flatpak app, which the Flatpak check ownsinstrumented
Session exposes its applications through AT-SPIsessioncheck.py, e2e-apps.pythe accessibility registry lists at least one application, and the report names themthe binding or the registry is missing, or no application is listedinstrumented
An application opens from its desktop entrysessioncheck.py, e2e-apps.pya new application with at least one toplevel appears in the accessibility tree after its entry is launchedthe entry is missing, nothing new appears, or the new application has no windowinstrumented
Browser fetches harness contentsessioncheck.pythe guest fetches the harness page, the marker is in it, the fixture saw a Firefox request and a screenshot existsfetch fails, marker missing, no browser request or no screenshotinstrumented
Login logo file existssessioncheck.pythe dconf logo names a file the image carriesthe key is set and the file is missinginstrumented
Offline loginsessioncheck.py --offline (Core)autologin reaches a session with no NIC and no default routeno session, or the boot kept a routeinstrumented
Runtime tool reads the plansessioncheck.pydeskos report names the tested workstationno report, or another workstationinstrumented
Runtime checker runssessioncheck.pydeskos check exits 0 (clean) or 1 (it found a difference)it exits 2 or cannot runinstrumented
Screen locks on requestsessioncheck.pyorg.gnome.ScreenSaver.GetActive is true after Lockfalse or no answerinstrumented
Firefox runssessioncheck.py headless probethe guest reports Firefox installed, headless exit 0 and a non-empty screenshotnon-zero or no screenshot; an image without Firefox says soinstrumented
System Flatpaks materializesessioncheck.py and flatpak list --system --appevery declared application id is installeda declared id is missinginstrumented
Lifecycle A → B → Alifecycle-test.ymlstage, boot B, roll back, local state, failed candidate and host-side recoverywrong deployment, lost /var, failed retry, recovered wrong digestunmodified, weekly
Test ISO installs unattendedinstaller-test.ymlserial marker and GNOME Initial Setuptimeout or marker missingunmodified, dispatch
Published ISO carries the signed digestinstaller-build.yml (called by the weekly build, dispatchable)the digest's keyless signature verifies, the ISO is built from it, pushed signed, and tagged sha256-<image digest>signature does not verify, build fails, or the annotation does not name the digestfrom the published digest, not main

A missing result, an unreadable value or a not measurable count is a failure or an unverified item, not a pass. The session row is an instrumented autologin session, not proof of an interactive GDM login, so the Wayland session type through GDM is unproved too, as are launching every declared favorite, Flatpak install after reconnection, and suspend, battery, display and other hardware behavior (P1-07).

What is not covered​

  • Shutdown splash: captured, not asserted, since the guest powers off in 0.4 s with one frame. A reboot splash needs a boot that reboots.
  • Bare metal, BIOS boot, Secure Boot and non-x86_64 are untested, and the image build is not yet bit-for-bit reproducible.
  • No check installs the published ISO; its storage is interactive, so only a person completes it. The test-only ISO has the installer-test job.
  • The lifecycle check recovers a failed candidate through the previous GRUB entry from the host, not by a person; rollback after userspace is still manual.
  • RHEL composition and rendering are tested here; the entitled build and boot happen in the downstream organization.