Skip to content
Austin Shirley edited this page Jul 14, 2026 · 2 revisions

GitHub Actions workflows

Pre-commit checks

The pre-commit.yml workflow runs on push and pull requests to main, release/*, and dev/*.

This workflow contains two jobs:

  • nix-env: Instantiates the ci development shell, applies the Buildroot defconfig, and downloads the Linux kernel source tarball into dl/. The job fails if the Nix environment is broken. Kernel sources provide pre-commit rules for Device Tree files.
  • pre-commit: Restores dl/ from cache, then runs all pre-commit hooks via ./support/pre-commit.sh. Results are written to the job summary.

If nix-env fails, pre-commit is blocked and the failure is clearly attributed to the environment rather than to a hook.

Release image build

The build.yml workflow runs on push and pull requests to main and release/*, plus manual dispatch.

This workflow contains four jobs. The release and debug jobs deliberately use the two different build paths, the hermetic nix build and the make shell build, so that both paths are exercised on every run and a regression in either one is caught.

  • lockfile: Verifies the state of flake.lock, buildroot.lock, and toolchain.lock. It runs nix flake lock --no-update-lock-file to confirm flake.lock is current, then regenerates both Buildroot locks with make nix-lock and fails if either committed lock differs.
  • toolchain: Builds the toolchain SDK (nix build .#toolchain) and pushes it to Cachix first, so both build paths substitute the same cached SDK. Both build jobs depend on this job.
  • image: Builds the release image and SDK through the hermetic nix build path. The image build (nix build) consumes the stage-1 toolchain SDK as an external toolchain and builds packages, images, and programmer. The emitted flashlayout.tsv references artifacts for use with STM32_Programmer_CLI. The SDK build (nix build .#sdk) produces a relocatable cross-compiler SDK as a second output of the same derivation, and uses the cache once the image is built. Uses Cachix to cache Nix store paths across runs. Uploads the images and SDK as separate artifacts.
  • debug: Builds the debug image through the make shell path, running make debug with the debug fragment. The development shell's make shim resolves the Cachix-cached toolchain SDK automatically, and ccache plus a host cache (keyed on toolchain.lock) provide incremental reuse across runs.

Template project validation

The template-test.yml workflow runs on push and pull requests to main when files under support/parent/, lib.nix, inputs.nix, nix/, or .pre-commit-hooks.yaml change. It is also available via manual dispatch.

This workflow instantiates the parent template into a scratch directory and runs the same checks that a downstream parent would run on commit. No build occurs; evaluation only.

The template-test job copies the submodule into a temp directory as regular files, runs init.sh to generate the template, then validates:

  • All expected template files are created.
  • No leftover @@PLACEHOLDER@@ tokens remain.
  • Hook IDs in .pre-commit-config.yaml match .pre-commit-hooks.yaml.
  • nix flake check --no-build succeeds (evaluates all derivations without building).

Commit message checks

Commit messages are validated against Conventional Commits at push time (via the pre-push git hook) and in CI. They are intentionally not checked on every local commit to allow rebasing and fixups without friction.

To check messages manually:

./support/pre-commit/commitizen-check-push.sh HEAD~3
./support/pre-commit/commitizen-check-push.sh main

The script re-execs inside nix develop .#pre-commit automatically if cz is not on PATH.

Caching

The dl/ directory is cached, keyed on buildroot.lock. The cache accumulates downloaded sources over time and is reused across runs as long as the lock file does not change. As more packages are added (for example for a full build job), their tarballs are included automatically.

Running locally with act

act is included in the default development shell and runs GitHub Actions workflows locally via Docker.

act
act -W .github/workflows/pre-commit.yml
act -W .github/workflows/pre-commit.yml -j pre-commit

The first command runs all workflows. The second runs a specific workflow. The third runs a specific job from a workflow.

Act defaults may not suit the build requirements. A local ~/.actrc may require:

--container-daemon-socket $XDG_RUNTIME_DIR/podman/podman.sock
-P ubuntu-latest=catthehacker/ubuntu:act-latest
--container-options --security-opt=seccomp=unconfined

The first option uses Podman instead of Docker. The second selects an ubuntu-latest image similar to the one GitHub Actions uses. The third relaxes the container seccomp profile, which allows the unprivileged user namespaces that buildFHSEnv needs because it relies on bwrap (avoiding running the container fully --privileged).

Known limitations

  • cachix/install-nix-action prints a warning about running as root inside the Act container. This is cosmetic; Nix installs and works correctly.
  • actions/cache@v5 will not use cache from GitHub. This may work differently depending on local configuration.
  • Use act -s ACTIONS_RUNTIME_TOKEN=local to skip steps that upload artifacts.

The CI Nix development shell

The ci development shell (nix develop .#ci) contains all packages needed to run Buildroot builds in CI. It is identical to the default shell minus tools that require manual setup or are local-only:

  • stm32cubeprog requires a manually downloaded ST zip and cannot be fetched automatically.
  • act and podman are local workflow tooling, not needed in CI.

Use .#ci in any CI step that invokes make. Use .#default locally for the full development environment including flashing tools.

To enter the CI shell locally (for example to reproduce a CI-specific environment failure):

nix develop .#ci

Adding a new workflow

  • Use nix develop .#ci --command <cmd> for steps that need the Buildroot environment.
  • Use nix develop .#pre-commit --command <cmd> for lint and hook steps.
  • Add dl/ to the cache if the job downloads sources; key on buildroot.lock.
  • If a job depends on the Nix environment being valid, add needs: nix-env to make the dependency explicit.

Clone this wiki locally