# Multi-repo Docker build template for tier-3 prep (e.g. state-hub + hub-core).
# Copy to: .forgejo/workflows/image.yaml and set PRIMARY_REPO + EXTRA_REPOS.
# Uses archive checkout (no actions/checkout; non-root runner has no git).
# Dockerfile must reference named contexts, e.g.:
#   COPY --from=hub_core_src pyproject.toml /tmp/hub-core/pyproject.toml
name: Build and Publish Multi-Context Image

on:
  push:
    branches:
      - main
    # Must list every path the Dockerfile COPYs, or a change ships to git
    # without ever reaching the image. This previously covered only api/**,
    # so edits to mcp_server/ and — more seriously — migrations/ produced no
    # rebuild (CUST-WP-0067-T08).
    paths:
      - ".forgejo/workflows/image.yaml"
      - "Dockerfile"
      - "alembic.ini"
      - "api/**"
      - "flows/**"
      - "mcp_server/**"
      - "migrations/**"
      - "policies/**"
      - "prompts/**"
      - "pyproject.toml"
      - "scripts/**"
      - "task_flow_engine/**"
      - "templates/**"
      - "uv.lock"
  workflow_dispatch:

env:
  REGISTRY: forgejo.coulomb.social
  IMAGE_NAME: coulomb/state-hub
  DOCKER_HOST: tcp://127.0.0.1:2375
  # Space-separated coulomb/repo@context_name entries for extra build contexts.
  # Example: "coulomb/hub-core@hub_core_src"
  EXTRA_REPOS: "coulomb/hub-core@hub_core_src"

jobs:
  build-and-push:
    runs-on: container-build
    steps:
      - name: Build and push image
        env:
          REGISTRY_USER: ${{ secrets.REGISTRY_USER }}
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
        run: |
          set -eu
          REF="${GITHUB_SHA:-main}"
          SHORT="${REF:0:7}"
          mkdir -p buildctx "${HOME}/bin"
          # Forgejo archive endpoint accepts short SHA; full SHA can hang.
          wget -qO /tmp/primary.tar.gz \
            "https://forgejo.coulomb.social/${GITHUB_REPOSITORY}/archive/${SHORT}.tar.gz"
          tar xzf /tmp/primary.tar.gz -C buildctx --strip-components=1
          BUILD_ARGS=()
          for spec in ${EXTRA_REPOS}; do
            repo="${spec%@*}"
            ctx="${spec#*@}"
            # Extra repos track their own main branch; primary SHA is not valid there.
            extra_ref="main"
            wget -qO "/tmp/${ctx}.tar.gz" \
              "https://forgejo.coulomb.social/${repo}/archive/${extra_ref}.tar.gz"
            mkdir -p "/tmp/ctx-${ctx}"
            tar xzf "/tmp/${ctx}.tar.gz" -C "/tmp/ctx-${ctx}" --strip-components=1
          done
          # Runner DinD has legacy docker (no buildx); vendor hub-core into context.
          mkdir -p buildctx/_hub_core_src
          cp -r /tmp/ctx-hub_core_src/pyproject.toml /tmp/ctx-hub_core_src/hub_core buildctx/_hub_core_src/
          echo "${SHORT}" > buildctx/.ci-build-id
          grep -q 'asyncpg' buildctx/pyproject.toml
          sed \
            -e 's|^COPY pyproject.toml|COPY .ci-build-id /tmp/.ci-build-id\nCOPY pyproject.toml|' \
            -e 's|COPY --from=hub_core_src pyproject.toml|COPY _hub_core_src/pyproject.toml|' \
            -e 's|COPY --from=hub_core_src hub_core/|COPY _hub_core_src/hub_core/|' \
            buildctx/Dockerfile > buildctx/Dockerfile.ci
          wget -qO- https://download.docker.com/linux/static/stable/x86_64/docker-27.3.1.tgz \
            | tar xz --strip-components=1 -C "${HOME}/bin" docker/docker
          export PATH="${HOME}/bin:${PATH}"
          echo "${REGISTRY_TOKEN}" | docker login "${REGISTRY}" -u "${REGISTRY_USER}" --password-stdin
          IMAGE="${REGISTRY}/${IMAGE_NAME}"
          docker build --build-arg DEPS_LOCK_ID=10 -f buildctx/Dockerfile.ci \
            -t "${IMAGE}:latest" -t "${IMAGE}:main-${SHORT}" buildctx
          docker push "${IMAGE}:latest"
          docker push "${IMAGE}:main-${SHORT}"
          echo "pushed ${IMAGE}:latest and ${IMAGE}:main-${SHORT}"