From 44a761d9ebe181d11bcdc9a48f85f085d748a15b Mon Sep 17 00:00:00 2001 From: Copilot <198982749+Copilot@users.noreply.github.com> Date: Fri, 27 Feb 2026 13:01:16 +0200 Subject: [PATCH] Automated weekly security rebuilds for all active Ubuntu LTS tracks (#652) * Add scheduled security builds for multiple LTS tracks (jammy + noble) Co-authored-by: Theaxiom <57013+Theaxiom@users.noreply.github.com> * Address review feedback: checkout at release tag, exclude pre-releases/drafts, warn on unknown tag prefix Co-authored-by: Theaxiom <57013+Theaxiom@users.noreply.github.com> --------- Co-authored-by: copilot-swe-agent[bot] <198982749+Copilot@users.noreply.github.com> Co-authored-by: Theaxiom <57013+Theaxiom@users.noreply.github.com> --- .github/workflows/main.yml | 13 ++++ .github/workflows/scheduled-build.yml | 91 +++++++++++++++++++++++++++ 2 files changed, 104 insertions(+) create mode 100644 .github/workflows/scheduled-build.yml diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml index 1cb5107..e749661 100644 --- a/.github/workflows/main.yml +++ b/.github/workflows/main.yml @@ -20,6 +20,17 @@ jobs: # Set the platforms to build for here and thus reduce duplicating it. PLATFORMS=amd64,arm,arm64 TAGS="${DOCKER_IMAGE}:${GIT_BRANCH}, ghcr.io/${{ github.repository_owner }}/baseimage:${GIT_BRANCH}" + + # Determine BASE_IMAGE from release tag prefix (e.g. noble-1.0.2 -> ubuntu:24.04) + if [[ "${GIT_BRANCH}" == noble-* ]]; then + BASE_IMAGE="ubuntu:24.04" + elif [[ "${GIT_BRANCH}" == jammy-* ]]; then + BASE_IMAGE="ubuntu:22.04" + else + # Default to noble (latest LTS) for unrecognised tag prefixes + echo "::warning::Unrecognized release tag prefix '${GIT_BRANCH}'. Expected it to start with 'noble-' or 'jammy-'. Defaulting BASE_IMAGE to ubuntu:24.04 (Noble)." + BASE_IMAGE="ubuntu:24.04" + fi # Set output parameters. @@ -32,6 +43,7 @@ jobs: echo "docker_image=${DOCKER_IMAGE}" >> $GITHUB_OUTPUT fi echo "platforms=${PLATFORMS}" >> $GITHUB_OUTPUT + echo "base_image=${BASE_IMAGE}" >> $GITHUB_OUTPUT - name: Set up QEMU @@ -71,3 +83,4 @@ jobs: platforms: ${{ steps.prep.outputs.platforms }} push: ${{ steps.prep.outputs.push }} tags: ${{ steps.prep.outputs.tags }} + build-args: BASE_IMAGE=${{ steps.prep.outputs.base_image }} diff --git a/.github/workflows/scheduled-build.yml b/.github/workflows/scheduled-build.yml new file mode 100644 index 0000000..a4beae7 --- /dev/null +++ b/.github/workflows/scheduled-build.yml @@ -0,0 +1,91 @@ +name: Scheduled Security Build + +on: + schedule: + - cron: '0 2 * * 0' # Every Sunday at 02:00 UTC + workflow_dispatch: + +jobs: + build: + runs-on: ubuntu-latest + permissions: + contents: read + packages: write + strategy: + fail-fast: false + matrix: + include: + - ubuntu_codename: noble + base_image: ubuntu:24.04 + - ubuntu_codename: jammy + base_image: ubuntu:22.04 + steps: + - name: Get latest release tag for this LTS track + id: release + run: | + LATEST_TAG=$(gh release list \ + --repo ${{ github.repository }} \ + --exclude-pre-releases \ + --exclude-drafts \ + --json tagName \ + --jq '[.[] | select(.tagName | startswith("${{ matrix.ubuntu_codename }}-"))] | first | .tagName') + if [ -z "${LATEST_TAG}" ]; then + echo "No release found for ${{ matrix.ubuntu_codename }} track" >&2 + exit 1 + fi + echo "tag=${LATEST_TAG}" >> $GITHUB_OUTPUT + env: + GH_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + - name: Checkout release tag + uses: actions/checkout@v4 + with: + ref: ${{ steps.release.outputs.tag }} + + - name: Prepare + id: prep + run: | + DOCKER_IMAGE=phusion/baseimage + RELEASE_TAG=${{ steps.release.outputs.tag }} + PLATFORMS=amd64,arm,arm64 + TAGS="${DOCKER_IMAGE}:${RELEASE_TAG}" + TAGS="${TAGS}, ${DOCKER_IMAGE}:${{ matrix.ubuntu_codename }}" + TAGS="${TAGS}, ghcr.io/${{ github.repository_owner }}/baseimage:${RELEASE_TAG}" + TAGS="${TAGS}, ghcr.io/${{ github.repository_owner }}/baseimage:${{ matrix.ubuntu_codename }}" + echo "tags=${TAGS}" >> $GITHUB_OUTPUT + echo "platforms=${PLATFORMS}" >> $GITHUB_OUTPUT + + - name: Set up QEMU + uses: docker/setup-qemu-action@v3 + with: + platforms: ${{ steps.prep.outputs.platforms }} + + - name: Set up Docker Buildx + uses: docker/setup-buildx-action@v3 + with: + install: true + version: latest + driver-opts: image=moby/buildkit:latest + + - name: Login to GHCR (Github Container Registry) + uses: docker/login-action@v3 + with: + registry: ghcr.io + username: ${{ github.actor }} + password: ${{ secrets.GITHUB_TOKEN }} + + - name: Login to Docker Hub + uses: docker/login-action@v3 + with: + username: ${{ secrets.DOCKER_USERNAME }} + password: ${{ secrets.DOCKER_PASSWORD }} + + - name: Build and Push + uses: docker/build-push-action@v5 + with: + context: image + platforms: ${{ steps.prep.outputs.platforms }} + push: true + tags: ${{ steps.prep.outputs.tags }} + build-args: BASE_IMAGE=${{ matrix.base_image }} + no-cache: true