feat: complete Gitea Actions CI workflow for container builds
Some checks failed
Build containers when image tags change / build-if-image-changed (., shorefront-backend, shorefront backend, backend/Dockerfile, git.baumann.gr/adebaumann/shorefront-backend, .backend.image) (push) Failing after 41s
Build containers when image tags change / build-if-image-changed (., shorefront-frontend, shorefront frontend, frontend/Dockerfile, git.baumann.gr/adebaumann/shorefront-frontend, .frontend.image) (push) Failing after 41s

- Fix trigger/env path: Helm/ -> helm/ (was wrong case)
- Add image_yq_path and dockerfile to matrix so each container uses its
  own values.yaml key and Dockerfile path
- Fix yq paths: .django.image.* -> .frontend.image/.backend.image for
  repo, .containers.version for tag (single source of truth)
- Add file: param to docker/build-push-action (Dockerfiles are in
  frontend/ and backend/, not repo root)
- values.yaml: add registry prefix to image fields so k8s pulls from
  git.baumann.gr; quote containers.version; drop per-component tag
  fields (containers.version is now the single tag source)
- Deployment templates: use .containers.version for image tag

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
This commit is contained in:
2026-02-28 23:26:00 +01:00
parent cf837fb994
commit 84fd1c8072
4 changed files with 179 additions and 7 deletions

View File

@@ -0,0 +1,171 @@
name: Build containers when image tags change
on:
push:
# Uncomment/adjust once working:
# branches: [ master ]
paths:
- "helm/shorefront/values.yaml"
- "frontend/Dockerfile"
- "backend/Dockerfile"
- ".gitea/workflows/build-containers-on-demand.yml"
jobs:
build-if-image-changed:
runs-on: ubuntu-latest
strategy:
fail-fast: false
matrix:
include:
- container_name: shorefront-frontend
image_yq_path: .frontend.image
expected_repo: git.baumann.gr/adebaumann/shorefront-frontend
dockerfile: frontend/Dockerfile
build_context: .
description: shorefront frontend
- container_name: shorefront-backend
image_yq_path: .backend.image
expected_repo: git.baumann.gr/adebaumann/shorefront-backend
dockerfile: backend/Dockerfile
build_context: .
description: shorefront backend
env:
DEPLOY_FILE: "helm/shorefront/values.yaml"
CONTAINER_NAME: ${{ matrix.container_name }}
EXPECTED_REPO: ${{ matrix.expected_repo }}
steps:
- name: Checkout
uses: actions/checkout@v4
with:
fetch-depth: 2
- name: Determine base commit
id: base
shell: bash
run: |
set -euo pipefail
if git rev-parse --verify -q HEAD~1 >/dev/null; then
echo "base=$(git rev-parse HEAD~1)" >> "$GITHUB_OUTPUT"
else
echo "base=$(git hash-object -t tree /dev/null)" >> "$GITHUB_OUTPUT"
fi
- name: Install yq
shell: bash
run: |
set -euo pipefail
YQ_VER=v4.44.3
curl -sL "https://github.com/mikefarah/yq/releases/download/${YQ_VER}/yq_linux_amd64" -o /usr/local/bin/yq
chmod +x /usr/local/bin/yq
yq --version
- name: Read ${{ matrix.description }} image from Helm values
id: img
shell: bash
run: |
set -euo pipefail
file="${DEPLOY_FILE}"
expected_repo="${EXPECTED_REPO}"
echo "========================================"
echo "Reading image from: $file"
echo "Expected repo: $expected_repo"
echo "========================================"
new_repo=$(yq -r '${{ matrix.image_yq_path }}' "$file")
new_tag=$(yq -r '.containers.version' "$file")
new_image="${new_repo}:${new_tag}"
if git cat-file -e "${{ steps.base.outputs.base }}:$file" 2>/dev/null; then
old_repo=$(git show "${{ steps.base.outputs.base }}:$file" | yq -r '${{ matrix.image_yq_path }}' || true)
old_tag=$(git show "${{ steps.base.outputs.base }}:$file" | yq -r '.containers.version' || true)
old_image="${old_repo}:${old_tag}"
else
old_image="<none>"
fi
echo "Old image: ${old_image}"
echo "New image: ${new_image}"
if [ -z "${new_repo:-}" ] || [ "$new_repo" = "null" ]; then
echo "ERROR: Could not read ${{ matrix.image_yq_path }} from $file"
exit 1
fi
if [[ "$new_repo" != "$expected_repo" ]]; then
echo "ERROR: Found image repo \"$new_repo\" but expected \"$expected_repo\""
exit 1
fi
registry="$(echo "$new_repo" | awk -F/ '{print $1}')"
{
echo "new_image=$new_image"
echo "new_repo=$new_repo"
echo "new_tag=$new_tag"
echo "registry=$registry"
} >> "$GITHUB_OUTPUT"
- name: Check if image exists on registry
id: check_image
shell: bash
run: |
set -euo pipefail
new_repo="${{ steps.img.outputs.new_repo }}"
new_tag="${{ steps.img.outputs.new_tag }}"
registry_user="${{ gitea.actor }}"
registry_password="${{ secrets.REGISTRY_TOKEN }}"
registry_host=$(echo "$new_repo" | cut -d/ -f1)
image_path=$(echo "$new_repo" | cut -d/ -f2-)
echo "Checking if $new_repo:$new_tag exists on registry $registry_host"
manifest_url="https://${registry_host}/v2/${image_path}/manifests/${new_tag}"
http_code=$(curl -s -o /dev/null -w "%{http_code}" \
-u "${registry_user}:${registry_password}" \
-H "Accept: application/vnd.docker.distribution.manifest.v2+json,application/vnd.docker.distribution.manifest.list.v2+json" \
"$manifest_url" || echo "000")
if [ "$http_code" = "200" ]; then
echo "Image already exists on registry (HTTP $http_code)"
echo "exists=true" >> "$GITHUB_OUTPUT"
else
echo "Image does not exist on registry (HTTP $http_code)"
echo "exists=false" >> "$GITHUB_OUTPUT"
fi
- name: Skip if image already exists
if: steps.check_image.outputs.exists == 'true'
run: echo "${{ matrix.description }} image ${{ steps.img.outputs.new_image }} already exists on registry; skipping build."
- name: Set up Buildx
if: steps.check_image.outputs.exists == 'false'
uses: docker/setup-buildx-action@v3
- name: Log in to registry
if: steps.check_image.outputs.exists == 'false'
uses: docker/login-action@v3
with:
registry: ${{ steps.img.outputs.registry }}
username: ${{ gitea.actor }}
password: ${{ secrets.REGISTRY_TOKEN }}
- name: Build and push ${{ matrix.description }} (exact tag from Helm values)
if: steps.check_image.outputs.exists == 'false'
uses: docker/build-push-action@v6
with:
context: ${{ matrix.build_context }}
file: ${{ matrix.dockerfile }}
push: true
tags: |
${{ steps.img.outputs.new_image }}
${{ steps.img.outputs.new_repo }}:latest
labels: |
org.opencontainers.image.source=${{ gitea.repository }}
org.opencontainers.image.revision=${{ gitea.sha }}
cache-from: type=gha
cache-to: type=gha,mode=max