Files
homelabstack/.gitea/workflows/build-romhacks-orchestrator.yml
ginnoirandClaude Opus 5 60121a5d52
Build romhacks orchestrator image / build-and-push (push) Successful in 2m1s
ci(romhacks): build orchestrator image to the self-hosted registry
Portainer's git auto-update only runs `docker compose pull`, never `build`,
so the orchestrator's `build:` context + local-only
`homelab/romhacks-orchestrator:latest` deadlocked stack 28: every 5-min poll
died on "pull access denied" and the stack sat frozen at 847edff since
2026-06-24 while every other stack moved on.

Build it in CI and push it to registry.ginnoir.com instead, same shape as
famapp's release.yml. Compose switches to the registry image in the next
commit, once the image actually exists.

Push creds come from the committed .env rather than Gitea Actions secrets
(famapp needs those only because its repo doesn't commit .env) — one source
of truth on rotation. Only the two REGISTRY_PUSH_* keys are extracted; the
vault material in that file stays out of the job env.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-25 15:02:10 -05:00

100 lines
4.3 KiB
YAML

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