Skip to main content

ci cd

TunaOS uses GitHub Actions for automated building, testing, and distribution of container images and ISO artifacts.

Architecture​

The CI pipeline is driven by a central configuration file (.github/build-config.yml) which defines all variants, flavors, platforms, and build stages. A single reusable workflow (build-variant.yml) handles all image builds using matrix strategies generated from this config.

Per-variant trigger workflows (build-yellowfin.yml, etc.) are thin wrappers that call the reusable workflow with the variant name β€” they exist primarily for independent cron schedules and manual dispatch.

Workflows​

Build Images​

Workflow: reusable-build-image.yml (reusable) + build-{variant}.yml (per variant)

Triggered on:

  • Push to main (affected variants only)
  • Pull requests (affected variants only)
  • Scheduled (daily)
  • Manual dispatch (workflow_dispatch)

The reusable workflow:

  1. Builds the container image for a matrix of platforms (linux/amd64, linux/amd64/v2, linux/arm64)
  2. Applies chunkah rechunking
  3. Signs images with cosign
  4. Generates SBOM attestations
  5. Pushes to ghcr.io/tuna-os/<variant>:<flavor>

Build Live ISOs​

ISOs are built through two paths:

  1. build-variant.yml β†’ build_artifacts job β€” builds ISOs and QCOW2s as part of the main build pipeline, after all image stages complete. Uses tacklebox. Runs on weekly schedule and manual dispatch.

  2. publish-isos.yml β€” standalone ISO publishing workflow. Triggered on:

    • Schedule (weekly, Sunday 22:00 UTC)
    • Manual dispatch

Downloads the published container image from GHCR, runs tacklebox to produce an ISO, and uploads to Cloudflare R2 (download.tunaos.org).

ISO E2E Testing​

Workflow: iso-e2e.yml

Triggered on:

  • PRs touching ISO-related files
  • Schedule (weekly)

Downloads published ISOs, boots them in QEMU+OVMF, and verifies:

  • Live environment reaches desktop (gdm/sddm)
  • Serial console markers
  • Screenshot capture

Snapshot Upstreams​

Workflow: snapshot-upstreams.yml

Triggered on schedule. Monitors upstream repositories for changes and generates porting recommendations.

Code Quality​

Every PR run:

  • CodeQL β€” security analysis (Python, JavaScript/TypeScript)
  • ShellCheck β€” shell script linting
  • shfmt β€” shell script formatting
  • yamllint β€” YAML validation
  • actionlint β€” GitHub Actions workflow validation

Local CI Simulation​

Run the CI matrix locally:

just simulate-matrix

Run all checks:

just check

Fix formatting automatically:

just fix

Cache Strategy​

  • RPM cache: Local builds use .rpm-cache volume shared across all variants; preserved by just clean, removed by just clean-cache
  • Build cache: Podman BuildKit cache mounted at /var/cache/tunaos

Artifact Signing​

All images are signed with cosign using keyless signing (OIDC). Signatures are published to the Rekor transparency log and can be verified:

cosign verify \
--certificate-identity https://github.com/tuna-os/tunaOS/.github/workflows/reusable-build-image.yml@refs/heads/main \
--certificate-oidc-issuer https://token.actions.githubusercontent.com \
ghcr.io/tuna-os/yellowfin:gnome

Public key available in cosign.pub:

cosign verify --key cosign.pub ghcr.io/tuna-os/yellowfin:gnome

Release Publishing​

Container Images​

Published to ghcr.io/tuna-os/ on every successful main build. Tags:

Tag patternWhen
<flavor>Every build (e.g., gnome, kde, gnome-hwe) β€” each flavor is its own tag
<flavor>-<platform>Per-architecture tag (e.g., gnome-linux-amd64)
<sha-short>Every build (immutable reference)

There is no monolithic latest tag β€” each flavor has its own independent tag.

ISOs​

Published weekly to Cloudflare R2 (download.tunaos.org). Currently published variants:

VariantFlavors
Yellowfingnome, gnome-hwe
Albacoregnome, gnome-hwe

ISO expansion to all build_iso: true flavors is tracked in the improvement plan.