name: CI

on:
  push:
    branches: [main]
  pull_request:
    branches: [main]
  workflow_dispatch:

jobs:
  lint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.11" }
      - run: pip install -r requirements.txt
      - run: pip install -r requirements-audit.txt
      - run: python3 -m pip_audit -r requirements.txt --strict
      - run: python3 -m pytest tests/ -q

  build-release:
    runs-on: ubuntu-latest
    needs: lint
    steps:
      - uses: actions/checkout@v4
      - name: Build deterministic release bundle
        run: |
          SOURCE_DATE_EPOCH="$(git show -s --format=%ct "$GITHUB_SHA")"
          python3 scripts/build_release.py \
            --root . \
            --output-dir dist \
            --commit "$GITHUB_SHA" \
            --source-date-epoch "$SOURCE_DATE_EPOCH"
      - name: Upload tested release bundle
        uses: actions/upload-artifact@v3
        with:
          name: release-bundle
          path: dist/

  browser-journey:
    runs-on: ubuntu-latest
    needs: build-release
    env:
      STACKCHAIN_RUN_RELEASE_E2E: "1"
    steps:
      - uses: actions/checkout@v4
      - uses: actions/setup-python@v5
        with: { python-version: "3.11" }
      - name: Download assembled release bundle
        uses: actions/download-artifact@v3
        with:
          name: release-bundle
          path: dist
      - name: Install browser test dependencies
        run: |
          pip install -r requirements-e2e.txt
          python3 -m playwright install --with-deps chromium
      - name: Exercise packaged mobile work journeys
        run: python3 -m pytest tests/e2e/test_mobile_offline_issue_release.py tests/e2e/test_mobile_search_preview_navigation.py tests/e2e/test_mobile_search_week_plan.py tests/e2e/test_mobile_find_work_release.py tests/e2e/test_mobile_home_bootstrap_release.py tests/e2e/test_mobile_sign_out_release.py tests/e2e/test_mobile_today_handoff_release.py tests/e2e/test_mobile_today_wrap_up_release.py tests/e2e/test_mobile_today_summary_release.py tests/e2e/test_mobile_tomorrow_conflict_release.py tests/e2e/test_mobile_week_ahead_release.py tests/e2e/test_mobile_today_week_reschedule_release.py tests/e2e/test_mobile_wrap_up_handoff_release.py tests/e2e/test_mobile_following_release.py tests/e2e/test_mobile_detail_watch_release.py -q

  release-candidate:
    runs-on: ubuntu-latest
    needs: [lint, build-release, browser-journey]
    if: github.event_name == 'push' && github.ref == 'refs/heads/main'
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v4
      - name: Download tested release bundle
        uses: actions/download-artifact@v3
        with:
          name: release-bundle
          path: dist
      - name: Verify and publish release candidate
        env:
          TOKEN: ${{ secrets.GITHUB_TOKEN }}
        run: |
          set -euo pipefail
          TARGET="${{ github.sha }}"
          TAG="v0.1.0-rc.${{ github.run_number }}"
          RELEASE_URL="${{ github.server_url }}/api/v1/repos/${{ github.repository }}/releases"

          (cd dist && sha256sum -c ./*.sha256)
          python3 scripts/verify_release.py --input-dir dist --commit "$TARGET" --repository .

          printf '{"tag_name":"%s","target_commitish":"%s","name":"Release Candidate %s","body":"CI-tested release candidate for commit %s. Verify downloads with the attached SHA-256 checksum.","draft":true,"prerelease":true}\n' \
            "$TAG" "$TARGET" "$TAG" "$TARGET" > /tmp/release.json
          curl --fail-with-body -sS -X POST "$RELEASE_URL" \
            -H "Authorization: token $TOKEN" \
            -H "Content-Type: application/json" \
            --data-binary @/tmp/release.json > /tmp/release-response.json
          RELEASE_ID="$(python3 -c 'import json; print(json.load(open("/tmp/release-response.json"))["id"])')"

          for ASSET in dist/*; do
            NAME="$(basename "$ASSET")"
            ENCODED_NAME="$(python3 -c 'import sys,urllib.parse; print(urllib.parse.quote(sys.argv[1]))' "$NAME")"
            curl --fail-with-body -sS -X POST "$RELEASE_URL/$RELEASE_ID/assets?name=$ENCODED_NAME" \
              -H "Authorization: token $TOKEN" \
              -H "Content-Type: application/octet-stream" \
              --data-binary "@$ASSET"
          done

          printf '{"draft":false,"prerelease":true}\n' > /tmp/publish.json
          curl --fail-with-body -sS -X PATCH "$RELEASE_URL/$RELEASE_ID" \
            -H "Authorization: token $TOKEN" \
            -H "Content-Type: application/json" \
            --data-binary @/tmp/publish.json
