From 67cc71b05c841da9c5356b228090a7593d6eb5de Mon Sep 17 00:00:00 2001 From: Butler Agent Date: Fri, 11 Sep 2026 08:10:34 +0000 Subject: [PATCH 1/5] Scope documentation CI and isolate delivery job resources --- .gitea/workflows/build-and-push.yml | 16 ++++++++++++ scripts/ci-select.sh | 39 +++++++++++++++++++++++++++++ 2 files changed, 55 insertions(+) create mode 100644 scripts/ci-select.sh diff --git a/.gitea/workflows/build-and-push.yml b/.gitea/workflows/build-and-push.yml index 1a329dc..7fb2bb5 100644 --- a/.gitea/workflows/build-and-push.yml +++ b/.gitea/workflows/build-and-push.yml @@ -21,7 +21,18 @@ jobs: - name: Checkout uses: actions/checkout@v4 + - name: Select relevant delivery work + id: delivery + env: + DELIVERY_EVENT: ${{ github.event_name }} + DELIVERY_REF: ${{ github.ref }} + DELIVERY_SHA: ${{ github.sha }} + DELIVERY_BASE: ${{ github.event.pull_request.base.sha || github.event.before }} + run: | + cd . + bash scripts/ci-select.sh - name: Install Go and Docker CLI if needed + if: ${{ steps.delivery.outputs.run == 'true' }} shell: bash run: | set -euo pipefail @@ -62,9 +73,11 @@ jobs: docker version - name: Run tests + if: ${{ steps.delivery.outputs.run == 'true' }} run: go test ./... - name: Log in to Gitea Container Registry + if: ${{ steps.delivery.outputs.run == 'true' }} shell: bash run: | set -euo pipefail @@ -79,6 +92,7 @@ jobs: exit 1 - name: Determine image tags + if: ${{ steps.delivery.outputs.run == 'true' }} id: meta shell: bash env: @@ -109,6 +123,7 @@ jobs: printf 'EOF\n' >> "$GITHUB_OUTPUT" - name: Build image + if: ${{ steps.delivery.outputs.run == 'true' }} shell: bash run: | set -euo pipefail @@ -124,6 +139,7 @@ jobs: docker build "${build_args[@]}" . - name: Push image + if: ${{ steps.delivery.outputs.run == 'true' }} shell: bash run: | set -euo pipefail diff --git a/scripts/ci-select.sh b/scripts/ci-select.sh new file mode 100644 index 0000000..7260b1b --- /dev/null +++ b/scripts/ci-select.sh @@ -0,0 +1,39 @@ +#!/usr/bin/env bash +# Keep required jobs alive; only skip reviewed non-runtime documentation paths. +set -euo pipefail +base="${DELIVERY_BASE:-}" +head="$(git rev-parse HEAD)" +run=true +if [[ "${DELIVERY_REF:-}" != refs/tags/* && "$head" == "${DELIVERY_SHA:-}" && "${DELIVERY_EVENT:-}" =~ ^(push|pull_request)$ && "$base" =~ ^[0-9a-f]{40}$ && "$base" != 0000000000000000000000000000000000000000 ]]; then + if ! git cat-file -e "$base^{commit}" 2>/dev/null; then + if [[ -n "${DELIVERY_FETCH_TOKEN:-}" ]]; then + git -c "http.extraHeader=Authorization: token ${DELIVERY_FETCH_TOKEN}" fetch --quiet --depth=1 origin "$base" >/dev/null 2>&1 || true + else + git fetch --quiet --depth=1 origin "$base" >/dev/null 2>&1 || true + fi + fi + if git cat-file -e "$base^{commit}" 2>/dev/null; then + paths="$(mktemp)" + trap 'rm -f -- "$paths"' EXIT + # Snapshot comparison is conservative when main advanced during a PR. + # Both rename sides remain visible, including names containing newlines. + if git diff --no-renames --name-only -z "$base" "$head" > "$paths"; then + run=false + while IFS= read -r -d '' path; do + case "$path" in + README.md|CHANGELOG.md|LICENSE|LICENSE.md) ;; + *) run=true; break ;; + esac + done < "$paths" + fi + fi +fi +if [[ "$run" == false ]]; then + echo 'Only reviewed non-runtime documentation changed; build and validation are not applicable.' +else + echo 'Runtime, unknown inputs, or unavailable event history: run required validation.' +fi +if [[ -n "${GITHUB_OUTPUT:-}" ]]; then + echo "run=$run" >> "$GITHUB_OUTPUT" +fi +printf '%s\n' "$run" -- 2.54.0 From d1eb5f05afe1b7e653bded9df7c19ec3d5a7be5e Mon Sep 17 00:00:00 2001 From: Butler Agent Date: Fri, 11 Sep 2026 08:37:24 +0000 Subject: [PATCH 2/5] Run pull request validation once through native CI --- .gitea/workflows/build-and-push.yml | 16 +++++++++------- 1 file changed, 9 insertions(+), 7 deletions(-) diff --git a/.gitea/workflows/build-and-push.yml b/.gitea/workflows/build-and-push.yml index 7fb2bb5..ec37adb 100644 --- a/.gitea/workflows/build-and-push.yml +++ b/.gitea/workflows/build-and-push.yml @@ -3,15 +3,17 @@ name: Build and Push Container on: push: branches: - - master - - main + - master tags: - - v* - workflow_dispatch: + - v* + workflow_dispatch: null + pull_request: + branches: + - master jobs: build-and-push: - runs-on: ubuntu-latest + runs-on: butler-ci env: REGISTRY: gitea.wayfinderak.com IMAGE_NAME: gitea.wayfinderak.com/wayfinderak/geeksbot @@ -77,7 +79,7 @@ jobs: run: go test ./... - name: Log in to Gitea Container Registry - if: ${{ steps.delivery.outputs.run == 'true' }} + if: ${{ (steps.delivery.outputs.run == 'true') && github.event_name != 'pull_request' }} shell: bash run: | set -euo pipefail @@ -139,7 +141,7 @@ jobs: docker build "${build_args[@]}" . - name: Push image - if: ${{ steps.delivery.outputs.run == 'true' }} + if: ${{ (steps.delivery.outputs.run == 'true') && github.event_name != 'pull_request' }} shell: bash run: | set -euo pipefail -- 2.54.0 From 198c3e7952d62e3772f92036b9bc7ef1c41682fc Mon Sep 17 00:00:00 2001 From: Butler Agent Date: Fri, 11 Sep 2026 08:47:06 +0000 Subject: [PATCH 3/5] Cancel superseded pull request validation without cancelling releases --- .gitea/workflows/build-and-push.yml | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/.gitea/workflows/build-and-push.yml b/.gitea/workflows/build-and-push.yml index ec37adb..dcf7cf7 100644 --- a/.gitea/workflows/build-and-push.yml +++ b/.gitea/workflows/build-and-push.yml @@ -11,6 +11,11 @@ on: branches: - master +concurrency: + group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number + || github.run_id }} + cancel-in-progress: ${{ github.event_name == 'pull_request' }} + jobs: build-and-push: runs-on: butler-ci -- 2.54.0 From 593d6c552e65fbb585ffc40da21ed180f000e315 Mon Sep 17 00:00:00 2001 From: Butler Agent Date: Fri, 11 Sep 2026 08:53:23 +0000 Subject: [PATCH 4/5] feat(delivery): publish immutable source images and declare release --- .butler/README.md | 5 +++++ .butler/deployment.json | 12 ++++++++++++ .gitea/workflows/build-and-push.yml | 4 ++-- 3 files changed, 19 insertions(+), 2 deletions(-) create mode 100644 .butler/README.md create mode 100644 .butler/deployment.json diff --git a/.butler/README.md b/.butler/README.md new file mode 100644 index 0000000..a70684e --- /dev/null +++ b/.butler/README.md @@ -0,0 +1,5 @@ +# Service release contract + +Butler resolves this repository's protected source revision to verified immutable images. The platform updates only image references in the existing production Compose file and restarts only the already running application services. It preserves current environment, storage, routes, and provider configuration. It retains previous application images and restores them if readiness fails. + +Migration and maintenance images are pinned when declared, but this release operation does not run database migrations or maintenance jobs. A release requiring a schema change needs the corresponding explicit platform migration first. No homelab image-pin commit is required for an ordinary compatible application release. diff --git a/.butler/deployment.json b/.butler/deployment.json new file mode 100644 index 0000000..4d238d3 --- /dev/null +++ b/.butler/deployment.json @@ -0,0 +1,12 @@ +{ + "version": 1, + "deployment": "geeksbot-release", + "environment": "production", + "images": { + "geeksbot_release_geeksbot_image": { + "name": "geeksbot", + "tag": "sha-{revision}" + } + }, + "revision_variable": "geeksbot_release_revision" +} diff --git a/.gitea/workflows/build-and-push.yml b/.gitea/workflows/build-and-push.yml index dcf7cf7..2c71a46 100644 --- a/.gitea/workflows/build-and-push.yml +++ b/.gitea/workflows/build-and-push.yml @@ -108,7 +108,7 @@ jobs: SHA: ${{ gitea.sha }} run: | set -euo pipefail - tags=() + tags=("$IMAGE_NAME:sha-$SHA") if [[ "$REF" == refs/tags/* ]]; then version="$REF_NAME" @@ -143,7 +143,7 @@ jobs: build_args+=(--tag "$tag") done - docker build "${build_args[@]}" . + docker build --label "org.opencontainers.image.revision=$GITHUB_SHA" "${build_args[@]}" . - name: Push image if: ${{ (steps.delivery.outputs.run == 'true') && github.event_name != 'pull_request' }} -- 2.54.0 From dd2e4793614898889b9cd8255c3764f88052e4d2 Mon Sep 17 00:00:00 2001 From: Butler Agent Date: Fri, 11 Sep 2026 09:14:35 +0000 Subject: [PATCH 5/5] Resolve upstream Actions explicitly and check out the exact event revision --- .gitea/workflows/build-and-push.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitea/workflows/build-and-push.yml b/.gitea/workflows/build-and-push.yml index 2c71a46..acd72eb 100644 --- a/.gitea/workflows/build-and-push.yml +++ b/.gitea/workflows/build-and-push.yml @@ -26,7 +26,7 @@ jobs: options: --dns 172.16.30.10 steps: - name: Checkout - uses: actions/checkout@v4 + uses: https://github.com/actions/checkout@v4 - name: Select relevant delivery work id: delivery -- 2.54.0