Compare commits
7
Commits
779c73d07f
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
768f4ae991
|
||
|
|
648bb34237
|
||
|
|
4ec10db3bc
|
||
|
|
5e6f5bd518
|
||
|
|
9ddab5f1fa
|
||
|
|
8502885a9d
|
||
|
|
20c1efb8a3
|
@@ -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.
|
||||||
@@ -0,0 +1,12 @@
|
|||||||
|
{
|
||||||
|
"version": 1,
|
||||||
|
"deployment": "prepbot-release",
|
||||||
|
"environment": "production",
|
||||||
|
"images": {
|
||||||
|
"prepbot_release_prepbot_image": {
|
||||||
|
"name": "prepbot",
|
||||||
|
"tag": "sha-{revision}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"revision_variable": "prepbot_release_revision"
|
||||||
|
}
|
||||||
@@ -3,42 +3,66 @@ name: Build and Push Container
|
|||||||
on:
|
on:
|
||||||
push:
|
push:
|
||||||
branches:
|
branches:
|
||||||
- master
|
- main
|
||||||
- main
|
|
||||||
tags:
|
tags:
|
||||||
- v*
|
- v*
|
||||||
workflow_dispatch:
|
workflow_dispatch: null
|
||||||
|
pull_request:
|
||||||
|
branches:
|
||||||
|
- main
|
||||||
|
|
||||||
env:
|
env:
|
||||||
REGISTRY: gitea.wayfinderak.com
|
REGISTRY: gitea.wayfinderak.com
|
||||||
IMAGE_NAME: wayfinderak/prepbot
|
IMAGE_NAME: wayfinderak/prepbot
|
||||||
|
|
||||||
|
concurrency:
|
||||||
|
group: ${{ github.workflow }}-${{ github.event_name }}-${{ github.event.pull_request.number
|
||||||
|
|| github.run_id }}
|
||||||
|
cancel-in-progress: ${{ github.event_name == 'pull_request' }}
|
||||||
|
|
||||||
jobs:
|
jobs:
|
||||||
docker:
|
docker:
|
||||||
runs-on: ubuntu-latest
|
runs-on: butler-ci
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v4
|
uses: https://github.com/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: Set up QEMU
|
- name: Set up QEMU
|
||||||
uses: docker/setup-qemu-action@v3
|
if: ${{ steps.delivery.outputs.run == 'true' }}
|
||||||
|
uses: https://github.com/docker/setup-qemu-action@v3
|
||||||
|
with:
|
||||||
|
cache-image: "false"
|
||||||
|
|
||||||
- name: Set up Docker Buildx
|
- name: Set up Docker Buildx
|
||||||
uses: docker/setup-buildx-action@v3
|
if: ${{ steps.delivery.outputs.run == 'true' }}
|
||||||
|
uses: https://github.com/docker/setup-buildx-action@v3
|
||||||
|
|
||||||
- name: Log in to Gitea registry
|
- name: Log in to Gitea registry
|
||||||
uses: docker/login-action@v3
|
if: ${{ (steps.delivery.outputs.run == 'true') && github.event_name != 'pull_request' }}
|
||||||
|
uses: https://github.com/docker/login-action@v3
|
||||||
with:
|
with:
|
||||||
registry: ${{ env.REGISTRY }}
|
registry: ${{ env.REGISTRY }}
|
||||||
username: ${{ secrets.REGISTRY_USERNAME }}
|
username: ${{ secrets.REGISTRY_USERNAME }}
|
||||||
password: ${{ secrets.REGISTRY_PASSWORD }}
|
password: ${{ secrets.REGISTRY_PASSWORD }}
|
||||||
|
|
||||||
- name: Prepare image tags
|
- name: Prepare image tags
|
||||||
|
if: ${{ steps.delivery.outputs.run == 'true' }}
|
||||||
id: prep
|
id: prep
|
||||||
shell: bash
|
shell: bash
|
||||||
run: |
|
run: |
|
||||||
short_sha="${GITHUB_SHA::7}"
|
short_sha="${GITHUB_SHA::7}"
|
||||||
tags="${REGISTRY}/${IMAGE_NAME}:sha-${short_sha}"
|
tags="${REGISTRY}/${IMAGE_NAME}:sha-${short_sha}"
|
||||||
|
tags+=$'\n'"${REGISTRY}/${IMAGE_NAME}:sha-${GITHUB_SHA}"
|
||||||
|
|
||||||
if [[ "${GITHUB_REF_TYPE}" == "branch" && ("${GITHUB_REF_NAME}" == "master" || "${GITHUB_REF_NAME}" == "main") ]]; then
|
if [[ "${GITHUB_REF_TYPE}" == "branch" && ("${GITHUB_REF_NAME}" == "master" || "${GITHUB_REF_NAME}" == "main") ]]; then
|
||||||
tags+=$'\n'"${REGISTRY}/${IMAGE_NAME}:latest"
|
tags+=$'\n'"${REGISTRY}/${IMAGE_NAME}:latest"
|
||||||
@@ -56,9 +80,13 @@ jobs:
|
|||||||
} >> "$GITHUB_OUTPUT"
|
} >> "$GITHUB_OUTPUT"
|
||||||
|
|
||||||
- name: Build and push image
|
- name: Build and push image
|
||||||
uses: docker/build-push-action@v6
|
if: ${{ steps.delivery.outputs.run == 'true' }}
|
||||||
|
uses: https://github.com/docker/build-push-action@v6
|
||||||
|
env:
|
||||||
|
DOCKER_BUILD_RECORD_UPLOAD: "false"
|
||||||
with:
|
with:
|
||||||
context: .
|
context: .
|
||||||
push: true
|
push: ${{ github.event_name != 'pull_request' }}
|
||||||
platforms: linux/amd64,linux/arm64
|
platforms: linux/amd64,linux/arm64
|
||||||
tags: ${{ steps.prep.outputs.tags }}
|
tags: ${{ steps.prep.outputs.tags }}
|
||||||
|
labels: org.opencontainers.image.revision=${{ github.sha }}
|
||||||
|
|||||||
@@ -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"
|
||||||
Reference in New Issue
Block a user