From 7f0a30c01f8da222eb32e9fd43e0fa9e083592b6 Mon Sep 17 00:00:00 2001 From: ckoch Date: Wed, 29 Jul 2026 13:25:52 -0400 Subject: [PATCH] Local build path: pinned alt-tags, manual-only workflow, README build docs Co-Authored-By: Claude Fable 5 --- .gitea/workflows/build.yml | 15 +++++----- .gitignore | 1 + README.md | 57 ++++++++++++++++++++++++++------------ recipes/recipe.yml | 5 ++++ 4 files changed, 53 insertions(+), 25 deletions(-) diff --git a/.gitea/workflows/build.yml b/.gitea/workflows/build.yml index eb8b5ae..5a8b7f3 100644 --- a/.gitea/workflows/build.yml +++ b/.gitea/workflows/build.yml @@ -2,15 +2,16 @@ # is a GitHub-context composite and is not supported outside GitHub/GitLab CI. # Runner requirement: act_runner must allow privileged job containers # (container.privileged: true in the runner's config.yaml) — buildah needs it. +# NOTE: manual-only for now — no Actions runner is registered on the instance, and the +# image is currently built/pushed locally (see README "Building locally"). When a runner +# exists, restore the schedule + push triggers below to make builds fully automatic: +# schedule: +# - cron: "00 06 * * *" # daily rebuild pulls in base-image updates +# push: +# branches: [main] +# paths-ignore: ["**.md"] name: bluebuild on: - schedule: - - cron: "00 06 * * *" # daily rebuild pulls in base-image updates (self-updating) - push: - branches: - - main - paths-ignore: - - "**.md" workflow_dispatch: jobs: diff --git a/.gitignore b/.gitignore index 91b197a..03faf1f 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ # NEVER commit the cosign private key — it goes in the SIGNING_SECRET GitHub secret. cosign.key +/.bluebuild-scripts_* diff --git a/README.md b/README.md index ac6dd74..5c9b88c 100644 --- a/README.md +++ b/README.md @@ -1,8 +1,9 @@ # main-desktop Custom [Bazzite DX](https://github.com/ublue-os/bazzite-dx) image for my desktop, built with -[BlueBuild](https://blue-build.org), published to the container registry on my Gitea instance -(**git.lazypugs.com**) by Gitea Actions, and signed with cosign. +[BlueBuild](https://blue-build.org), published signed (cosign) to the container registry on my +Gitea instance (**git.lazypugs.com**) — built locally today, Gitea Actions-ready when a runner +is registered. - **Base:** `ghcr.io/ublue-os/bazzite-dx-nvidia` — Bazzite DX, KDE Plasma, **NVIDIA open kernel modules**. There is no separate `-open` DX image anymore: DX NVIDIA is open-driver-only, which @@ -21,12 +22,37 @@ in-image, the whole custom layer is "install these Flatpaks on first boot + trus which the `default-flatpaks` and `signing` modules express declaratively in ~40 lines of YAML — no hand-rolled first-boot systemd unit needed. -## CI setup (Gitea Actions) +## Building & publishing -The workflow lives at [.gitea/workflows/build.yml](.gitea/workflows/build.yml) and runs the -**BlueBuild CLI** directly (the `blue-build/github-action` is GitHub-only). It builds on push, -manual dispatch, and daily at 06:00 UTC so base-image updates flow through automatically — that -schedule is what makes the image self-updating. +### Locally (current path) + +The image is built and pushed from a workstation with the BlueBuild CLI driving Docker. From +the repo root (needs `cosign.key` present there, and ~25 GB free for layers): + +```bash +# One-time CLI install (extracts a static binary to /usr/local/bin/bluebuild): +docker run --pull always --rm ghcr.io/blue-build/cli:latest-installer | bash + +# Build, push, and sign in one shot: +BB_USERNAME=ckoch BB_PASSWORD= \ + bluebuild build --push --retry-push \ + --registry git.lazypugs.com --registry-namespace ckoch \ + recipes/recipe.yml +``` + +Tags are pinned in the recipe (`alt-tags: latest, stable-44`), so the pushed refs are the same +no matter where the build runs. Signing happens automatically because `cosign.pub` is in the +repo root and the key is available. **Rebuild cadence is manual under this model** — run the +build when you want base-image updates rolled in; the OS then picks them up on its normal +update timer. + +### Gitea Actions (optional, needs a runner) + +[.gitea/workflows/build.yml](.gitea/workflows/build.yml) runs the same **BlueBuild CLI** build +(the `blue-build/github-action` is GitHub-only). It is currently `workflow_dispatch`-only +because no Actions runner is registered on the instance; when one exists, restore the +commented-out `schedule` + `push` triggers in the workflow to make builds fully automatic +(daily rebuilds = true self-updating). Repo secrets (already configured): @@ -39,18 +65,13 @@ Repo secrets (already configured): the secret** (repo Settings → Actions → Secrets, or `PUT /api/v1/repos/ckoch/main-desktop/actions/secrets/REGISTRY_TOKEN`). -Runner requirements (act_runner on the instance): +Runner requirements when you set one up (act_runner): - **Privileged job containers must be allowed** — the build runs buildah inside the job container (`ghcr.io/blue-build/cli`). In the runner's `config.yaml`: `container: { privileged: true }`. Without it the build fails at the buildah stage. - Internet access (pulls the multi-GB Bazzite base from ghcr.io) and ~25+ GB free scratch disk. -Known first-run watch-items (verified docs, but no public precedent for this exact stack): -cosign signature push to a Gitea registry and the CLI's tag generation under act_runner's -GitHub-compat env are both expected to work but unproven in the wild — if the first run fails -at signing or tagging, that's where to look, not the recipe. - ## Rebasing the desktop onto this image From the existing Bazzite install, rebase in two steps — first unsigned (this installs the image, @@ -192,12 +213,12 @@ no local hypervisor tooling in this image. ## Maintenance - **Change the Flatpak list / packages:** edit [recipes/recipe.yml](recipes/recipe.yml), push, - and the next update picks it up. (Removing an app from the list does not uninstall it from the - machine; `flatpak uninstall` it once by hand.) + rebuild (see "Building & publishing"), and the next OS update picks it up. (Removing an app + from the list does not uninstall it from the machine; `flatpak uninstall` it once by hand.) - **Jump Fedora majors:** change `image-version: stable-44` → `stable-45` in the recipe when - ready, push, then update normally. -- **Check build status:** the repo's Actions tab; builds also run nightly, so a broken base - shows up there before it reaches the machine. + ready, rebuild, then update normally. +- **Pull in base-image updates:** just rebuild — the base tag is `stable-44`, so each rebuild + picks up the newest Bazzite build within Fedora 44. - **Key hygiene:** `cosign.key` is git-ignored and lives only on the workstation + in the `SIGNING_SECRET` secret — keep a backup (password manager). Losing it means generating a new pair, updating the secret, and re-doing the two-step rebase to re-establish trust. diff --git a/recipes/recipe.yml b/recipes/recipe.yml index 8b4f5c1..a85cba2 100644 --- a/recipes/recipe.yml +++ b/recipes/recipe.yml @@ -12,6 +12,11 @@ description: Bazzite DX NVIDIA (open, KDE) with my first-boot Flatpak set, signe base-image: ghcr.io/ublue-os/bazzite-dx-nvidia # Pinned to Fedora 44. Bump deliberately (stable-45, ...) when ready to jump majors. image-version: stable-44 +# Deterministic tags regardless of where the build runs (local builds would +# otherwise only produce a local- tag; rebase refs rely on :latest). +alt-tags: + - latest + - stable-44 modules: - type: default-flatpaks