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