diff --git a/.gitea/workflows/build-romhacks-orchestrator.yml b/.gitea/workflows/build-romhacks-orchestrator.yml new file mode 100644 index 0000000..7ed66ad --- /dev/null +++ b/.gitea/workflows/build-romhacks-orchestrator.yml @@ -0,0 +1,99 @@ +name: Build romhacks orchestrator image + +# The romhacks orchestrator is the one stack service whose image is built from +# source in THIS repo. Portainer's git auto-update only ever runs +# `docker compose pull` — never `build` — so a compose `build:` context plus a +# local-only `image:` name deadlocks the stack: every poll fails with +# "pull access denied for homelab/romhacks-orchestrator" and the stack freezes +# at whatever commit last deployed. +# +# So the image is built here and pushed to the self-hosted registry, exactly +# like famapp (ginnoir/famapp .gitea/workflows/release.yml). Compose then just +# pulls a real image like every other service. +# +# Triggered by any change under stacks/romhacks/orchestrator/ (scripts, +# channels.json, Dockerfile). Editing channels.json => push => new :latest. + +on: + push: + branches: [main] + paths: + - stacks/romhacks/orchestrator/** + - .gitea/workflows/build-romhacks-orchestrator.yml + workflow_dispatch: + +concurrency: + group: build-romhacks-orchestrator + cancel-in-progress: false + +jobs: + build-and-push: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Ensure docker CLI + buildx + run: | + # Debian's docker.io package ships no buildx plugin, which the + # registry-cache build below requires. Install Docker's official + # CLI + buildx plugin so the build works regardless of what the + # runner image happens to provide. + if docker buildx version >/dev/null 2>&1; then + echo "docker + buildx already available" + docker version + docker buildx version + exit 0 + fi + + export DEBIAN_FRONTEND=noninteractive + apt-get update -qq + apt-get install -y -qq ca-certificates curl gnupg + install -m 0755 -d /etc/apt/keyrings + curl -fsSL https://download.docker.com/linux/debian/gpg -o /etc/apt/keyrings/docker.asc + chmod a+r /etc/apt/keyrings/docker.asc + echo "deb [arch=$(dpkg --print-architecture) signed-by=/etc/apt/keyrings/docker.asc] https://download.docker.com/linux/debian $(. /etc/os-release && echo "$VERSION_CODENAME") stable" \ + > /etc/apt/sources.list.d/docker.list + apt-get update -qq + apt-get install -y -qq docker-ce-cli docker-buildx-plugin + docker version + docker buildx version + + - name: Login to registry + run: | + # Unlike famapp (separate repo, .env not committed => Gitea Actions + # secrets), this repo commits .env on purpose, so REGISTRY_PUSH_* is + # already in the checkout. One source of truth on rotation, no + # out-of-band repo secrets to drift. + # Pull ONLY these two keys rather than sourcing .env wholesale — that + # file also carries the vault unseal keys/root token, which have no + # business in this job's environment. Piped to --password-stdin, so + # the value is never echoed, never in argv, never in the job log. + eval "$(grep -E '^REGISTRY_PUSH_(USERNAME|PASSWORD)=' ./.env | sed 's/^/export /')" + if [ -z "${REGISTRY_PUSH_USERNAME:-}" ] || [ -z "${REGISTRY_PUSH_PASSWORD:-}" ]; then + echo "REGISTRY_PUSH_USERNAME/PASSWORD missing from .env" >&2 + exit 1 + fi + printf '%s' "$REGISTRY_PUSH_PASSWORD" | docker login registry.ginnoir.com \ + --username "$REGISTRY_PUSH_USERNAME" \ + --password-stdin + + - name: Set up buildx + run: | + docker buildx create --name romhacks-builder --use 2>/dev/null || docker buildx use romhacks-builder + docker buildx inspect --bootstrap + + - name: Build and push image + env: + IMAGE: registry.ginnoir.com/ginnoir/romhacks-orchestrator + CACHE: registry.ginnoir.com/ginnoir/romhacks-orchestrator:buildcache + run: | + # No v* tags in this repo (it holds ~50 stacks, not one app), so the + # immutable tag is the commit sha; compose tracks :latest. + SHA_TAG="sha-$(printf '%s' "$GITHUB_SHA" | cut -c1-7)" + docker buildx build \ + --push \ + --tag "${IMAGE}:latest" \ + --tag "${IMAGE}:${SHA_TAG}" \ + --cache-from "type=registry,ref=${CACHE}" \ + --cache-to "type=registry,ref=${CACHE},mode=max" \ + stacks/romhacks/orchestrator