name: Release

on:
  push:
    tags:
      - 'v*'

env:
  REGISTRY: git.dolgolyov-family.by
  IMAGE_NAME: alexei.dolgolyov/notify-bridge

jobs:
  test-backend:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4

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

      # Same wheel-first strategy as build.yml — editable install is too slow
      # on the hosted runner.
      - name: Build wheels
        run: |
          python -m pip install --upgrade pip build
          mkdir -p /tmp/wheels
          pip wheel --no-deps -w /tmp/wheels packages/core packages/server

      - name: Install backend + test deps
        run: |
          pip install /tmp/wheels/*.whl pytest pytest-asyncio httpx aioresponses prometheus_client

      - name: Run pytest
        env:
          NOTIFY_BRIDGE_DATA_DIR: /tmp/nb-test-data
          NOTIFY_BRIDGE_SECRET_KEY: ci-secret-key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
          NOTIFY_BRIDGE_DEBUG: "false"
          NOTIFY_BRIDGE_CORS_ALLOWED_ORIGINS: "http://localhost:8420"
        run: |
          cd packages/server
          pytest tests --tb=short

  release:
    needs: [test-backend]
    runs-on: ubuntu-latest
    steps:
      - name: Checkout repo
        uses: actions/checkout@v4
        with:
          fetch-depth: 0

      - name: Extract version from tag
        id: version
        run: |
          TAG="${{ gitea.ref_name }}"
          VERSION="${TAG#v}"
          echo "tag=$TAG" >> "$GITHUB_OUTPUT"
          echo "version=$VERSION" >> "$GITHUB_OUTPUT"

          IS_PRE="false"
          if echo "$TAG" | grep -qE '(alpha|beta|rc)'; then
            IS_PRE="true"
          fi
          echo "is_pre=$IS_PRE" >> "$GITHUB_OUTPUT"

      - name: Login to Gitea Container Registry
        uses: docker/login-action@v3
        with:
          registry: ${{ env.REGISTRY }}
          username: ${{ gitea.actor }}
          password: ${{ secrets.DEPLOY_TOKEN }}

      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3

      - name: Build and push Docker image
        uses: docker/build-push-action@v5
        with:
          context: .
          push: true
          tags: |
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.tag }}
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:${{ steps.version.outputs.version }}
            ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:sha-${{ gitea.sha }}
            ${{ steps.version.outputs.is_pre == 'false' && format('{0}/{1}:latest', env.REGISTRY, env.IMAGE_NAME) || '' }}
          cache-from: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache
          cache-to: type=registry,ref=${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:buildcache,mode=max

      - name: Trigger redeploy webhook
        if: steps.version.outputs.is_pre == 'false'
        continue-on-error: true
        run: |
          if [ -n "${{ secrets.DOCKER_REDEPLOY_WEBHOOK_URL }}" ]; then
            echo "Triggering redeploy webhook..."
            curl -sf -X POST "${{ secrets.DOCKER_REDEPLOY_WEBHOOK_URL }}" \
              --max-time 30 || echo "::warning::Redeploy webhook failed"
          else
            echo "DOCKER_REDEPLOY_WEBHOOK_URL not set — skipping auto-deploy"
          fi

      - name: Generate changelog
        id: changelog
        run: |
          PREV_TAG=$(git tag --sort=-v:refname | head -2 | tail -1)
          if [ -z "$PREV_TAG" ] || [ "$PREV_TAG" = "${{ gitea.ref_name }}" ]; then
            CHANGELOG=$(git log --oneline --no-decorate -n 20)
          else
            CHANGELOG=$(git log --oneline --no-decorate ${PREV_TAG}..HEAD)
          fi
          echo "$CHANGELOG" > /tmp/changelog.txt

      - name: Create Gitea Release
        env:
          DEPLOY_TOKEN: ${{ secrets.DEPLOY_TOKEN }}
        run: |
          TAG="${{ steps.version.outputs.tag }}"
          VERSION="${{ steps.version.outputs.version }}"
          IS_PRE="${{ steps.version.outputs.is_pre }}"
          BASE_URL="https://${{ env.REGISTRY }}/api/v1/repos/${{ env.IMAGE_NAME }}"

          if [ -f RELEASE_NOTES.md ]; then
            export RELEASE_NOTES=$(cat RELEASE_NOTES.md)
            echo "Found RELEASE_NOTES.md"
          else
            export RELEASE_NOTES=""
            echo "No RELEASE_NOTES.md found"
          fi

          # Build release payload (avoids shell escaping & CLI length limits)
          export TAG VERSION IS_PRE
          python3 <<'PY'
          import json, os

          release_notes = os.environ.get('RELEASE_NOTES', '')
          changelog = open('/tmp/changelog.txt').read().strip()

          sections = []
          if release_notes.strip():
              sections.append(release_notes.strip())
          if changelog:
              sections.append('## Changelog\n\n' + changelog)

          payload = {
              'tag_name': os.environ['TAG'],
              'name': f"Notify Bridge {os.environ['VERSION']}",
              'body': '\n\n'.join(sections),
              'draft': False,
              'prerelease': os.environ['IS_PRE'] == 'true',
          }
          with open('/tmp/release-payload.json', 'w') as f:
              json.dump(payload, f)
          PY

          HTTP=$(curl -s -o /tmp/release-resp.json -w "%{http_code}" \
            -X POST "$BASE_URL/releases" \
            -H "Authorization: token $DEPLOY_TOKEN" \
            -H "Content-Type: application/json" \
            --data-binary @/tmp/release-payload.json)

          echo "POST /releases → HTTP $HTTP"
          echo "--- response ---"
          head -c 2000 /tmp/release-resp.json; echo
          echo "----------------"

          if [ "$HTTP" = "201" ]; then
            RELEASE_ID=$(python3 -c "import json; print(json.load(open('/tmp/release-resp.json'))['id'])")
            echo "Created release $RELEASE_ID for $TAG"
          elif [ "$HTTP" = "409" ] || grep -q "already exists" /tmp/release-resp.json; then
            echo "::warning::Release already exists for tag $TAG — reusing"
            HTTP2=$(curl -s -o /tmp/release-resp.json -w "%{http_code}" \
              "$BASE_URL/releases/tags/$TAG" \
              -H "Authorization: token $DEPLOY_TOKEN")
            if [ "$HTTP2" != "200" ]; then
              echo "::error::Failed to fetch existing release (HTTP $HTTP2)"
              cat /tmp/release-resp.json
              exit 1
            fi
            RELEASE_ID=$(python3 -c "import json; print(json.load(open('/tmp/release-resp.json'))['id'])")
            echo "Reused release $RELEASE_ID for $TAG"
          else
            echo "::error::Failed to create release for $TAG (HTTP $HTTP)"
            exit 1
          fi
