Move to Gitea: Gitea Actions workflow (BlueBuild CLI), registry git.lazypugs.com
bluebuild / Build Custom Image (push) Has been cancelled
bluebuild / Build Custom Image (push) Has been cancelled
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
@@ -0,0 +1,41 @@
|
|||||||
|
# Gitea Actions workflow. Uses the BlueBuild CLI directly — the blue-build/github-action
|
||||||
|
# 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.
|
||||||
|
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:
|
||||||
|
bluebuild:
|
||||||
|
name: Build Custom Image
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
container:
|
||||||
|
image: ghcr.io/blue-build/cli:v0.9
|
||||||
|
options: --privileged
|
||||||
|
env:
|
||||||
|
# Auto-signs on push when this + cosign.pub (repo root) are present.
|
||||||
|
COSIGN_PRIVATE_KEY: ${{ secrets.SIGNING_SECRET }}
|
||||||
|
# Gitea's auto job token cannot push packages (documented limitation),
|
||||||
|
# so registry auth uses a PAT with write:package scope.
|
||||||
|
BB_REGISTRY: git.lazypugs.com
|
||||||
|
BB_REGISTRY_NAMESPACE: ckoch
|
||||||
|
BB_USERNAME: ckoch
|
||||||
|
BB_PASSWORD: ${{ secrets.REGISTRY_TOKEN }}
|
||||||
|
steps:
|
||||||
|
# Plain clone instead of actions/checkout: the CLI job container isn't
|
||||||
|
# guaranteed to have node, and the repo is public.
|
||||||
|
- name: Clone repo
|
||||||
|
run: |
|
||||||
|
git config --global --add safe.directory "$(pwd)"
|
||||||
|
git clone --depth 1 --branch "${GITHUB_REF_NAME:-main}" "${GITHUB_SERVER_URL}/${GITHUB_REPOSITORY}.git" .
|
||||||
|
|
||||||
|
- name: Build and push signed image
|
||||||
|
run: bluebuild build --verbose --push --retry-push recipes/recipe.yml
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
name: bluebuild
|
|
||||||
on:
|
|
||||||
schedule:
|
|
||||||
- cron: "00 06 * * *" # daily rebuild pulls in base-image updates (self-updating)
|
|
||||||
push:
|
|
||||||
branches:
|
|
||||||
- main
|
|
||||||
paths-ignore:
|
|
||||||
- "**.md"
|
|
||||||
pull_request:
|
|
||||||
workflow_dispatch:
|
|
||||||
|
|
||||||
concurrency:
|
|
||||||
group: ${{ github.workflow }}-${{ github.ref }}
|
|
||||||
cancel-in-progress: true
|
|
||||||
|
|
||||||
jobs:
|
|
||||||
bluebuild:
|
|
||||||
name: Build Custom Image
|
|
||||||
runs-on: ubuntu-latest
|
|
||||||
permissions:
|
|
||||||
contents: read
|
|
||||||
packages: write
|
|
||||||
id-token: write
|
|
||||||
strategy:
|
|
||||||
fail-fast: false
|
|
||||||
matrix:
|
|
||||||
recipe:
|
|
||||||
- recipe.yml
|
|
||||||
steps:
|
|
||||||
- name: Build Custom Image
|
|
||||||
uses: blue-build/github-action@v1.12.0
|
|
||||||
with:
|
|
||||||
recipe: ${{ matrix.recipe }}
|
|
||||||
cosign_private_key: ${{ secrets.SIGNING_SECRET }}
|
|
||||||
registry_token: ${{ github.token }}
|
|
||||||
pull_request_number: ${{ github.event.number }}
|
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
# main-desktop
|
# main-desktop
|
||||||
|
|
||||||
Custom [Bazzite DX](https://github.com/ublue-os/bazzite-dx) image for my desktop, built with
|
Custom [Bazzite DX](https://github.com/ublue-os/bazzite-dx) image for my desktop, built with
|
||||||
[BlueBuild](https://blue-build.org), published to GHCR by GitHub Actions, and signed with cosign.
|
[BlueBuild](https://blue-build.org), published to the container registry on my Gitea instance
|
||||||
|
(**git.lazypugs.com**) by Gitea Actions, and signed with cosign.
|
||||||
|
|
||||||
- **Base:** `ghcr.io/ublue-os/bazzite-dx-nvidia` — Bazzite DX, KDE Plasma, **NVIDIA open kernel
|
- **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
|
modules**. There is no separate `-open` DX image anymore: DX NVIDIA is open-driver-only, which
|
||||||
@@ -20,29 +21,35 @@ 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 —
|
which the `default-flatpaks` and `signing` modules express declaratively in ~40 lines of YAML —
|
||||||
no hand-rolled first-boot systemd unit needed.
|
no hand-rolled first-boot systemd unit needed.
|
||||||
|
|
||||||
## One-time setup (before first push)
|
## CI setup (Gitea Actions)
|
||||||
|
|
||||||
1. Create a GitHub repo and push this directory to it (`main` branch).
|
The workflow lives at [.gitea/workflows/build.yml](.gitea/workflows/build.yml) and runs the
|
||||||
2. Generate the signing keypair in the repo root (**press Enter for an empty password** — the
|
**BlueBuild CLI** directly (the `blue-build/github-action` is GitHub-only). It builds on push,
|
||||||
build action cannot use an encrypted key):
|
manual dispatch, and daily at 06:00 UTC so base-image updates flow through automatically — that
|
||||||
|
schedule is what makes the image self-updating.
|
||||||
|
|
||||||
```bash
|
Repo secrets (already configured):
|
||||||
cosign generate-key-pair
|
|
||||||
```
|
|
||||||
|
|
||||||
3. Store the private key as an Actions secret and commit only the public half:
|
- `SIGNING_SECRET` — contents of `cosign.key` (generated with an empty password; the public half
|
||||||
|
is committed as `cosign.pub`). The CLI signs automatically on push when both are present.
|
||||||
|
- `REGISTRY_TOKEN` — a Gitea personal access token with **write:package** scope, used to push to
|
||||||
|
the registry. Gitea's automatic per-job token *cannot* publish packages (documented Gitea
|
||||||
|
limitation), hence the PAT. **Currently seeded with a temporary token — before revoking it,
|
||||||
|
create a durable PAT (Settings → Applications → Generate token, `write:package`) and update
|
||||||
|
the secret** (repo Settings → Actions → Secrets, or
|
||||||
|
`PUT /api/v1/repos/ckoch/main-desktop/actions/secrets/REGISTRY_TOKEN`).
|
||||||
|
|
||||||
```bash
|
Runner requirements (act_runner on the instance):
|
||||||
gh secret set SIGNING_SECRET < cosign.key
|
|
||||||
git add cosign.pub && git commit -m "Add cosign public key" && git push
|
|
||||||
```
|
|
||||||
|
|
||||||
`cosign.key` is git-ignored — never commit it.
|
- **Privileged job containers must be allowed** — the build runs buildah inside the job
|
||||||
4. The workflow (`.github/workflows/build.yml`) now builds on every push, on manual dispatch, and
|
container (`ghcr.io/blue-build/cli`). In the runner's `config.yaml`:
|
||||||
daily at 06:00 UTC (so base-image updates flow through automatically — this is what makes the
|
`container: { privileged: true }`. Without it the build fails at the buildah stage.
|
||||||
image self-updating). Images publish to `ghcr.io/<your-github-user>/main-desktop`.
|
- Internet access (pulls the multi-GB Bazzite base from ghcr.io) and ~25+ GB free scratch disk.
|
||||||
5. If the GHCR package ends up private, make it public in the package settings (Packages →
|
|
||||||
main-desktop → Package settings → Change visibility), or rebasing will fail to pull.
|
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
|
## Rebasing the desktop onto this image
|
||||||
|
|
||||||
@@ -51,11 +58,11 @@ which contains the signing policy and public key), then signed:
|
|||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Step 1: unsigned rebase, then reboot
|
# Step 1: unsigned rebase, then reboot
|
||||||
rpm-ostree rebase ostree-unverified-registry:ghcr.io/<your-github-user>/main-desktop:latest
|
rpm-ostree rebase ostree-unverified-registry:git.lazypugs.com/ckoch/main-desktop:latest
|
||||||
systemctl reboot
|
systemctl reboot
|
||||||
|
|
||||||
# Step 2: switch to the signed ref, then reboot
|
# Step 2: switch to the signed ref, then reboot
|
||||||
rpm-ostree rebase ostree-image-signed:docker://ghcr.io/<your-github-user>/main-desktop:latest
|
rpm-ostree rebase ostree-image-signed:docker://git.lazypugs.com/ckoch/main-desktop:latest
|
||||||
systemctl reboot
|
systemctl reboot
|
||||||
```
|
```
|
||||||
|
|
||||||
@@ -64,6 +71,14 @@ in the recipe, so `latest` never crosses a major until the recipe says so.
|
|||||||
|
|
||||||
Roll back anytime with `rpm-ostree rollback` (or pick the previous deployment in the boot menu).
|
Roll back anytime with `rpm-ostree rollback` (or pick the previous deployment in the boot menu).
|
||||||
|
|
||||||
|
Notes for a self-hosted registry:
|
||||||
|
|
||||||
|
- The repo/package is public, so anonymous pulls work and the desktop needs no auth config. If
|
||||||
|
you ever make it private, the *host* needs credentials in `/etc/ostree/auth.json`
|
||||||
|
(containers-auth.json format) — `podman login` alone does not cover OS updates.
|
||||||
|
- Updates only flow while git.lazypugs.com is reachable; if the box is down, updates pause and
|
||||||
|
retry later. The running system is unaffected.
|
||||||
|
|
||||||
## Install-time checklist
|
## Install-time checklist
|
||||||
|
|
||||||
1. **Driver sanity:** `nvidia-smi` reports driver **≥ 580** (currently 610.x) and the RTX 5090 is
|
1. **Driver sanity:** `nvidia-smi` reports driver **≥ 580** (currently 610.x) and the RTX 5090 is
|
||||||
@@ -72,11 +87,11 @@ Roll back anytime with `rpm-ostree rollback` (or pick the previous deployment in
|
|||||||
2. **Signature:** verify the published image against the committed public key:
|
2. **Signature:** verify the published image against the committed public key:
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
cosign verify --key cosign.pub ghcr.io/<your-github-user>/main-desktop:latest
|
cosign verify --key cosign.pub git.lazypugs.com/ckoch/main-desktop:latest
|
||||||
```
|
```
|
||||||
|
|
||||||
3. **Deployment:** `rpm-ostree status` shows the booted deployment is
|
3. **Deployment:** `rpm-ostree status` shows the booted deployment is
|
||||||
`ostree-image-signed:docker://ghcr.io/<your-github-user>/main-desktop` and the base version
|
`ostree-image-signed:docker://git.lazypugs.com/ckoch/main-desktop` and the base version
|
||||||
matches a recent build.
|
matches a recent build.
|
||||||
4. **Flatpaks:** the first-boot service installs the whole list below; give it a few minutes on
|
4. **Flatpaks:** the first-boot service installs the whole list below; give it a few minutes on
|
||||||
first login (it notifies when done). Check with `flatpak list --system`.
|
first login (it notifies when done). Check with `flatpak list --system`.
|
||||||
@@ -181,5 +196,8 @@ no local hypervisor tooling in this image.
|
|||||||
machine; `flatpak uninstall` it once by hand.)
|
machine; `flatpak uninstall` it once by hand.)
|
||||||
- **Jump Fedora majors:** change `image-version: stable-44` → `stable-45` in the recipe when
|
- **Jump Fedora majors:** change `image-version: stable-44` → `stable-45` in the recipe when
|
||||||
ready, push, then update normally.
|
ready, push, then update normally.
|
||||||
- **Check build status:** the Actions tab; builds also run nightly, so a broken base shows up
|
- **Check build status:** the repo's Actions tab; builds also run nightly, so a broken base
|
||||||
there before it reaches the machine.
|
shows up there before it reaches the machine.
|
||||||
|
- **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.
|
||||||
|
|||||||
Reference in New Issue
Block a user