name: Image rebuild (skip scrape)

# Fast path for code-only changes. Skips the scrape and goes straight to:
# rebuild indexes (from corpus already committed on main) + image build
# + push. Runtime is ~18 min vs ~40 min for the full refresh.
#
# Use when a PR only changes code/config — anything where the upstream
# corpus hasn't moved but we want the new Python in the running image.
#
# IMPORTANT: fetch-depth: 0 is required for the digest-history step
# to find commits to walk. Don't change to 1.

on:
  workflow_dispatch:

env:
  # PUSH goes to the LAN endpoint (HTTP) to bypass Cloudflare's 100 MB
  # body cap. PULL uses the public hostname (HTTPS). Same Gitea registry.
  REGISTRY_PUSH: 192.168.0.2:1234
  REGISTRY_PULL: git.jpaul.io
  IMAGE: ${{ github.repository_owner }}/${{ github.event.repository.name }}
  # Two GPU-pinned Ollama containers on the Gitea host — same infra
  # zerto-docs uses. :11435 = Titan X, :11436 = 1080 Ti. Indexer
  # round-robins per batch.
  OLLAMA_URLS: http://192.168.0.2:11435,http://192.168.0.2:11436,http://192.168.0.125:11434,http://192.168.0.126:11434
  EMBED_MODEL: nomic-embed-text
  PRODUCT_NAME: hvm

jobs:
  build:
    runs-on: docker
    container:
      image: catthehacker/ubuntu:act-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          # Full history so digest-history can walk git log.
          fetch-depth: 0

      - name: Set up Python
        uses: actions/setup-python@v5
        with:
          python-version: "3.12"

      - name: Install dependencies
        run: |
          python -m pip install -q --upgrade pip
          python -m pip install -q -r requirements.txt

      - name: Refresh digest history
        # Cheap (few seconds). Without this step, a code-only deploy
        # would ship an increasingly-stale digest history.
        run: |
          mkdir -p corpus/.digest
          python -m scrape.changelog \
              --history-out corpus/.digest/history.jsonl \
              --history-days 120

      - name: Verify committed corpus is present
        run: |
          test -d corpus || { echo "ERROR: corpus/ missing on this ref"; exit 1; }
          echo "corpus: $(du -sh corpus | cut -f1), $(find corpus -name '*.md' | wc -l) markdown files"

      - name: Rebuild indexes from existing corpus
        run: python -m rag.index --rebuild

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
        with:
          # LAN registry is HTTP only.
          config-inline: |
            [registry."192.168.0.2:1234"]
              http = true
              insecure = true

      - name: Configure registry credentials for buildx
        env:
          REGISTRY_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
          REGISTRY_USER: ${{ github.actor }}
        run: |
          mkdir -p ~/.docker
          AUTH=$(printf '%s:%s' "$REGISTRY_USER" "$REGISTRY_TOKEN" | base64 -w0)
          cat > ~/.docker/config.json <<EOF
          {
            "auths": {
              "192.168.0.2:1234": {
                "auth": "$AUTH"
              }
            }
          }
          EOF

      - name: Compute tags
        id: meta
        uses: docker/metadata-action@v5
        with:
          images: 192.168.0.2:1234/${{ github.repository_owner }}/${{ github.event.repository.name }}
          tags: |
            type=raw,value=latest
            type=sha,prefix=,format=short
            type=raw,value={{date 'YYYY.MM.DD'}}
          labels: |
            org.opencontainers.image.source=https://git.jpaul.io/${{ github.repository_owner }}/${{ github.event.repository.name }}
            org.opencontainers.image.url=https://git.jpaul.io/${{ github.repository_owner }}/${{ github.event.repository.name }}

      - name: Build & push (amd64)
        uses: docker/build-push-action@v6
        with:
          context: .
          platforms: linux/amd64
          push: true
          tags: ${{ steps.meta.outputs.tags }}
          labels: ${{ steps.meta.outputs.labels }}

      - name: Link container package to this repo
        env:
          GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
        run: |
          OWNER="${{ github.repository_owner }}"
          PKG="${{ github.event.repository.name }}"
          code=$(curl -s -o /tmp/link.out -w "%{http_code}" -X POST \
            -H "Authorization: token ${GITEA_TOKEN}" \
            "https://git.jpaul.io/api/v1/packages/${OWNER}/container/${PKG}/-/link/${PKG}")
          echo "link ${OWNER}/container/${PKG} -> ${PKG}: HTTP ${code}"
          body=$(cat /tmp/link.out)
          case "$code" in
            201)      echo "OK — newly linked" ;;
            400|409)  echo "OK — already linked: ${body}" ;;
            *)        echo "unexpected: ${body}"; exit 1 ;;
          esac

      - name: Prune old container versions
        env:
          GITEA_TOKEN: ${{ secrets.REGISTRY_TOKEN }}
        run: |
          python scripts/registry_gc.py \
            --owner "${{ github.repository_owner }}" \
            --package "${{ github.event.repository.name }}" \
            --keep-days 90 \
            --keep-latest 5
