FOS Release Workflows

FOGProject/fos — the Buildroot/kernel build repo covered in Fog Release — publishes its kernels and inits through three GitHub Actions workflows rather than the dev-branchstable PR pipeline described in Stable Release Workflow. FOS has no dev-branch; every workflow here builds directly from whatever ref is checked out (normally master) and publishes straight to a tagged GitHub release.

  • create_experimental_release.yml — on-demand, partial-build, prerelease. This is the workflow that actually gets used, including as the basis for the “official” release (see below).
  • create_release.yml — named “Create Latest/Official Release”, designed as the full-build/official path, but it has never once been run (verified via the Actions API).
  • make_usb.yml — intended to react to any published release and attach a bootable USB image, but has fired exactly once in the repo’s history, and that run failed.

Experimental Release

Triggered by hand (workflow_dispatch) with six boolean inputs — init and kernel, each for arm64/x64/x86 — so a maintainer can build just the piece under test (e.g. only the arm64 kernel after a driver change) instead of everything. input_checks fails the run if every input is left unchecked.

Only the selected build_kernel_*/build_initrd_* jobs run; the init jobs additionally restore a Buildroot download cache and an arch-specific ccache (keyed on build.sh’s hash and the run ID) to keep iteration fast. The final release job runs once every requested build job has finished, gated on !contains(needs.*.result, 'failure') && !contains(needs.*.result, 'cancelled') — a job that was never requested is neither failed nor cancelled, so skipping components doesn’t block the release.

The release it publishes is deliberately marked as not the “real” one:

  • Tag: EXP_<UTC timestamp> (e.g. EXP_20260730-141502).
  • Name: Experimental release from <UTC date/time>.
  • prerelease: true, and the body is prefixed with an explicit backup warning.

This is the mechanism for getting a build in front of the community — testers install it manually — without it ever being mistaken for, or picked up by, tooling that looks for the latest non-prerelease/official release.

Create Latest/Official Release

The workflow actually named “Create Latest/Official Release” (create_release.yml) is built to always build all six kernel/init combinations — there is no per-component selection here — and only proceed to release if every one of those six jobs succeeds (plain needs:, no always() override, unlike the experimental workflow).

Two workflow_dispatch inputs are designed to decide what kind of release comes out:

is_official_releaseofficial_fog_versionResult
unchecked(must be blank)Rolling release, tag <YYYYMMDD>, name Latest from <date>
checked(required)Official release, tag and name both the given version, name FOG {version} kernels and inits

input_checks enforces that pairing (version filled in iff the checkbox is set) before anything builds.

In practice, this workflow has never been run. Checking its GitHub Actions history directly (gh api repos/FOGProject/fos/actions/workflows/49199525/runs) shows "total_count": 0 — zero runs, ever, since it was added in February 2023. Every “Latest from …”/official-looking release actually published (see below) was produced a different way. Treat this workflow as designed-but-unused rather than as the real release path, and see the runner-image note at the end of this page before ever dispatching it for real.

How a release actually gets made official

The rolling “Latest from …” release name is called out in create_release.yml’s own comments as load-bearing — FOG’s Kernel Update page parses that exact release-name format — but the release that actually carries that meaning (the repo’s newest non-prerelease release) is produced by hand, by editing an Experimental Release’s output in place rather than by dispatching the dedicated workflow:

  1. Dispatch Experimental Release as usual (all six components, or just the ones under test). It builds and auto-publishes its normal EXP_<UTC timestamp> prerelease, with all six kernel/init assets and their .sha256 files attached.
  2. Once that build is confirmed good, edit that same release in place: change its tag to the plain rolling-release form (e.g. EXP_20260726-20391220260730), rename the title (e.g. Release 20260730), and clear the “Set as a pre-release” checkbox. No files are re-uploaded — the six assets that experimental run already built and attached become the official release’s assets untouched.

This was confirmed directly from a real example: the 20260730 release (published 2026-07-26) has author: github-actions[bot] and a created_at that matches — to the second — the commit date of the master HEAD that an Experimental Release run (dispatched by a maintainer, run:30216684381) built from that same day; the release object is the bot-created prerelease from that run, edited afterward. GitHub’s release created_at reflects the tagged commit’s date rather than the API-call time, which is what makes this identifiable after the fact.

Editing the release like this only works cleanly the same day (or soon after) the experimental build finished: buildFilesystem() in build.sh stamps initversion into funcs.sh with the build’s own date (export initversion=$(date +%Y%m%d)), so retagging a much older experimental release as today’s “Latest” would ship an init whose embedded version string no longer matches the release date.

There is nothing to separately clean up — the experimental prerelease doesn’t keep existing under its old EXP_* tag once retagged; it becomes the official release object.

USB image attachment (currently not working)

make_usb.yml is written to listen for release: published, intending to build a bootable USB image from the release’s own assets (create-usb-image.sh against https://github.com/<repo>/releases/download/<tag>) and attach fos-usb.img back onto that same release. In practice this does not happen:

  • It has fired exactly once in the repo’s entire history (2026-07-05), and that run failed.
  • It does not fire for a release that’s promoted by editing an existing prerelease (the method above) — GitHub only sends the published action when a release is first published, not when a prerelease is later flipped to a full release, so the retag-in-place method described above never triggers it.
  • Confirmed on the live 20260730 release: its only assets are the six kernel/init files and their checksums — no fos-usb.img.

So no FOS release currently ships an automatically-attached USB image; a USB image today would have to be built and attached by hand with create-usb-image.sh if one is needed.

If you do want to dispatch Create Latest/Official Release for real

Since it’s never run, nothing here is proven — this is a static read of the YAML, not a live result:

  • No structural blockers found: repo-level default_workflow_permissions is write, so the implicit GITHUB_TOKEN can create a release with no explicit permissions: block, same as the (working) Experimental Release workflow. The kernel/Buildroot-version extraction and input-pairing validation are byte-identical to logic Experimental Release already runs successfully.
  • It runs on ubuntu-22.04, which GitHub began deprecating on 2026-09-17 (full removal 2027-04-17) — jobs will start being intermittently failed during that window. Experimental Release was already moved to ubuntu-24.04 in the same commit that added it; this workflow was not.
  • Its pinned action versions are two majors behind Experimental Release’s (actions/checkout@v4 vs @v6, upload/download-artifact@v4 vs @v7/@v8, softprops/action-gh-release@v2 vs @v3) — nothing currently broken, just a sign it hasn’t been touched since 2024-04-03.
  • Unlike Experimental Release, its filesystem-build jobs have no Buildroot download/ccache caching, so a real run does a fully cold build for all three architectures — expect it to run considerably longer and be more exposed to network flakiness than the experimental builds you’ve actually been running.
  • Fog Release — the manual kernel/Buildroot/iPXE version-bump process that normally precedes a FOS release; that page’s “FOS kernel” and “FOS init” sections describe updating configs/kernel*.config/ configs/fs*.config, which is what these workflows then build and publish.
  • Stable Release Workflow — the analogous promotion pipeline for fogproject itself. Unlike FOS, that repo promotes through a dev-branch → stable PR gated on install-validation tests; FOS has no equivalent branch model or automated test gate — promotion here is the manual dispatch described above, with community testing of the experimental prerelease standing in for automated validation.