name: Scheduled Security Build on: schedule: - cron: '0 2 * * 0' # Every Sunday at 02:00 UTC workflow_dispatch: permissions: contents: write packages: write id-token: write pull-requests: read jobs: build: runs-on: ubuntu-latest permissions: contents: write packages: write id-token: write pull-requests: read strategy: fail-fast: false matrix: include: - ubuntu_codename: resolute base_image: ubuntu:26.04 - ubuntu_codename: noble base_image: ubuntu:24.04 - ubuntu_codename: jammy base_image: ubuntu:22.04 steps: - name: Get latest release tag and compute next patch version id: release run: | LATEST_TAG=$(gh release list \ --repo ${{ github.repository }} \ --limit 100 \ --exclude-pre-releases \ --exclude-drafts \ --json tagName \ --jq "[.[] | select(.tagName | startswith(\"${{ matrix.ubuntu_codename }}-\"))] | first | .tagName // empty") if [ -z "${LATEST_TAG}" ]; then echo "No release found for ${{ matrix.ubuntu_codename }} track. Skipping." echo "should_build=false" >> $GITHUB_OUTPUT exit 0 fi # Extract version and bump patch: noble-1.0.2 -> noble-1.0.3 if ! echo "${LATEST_TAG}" | grep -qE '^[a-z]+-[0-9]+\.[0-9]+\.[0-9]+$'; then echo "Tag '${LATEST_TAG}' does not match expected format -.." >&2 exit 1 fi PREFIX="${LATEST_TAG%.*}" # noble-1.0 PATCH="${LATEST_TAG##*.}" # 2 NEXT_PATCH=$((PATCH + 1)) NEXT_TAG="${PREFIX}.${NEXT_PATCH}" # noble-1.0.3 echo "current_tag=${LATEST_TAG}" >> $GITHUB_OUTPUT echo "next_tag=${NEXT_TAG}" >> $GITHUB_OUTPUT echo "should_build=true" >> $GITHUB_OUTPUT env: GH_TOKEN: ${{ github.token }} - name: Checkout release tag if: steps.release.outputs.should_build == 'true' uses: actions/checkout@v4 with: ref: ${{ steps.release.outputs.current_tag }} - name: Prepare if: steps.release.outputs.should_build == 'true' id: prep run: | DOCKER_IMAGE=phusion/baseimage NEXT_TAG=${{ steps.release.outputs.next_tag }} PLATFORMS=amd64,arm,arm64 TAGS="${DOCKER_IMAGE}:${NEXT_TAG}" TAGS="${TAGS}, ${DOCKER_IMAGE}:${{ matrix.ubuntu_codename }}" TAGS="${TAGS}, ghcr.io/${{ github.repository_owner }}/baseimage:${NEXT_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 if: steps.release.outputs.should_build == 'true' uses: docker/setup-qemu-action@v3 with: platforms: ${{ steps.prep.outputs.platforms }} - name: Set up Docker Buildx if: steps.release.outputs.should_build == 'true' uses: docker/setup-buildx-action@v3 with: install: true version: latest driver-opts: image=moby/buildkit:latest - name: Login to GHCR (Github Container Registry) if: steps.release.outputs.should_build == 'true' uses: docker/login-action@v3 with: registry: ghcr.io username: ${{ github.actor }} password: ${{ github.token }} - name: Login to Docker Hub if: steps.release.outputs.should_build == 'true' uses: docker/login-action@v3 with: username: ${{ secrets.DOCKER_USERNAME }} password: ${{ secrets.DOCKER_PASSWORD }} - name: Build and Push if: steps.release.outputs.should_build == 'true' uses: docker/build-push-action@v6 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 - name: Check gh auth status if: steps.release.outputs.should_build == 'true' run: gh auth status env: GH_TOKEN: ${{ github.token }} - name: Create GitHub Release if: steps.release.outputs.should_build == 'true' run: | cat < release_notes.md Automated weekly security rebuild of \`${{ steps.release.outputs.current_tag }}\` with latest \`${{ matrix.base_image }}\` packages. Images pushed: - \`phusion/baseimage:${{ steps.release.outputs.next_tag }}\` - \`phusion/baseimage:${{ matrix.ubuntu_codename }}\` - \`ghcr.io/${{ github.repository_owner }}/baseimage:${{ steps.release.outputs.next_tag }}\` - \`ghcr.io/${{ github.repository_owner }}/baseimage:${{ matrix.ubuntu_codename }}\` EOF set +e GH_RELEASE_OUTPUT=$(gh release create "${{ steps.release.outputs.next_tag }}" \ --repo "${{ github.repository }}" \ --target "$(git rev-parse HEAD)" \ --title "${{ steps.release.outputs.next_tag }}" \ --notes-file release_notes.md 2>&1) GH_RELEASE_EXIT_CODE=$? set -e if [ ${GH_RELEASE_EXIT_CODE} -ne 0 ]; then if echo "${GH_RELEASE_OUTPUT}" | grep -Eq "HTTP 403|Resource not accessible by integration"; then echo "::warning::Skipping GitHub release creation for ${{ steps.release.outputs.next_tag }} because the workflow token cannot create releases." else echo "${GH_RELEASE_OUTPUT}" >&2 exit ${GH_RELEASE_EXIT_CODE} fi else echo "${GH_RELEASE_OUTPUT}" fi env: GH_TOKEN: ${{ github.token }}