From 1f62e5ab1765bfe41e75f72a5ad8f1ceb983dd0b Mon Sep 17 00:00:00 2001 From: Audiobuzz Date: Sun, 21 Jun 2026 09:18:22 +0000 Subject: [PATCH] Add multi branch handling --- .gitea/workflows/dnsmasq-image.yaml | 57 ++++++++++++++++++++++++----- .gitea/workflows/ipxe-image.yaml | 54 ++++++++++++++++++++++----- .gitea/workflows/spdk-image.yaml | 53 ++++++++++++++++++++++----- 3 files changed, 134 insertions(+), 30 deletions(-) diff --git a/.gitea/workflows/dnsmasq-image.yaml b/.gitea/workflows/dnsmasq-image.yaml index 8c75f76..d787fb3 100644 --- a/.gitea/workflows/dnsmasq-image.yaml +++ b/.gitea/workflows/dnsmasq-image.yaml @@ -7,22 +7,36 @@ # Secure Boot keys and no iPXE binary — the signed snponly.efi rides the separate # fleet-ipxe image (ipxe-image.yaml), mounted into dnsmasq at /ipxe. # +# Tagging mirrors gitea-main-ci.yaml so every branch builds a uniquely tagged, +# pushed image you can test without clobbering main: +# - tag push (refs/tags/v1.2.3) -> "1.2.3" (+ :latest) +# - main push (refs/heads/main) -> "main-" (+ :latest) +# - branch push (refs/heads/) -> "-" (dev image, no :latest) +# Set DNSMASQ_VERSION in serving/.env to the tag you want to run. +# # Runs only when the dnsmasq image inputs change (path filter) or on demand. # # Required Gitea repo secrets: PACKAGE_USER, PACKAGE_TOKEN (registry creds). # name: Build dnsmasq image -run-name: ${{ gitea.actor }} builds the serving dnsmasq image +run-name: ${{ gitea.actor }} builds the serving dnsmasq image (${{ gitea.ref_name }}) on: push: branches: - - "main" + - "**" # every branch — dev branches get a branch-name+sha tag + tags: + - "v*" # tag push -> clean semver tag (v1.2.3 -> 1.2.3) paths: - "serving/dnsmasq/**" - ".gitea/workflows/dnsmasq-image.yaml" workflow_dispatch: +# One build per ref at a time; a newer push to the same ref cancels the in-flight. +concurrency: + group: dnsmasq-image-${{ gitea.ref }} + cancel-in-progress: true + env: DNSMASQ_IMAGE: "git.bitasylum.org/audiobuzz/fleet-dnsmasq" @@ -37,6 +51,25 @@ jobs: name: Checkout uses: actions/checkout@v6 + - + name: Derive image tag + id: vars + # Same scheme as gitea-main-ci.yaml: clean semver on a tag push, else + # "-" with the branch sanitized to the OCI tag charset. + run: | + short_sha="$(echo "${GITHUB_SHA}" | cut -c1-7)" + if [ "${GITHUB_REF#refs/tags/}" != "$GITHUB_REF" ]; then + version="${GITHUB_REF#refs/tags/}"; version="${version#v}" + else + branch="${GITHUB_REF#refs/heads/}" + safe_branch="$(printf '%s' "$branch" \ + | sed -e 's#[^A-Za-z0-9._-]#-#g' -e 's#^[.-]*##' | cut -c1-100)" + [ -n "$safe_branch" ] || safe_branch="branch" + version="${safe_branch}-${short_sha}" + fi + echo "version=${version}" >> "$GITHUB_OUTPUT" + echo "Building ${DNSMASQ_IMAGE}:${version}" + - name: Install buildah run: | @@ -58,11 +91,15 @@ jobs: STORAGE_DRIVER: vfs BUILDAH_ISOLATION: chroot run: | - SHA="${{ gitea.sha }}"; SHA="${SHA:0:7}" - echo "Building ${DNSMASQ_IMAGE}:${SHA} (+ :latest)" - buildah bud \ - -t "${DNSMASQ_IMAGE}:${SHA}" \ - -t "${DNSMASQ_IMAGE}:latest" \ - serving/dnsmasq - buildah push "${DNSMASQ_IMAGE}:${SHA}" - buildah push "${DNSMASQ_IMAGE}:latest" + VER="${{ steps.vars.outputs.version }}" + buildah bud -t "${DNSMASQ_IMAGE}:${VER}" serving/dnsmasq + buildah push "${DNSMASQ_IMAGE}:${VER}" + # Only main / release tags move :latest, so dev branches never clobber it. + case "$GITHUB_REF" in + refs/heads/main|refs/tags/*) + buildah tag "${DNSMASQ_IMAGE}:${VER}" "${DNSMASQ_IMAGE}:latest" + buildah push "${DNSMASQ_IMAGE}:latest" + echo "Updated ${DNSMASQ_IMAGE}:latest" ;; + *) + echo "Dev branch build — :latest left untouched (run with DNSMASQ_VERSION=${VER})" ;; + esac diff --git a/.gitea/workflows/ipxe-image.yaml b/.gitea/workflows/ipxe-image.yaml index 887cf26..fc12dcd 100644 --- a/.gitea/workflows/ipxe-image.yaml +++ b/.gitea/workflows/ipxe-image.yaml @@ -12,6 +12,14 @@ # key-agnostic and this one is the only per-Secure-Boot-environment artifact. # See scripts/build-ipxe-oci.sh, docs/secure-boot-keys.md, CLAUDE.md invariant #9. # +# Tagging mirrors gitea-main-ci.yaml so every branch builds a uniquely tagged, +# pushed image you can test without clobbering main: +# - tag push (refs/tags/v1.2.3) -> "1.2.3" (+ :latest) +# - main push (refs/heads/main) -> "" (+ :latest) +# - branch push (refs/heads/) -> "-" (dev image, no :latest) +# - dispatch input always wins. +# Set IPXE_VERSION in serving/.env to the tag you want to run. +# # Runs only when the iPXE inputs change (path filter) or on demand. # # Required Gitea repo secrets: PACKAGE_USER, PACKAGE_TOKEN (registry creds). @@ -21,11 +29,13 @@ # name: Build fleet-ipxe image -run-name: ${{ gitea.actor }} builds the signed fleet-ipxe bootloader image +run-name: ${{ gitea.actor }} builds the signed fleet-ipxe bootloader image (${{ gitea.ref_name }}) on: push: branches: - - "main" + - "**" # every branch — dev branches get a branch-name+sha tag + tags: + - "v*" # tag push -> clean semver tag (v1.2.3 -> 1.2.3) paths: - "scripts/build-ipxe-oci.sh" - ".gitea/workflows/ipxe-image.yaml" @@ -35,6 +45,10 @@ on: description: "Override the image tag (default: sanitized ipxe package version)" required: false +concurrency: + group: ipxe-image-${{ gitea.ref }} + cancel-in-progress: true + env: IPXE_IMAGE: "git.bitasylum.org/audiobuzz/fleet-ipxe" @@ -67,13 +81,28 @@ jobs: SNP=$(find /usr/lib/ipxe /usr/share/ipxe -name 'snponly.efi' 2>/dev/null | head -1) [ -n "$SNP" ] || { echo "snponly.efi not found in the ipxe package" >&2; exit 1; } echo "snponly=$SNP" >> "$GITHUB_OUTPUT" - # Tag: dispatch override, else the ipxe package version sanitized to the - # OCI tag charset ([A-Za-z0-9_.-]). + # Tag scheme (same as gitea-main-ci.yaml, with the ipxe pkg version as the + # main-branch identifier). :latest moves only on main / release tags. + short_sha="$(echo "${GITHUB_SHA}" | cut -c1-7)" RAW=$(dpkg-query -W -f='${Version}' ipxe 2>/dev/null || echo unknown) - VER="${{ inputs.ipxe_version }}" - [ -n "$VER" ] || VER=$(printf '%s' "$RAW" | sed 's/[^A-Za-z0-9_.-]/-/g') + PKGVER=$(printf '%s' "$RAW" | sed 's/[^A-Za-z0-9_.-]/-/g') + push_latest=false + if [ -n "${{ inputs.ipxe_version }}" ]; then + VER="${{ inputs.ipxe_version }}" + elif [ "${GITHUB_REF#refs/tags/}" != "$GITHUB_REF" ]; then + VER="${GITHUB_REF#refs/tags/}"; VER="${VER#v}"; push_latest=true + elif [ "${GITHUB_REF}" = "refs/heads/main" ]; then + VER="$PKGVER"; push_latest=true + else + branch="${GITHUB_REF#refs/heads/}" + safe_branch=$(printf '%s' "$branch" \ + | sed -e 's#[^A-Za-z0-9._-]#-#g' -e 's#^[.-]*##' | cut -c1-80) + [ -n "$safe_branch" ] || safe_branch="branch" + VER="${safe_branch}-${short_sha}" + fi echo "version=$VER" >> "$GITHUB_OUTPUT" - echo "Using snponly.efi=$SNP tag=$VER (ipxe pkg $RAW)" + echo "push_latest=$push_latest" >> "$GITHUB_OUTPUT" + echo "Using snponly.efi=$SNP tag=$VER (ipxe pkg $RAW, latest=$push_latest)" - name: Materialize Secure Boot signing material @@ -114,9 +143,14 @@ jobs: "${SB_KEY_FILE:-}" \ "${SB_CERT_FILE:-}" \ true - # also publish :latest for lab convenience (pin by digest in production) - buildah tag "${IPXE_IMAGE}:${VER}" "${IPXE_IMAGE}:latest" - buildah push "${IPXE_IMAGE}:latest" + # main / release tags also move :latest; dev branches never clobber it. + if [ "${{ steps.src.outputs.push_latest }}" = "true" ]; then + buildah tag "${IPXE_IMAGE}:${VER}" "${IPXE_IMAGE}:latest" + buildah push "${IPXE_IMAGE}:latest" + echo "Updated ${IPXE_IMAGE}:latest" + else + echo "Dev branch build — :latest left untouched (run with IPXE_VERSION=${VER})" + fi - name: Shred Secure Boot signing key diff --git a/.gitea/workflows/spdk-image.yaml b/.gitea/workflows/spdk-image.yaml index 9c54a83..2b1ee36 100644 --- a/.gitea/workflows/spdk-image.yaml +++ b/.gitea/workflows/spdk-image.yaml @@ -9,15 +9,25 @@ # Runs only when the SPDK image inputs change (path filter) or on demand — not # on every commit. Bump SPDK_VERSION (or use the manual run input) to roll SPDK. # +# Builds off ANY branch (dev branches welcome); the SPDK release (SPDK_VERSION / +# the dispatch input) is the --build-arg and the base tag. To avoid clobbering +# the main image, dev branches push "--" and never move +# :latest: +# - tag / main push -> "" (+ :latest) +# - branch push -> "--" (dev image, no :latest) +# Set SPDK_VERSION in serving/.env to the tag you want to run. +# # Required Gitea repo secrets: PACKAGE_USER, PACKAGE_TOKEN (registry creds). # name: Build SPDK NVMe-oF image -run-name: ${{ gitea.actor }} builds the SPDK NVMe/TCP target image +run-name: ${{ gitea.actor }} builds the SPDK NVMe/TCP target image (${{ gitea.ref_name }}) on: push: branches: - - "main" + - "**" # every branch — dev branches get a disambiguated tag + tags: + - "v*" paths: - "serving/spdk/**" - ".gitea/workflows/spdk-image.yaml" @@ -28,9 +38,14 @@ on: required: false default: "v24.09" +# One (slow) build per ref at a time; a newer push to the same ref cancels it. +concurrency: + group: spdk-image-${{ gitea.ref }} + cancel-in-progress: true + env: SPDK_IMAGE: "git.bitasylum.org/audiobuzz/spdk-nvmf" - SPDK_VERSION: "v24.09" # default tag for push-triggered builds + SPDK_VERSION: "v24.09" # default SPDK release for push-triggered builds jobs: spdk-build: @@ -66,12 +81,30 @@ jobs: STORAGE_DRIVER: vfs BUILDAH_ISOLATION: chroot run: | - VER="${{ inputs.spdk_version || env.SPDK_VERSION }}" - echo "Building ${SPDK_IMAGE}:${VER}" + # SPDK release: the --build-arg + base tag (dispatch input wins). + SVER="${{ inputs.spdk_version || env.SPDK_VERSION }}" + short_sha="$(echo "${GITHUB_SHA}" | cut -c1-7)" + # main / release tags -> "" + :latest; dev branches -> + # "--", no :latest (so they don't clobber main). + if [ "${GITHUB_REF#refs/tags/}" != "$GITHUB_REF" ] || [ "$GITHUB_REF" = "refs/heads/main" ]; then + TAG="$SVER"; push_latest=true + else + branch="${GITHUB_REF#refs/heads/}" + safe_branch=$(printf '%s' "$branch" \ + | sed -e 's#[^A-Za-z0-9._-]#-#g' -e 's#^[.-]*##' | cut -c1-80) + [ -n "$safe_branch" ] || safe_branch="branch" + TAG="${SVER}-${safe_branch}-${short_sha}"; push_latest=false + fi + echo "Building ${SPDK_IMAGE}:${TAG} (SPDK $SVER, latest=$push_latest)" buildah bud \ - --build-arg SPDK_VERSION="$VER" \ - -t "${SPDK_IMAGE}:${VER}" \ - -t "${SPDK_IMAGE}:latest" \ + --build-arg SPDK_VERSION="$SVER" \ + -t "${SPDK_IMAGE}:${TAG}" \ serving/spdk - buildah push "${SPDK_IMAGE}:${VER}" - buildah push "${SPDK_IMAGE}:latest" + buildah push "${SPDK_IMAGE}:${TAG}" + if [ "$push_latest" = "true" ]; then + buildah tag "${SPDK_IMAGE}:${TAG}" "${SPDK_IMAGE}:latest" + buildah push "${SPDK_IMAGE}:latest" + echo "Updated ${SPDK_IMAGE}:latest" + else + echo "Dev branch build — :latest left untouched (run with SPDK_VERSION=${TAG})" + fi