name: flutter

# Analyze + test + build the Flutter mobile client. Only runs when the
# diff touches flutter_client/ or one of the shared web inputs the
# sync_shared.sh script copies. Other pushes skip — this workflow is
# independent from the Go/web test.yml and release.yml.

on:
  push:
    branches: [dev, main]
    tags: ['v*']
    paths:
      - 'flutter_client/**'
      - 'web/src/lib/styles/tokens.json'
      - 'web/src/lib/styles/error-copy.json'
      - 'web/static/placeholders/album-fallback.svg'
      - '.forgejo/workflows/flutter.yml'
  pull_request:
    branches: [main]
    paths:
      - 'flutter_client/**'
      - 'web/src/lib/styles/tokens.json'
      - 'web/src/lib/styles/error-copy.json'
      - 'web/static/placeholders/album-fallback.svg'
      - '.forgejo/workflows/flutter.yml'
  workflow_dispatch:

jobs:
  analyze-test-build:
    # flutter-ci runner image (CI-Runner/CI-flutter/Dockerfile) bakes in
    # Flutter SDK + Android cmdline-tools + platform-34 + build-tools 34.0.0
    # + JDK 17 + a non-root `runner` user. No setup-action ceremony needed.
    runs-on: flutter-ci

    defaults:
      run:
        working-directory: flutter_client

    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Sync shared assets from web/
        run: ./tool/sync_shared.sh

      - name: Verify generated tokens.dart matches JSON
        shell: bash
        run: |
          dart run tool/gen_tokens.dart
          if ! git diff --exit-code lib/theme/tokens.dart; then
            echo "::error::lib/theme/tokens.dart is out of sync with shared/fabledsword.tokens.json"
            echo "Run: cd flutter_client && dart run tool/gen_tokens.dart"
            exit 1
          fi

      - name: Pub get
        run: flutter pub get

      - name: Analyze
        run: flutter analyze --fatal-infos

      - name: Test
        run: flutter test --reporter compact

      - name: Build debug APK
        if: github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/')
        run: flutter build apk --debug

      - name: Build release APK
        if: startsWith(github.ref, 'refs/tags/v')
        run: flutter build apk --release

      - name: Upload debug APK artifact
        if: github.event_name == 'push' && !startsWith(github.ref, 'refs/tags/')
        uses: forgejo/upload-artifact@v3
        with:
          name: minstrel-debug-${{ github.sha }}
          path: flutter_client/build/app/outputs/flutter-apk/app-debug.apk

      - name: Attach release APK to release
        if: startsWith(github.ref, 'refs/tags/v')
        shell: bash
        env:
          RELEASE_TOKEN: ${{ secrets.RELEASE_TOKEN }}
        run: |
          TAG="${GITHUB_REF#refs/tags/}"
          REPO="${GITHUB_REPOSITORY}"
          # Look up the release ID for this tag (release must exist already;
          # release.yml creates it as part of the server-side release flow).
          RELEASE_ID=$(curl -fsSL \
            -H "Authorization: token ${RELEASE_TOKEN}" \
            "https://git.fabledsword.com/api/v1/repos/${REPO}/releases/tags/${TAG}" \
            | grep -oP '"id":\s*\K[0-9]+' | head -1)
          if [ -z "${RELEASE_ID}" ]; then
            echo "::error::release for tag ${TAG} not found"
            exit 1
          fi
          curl -fsSL \
            -H "Authorization: token ${RELEASE_TOKEN}" \
            -F "attachment=@build/app/outputs/flutter-apk/app-release.apk" \
            "https://git.fabledsword.com/api/v1/repos/${REPO}/releases/${RELEASE_ID}/assets?name=minstrel-${TAG}.apk"
