name: Create release and upload to Apple and Google
on:
  push:
    tags:
      # Only builds for tags with a meaningless build number suffix: v1.0.0-1
      - 'v[0-9]+.[0-9]+.[0-9]+-*'

jobs:
  build:
    name: Build ios and android package
    runs-on: macos-latest

    steps:
      - name: Check out code
        uses: actions/checkout@v4
        with:
          show-progress: false
          fetch-depth: 25 # For sentry releases

      - name: Set up Go 1.22
        uses: actions/setup-go@v5
        with:
          go-version: "1.22"
          cache-dependency-path: nebula/go.sum

      - uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: '17'

      - name: Install flutter
        uses: subosito/flutter-action@v2
        with:
          flutter-version: '3.27.0'

      - name: Setup bundletool for APK generation
        uses: amyu/setup-bundletool@f7a6fdd8e04bb23d2fdf3c2f60c9257a6298a40a

      - name: Install the appstore connect key material
        env:
          AC_API_KEY_SECRET_BASE64: ${{ secrets.AC_API_KEY_SECRET_BASE64 }}
        run: |
          AC_API_KEY_SECRET_PATH="$RUNNER_TEMP/key.p8"
          echo "APP_STORE_CONNECT_API_KEY_KEY_FILEPATH=$AC_API_KEY_SECRET_PATH" >> $GITHUB_ENV
          echo -n "$AC_API_KEY_SECRET_BASE64" | base64 --decode --output "$AC_API_KEY_SECRET_PATH"

      - name: Install the google play key material
        env:
          GOOGLE_PLAY_API_JWT_BASE64: ${{ secrets.GOOGLE_PLAY_API_JWT_BASE64 }}
          GOOGLE_PLAY_KEYSTORE_BASE64: ${{ secrets.GOOGLE_PLAY_KEYSTORE_BASE64 }}
        run: |
          GOOGLE_PLAY_API_JWT_PATH="$RUNNER_TEMP/gp_api.json"
          echo "GOOGLE_PLAY_API_JWT_PATH=$GOOGLE_PLAY_API_JWT_PATH" >> $GITHUB_ENV
          echo -n "$GOOGLE_PLAY_API_JWT_BASE64" | base64 --decode --output "$GOOGLE_PLAY_API_JWT_PATH"

          GOOGLE_PLAY_KEYSTORE_PATH="$RUNNER_TEMP/gp_signing.jks"
          echo "GOOGLE_PLAY_KEYSTORE_PATH=$GOOGLE_PLAY_KEYSTORE_PATH" >> $GITHUB_ENV
          echo -n "$GOOGLE_PLAY_KEYSTORE_BASE64" | base64 --decode --output "$GOOGLE_PLAY_KEYSTORE_PATH"

      - name: Place Github token for fastlane match
        env:
          TOKEN: ${{ secrets.MACHINE_USER_PAT }}
        run:
          echo "MATCH_GIT_BASIC_AUTHORIZATION=$(echo -n "defined-machine:${TOKEN}" | base64)" >> $GITHUB_ENV

      - name: Get build name and number, install dependencies
        env:
          TOKEN: ${{ secrets.MACHINE_USER_PAT }}
        run: |
          go install golang.org/x/mobile/cmd/gomobile@latest
          gomobile init

          flutter pub get

          touch env.sh

          cd android
          fastlane release_build_number
          echo "BUILD_NUMBER=$(cat ../release_build_number)" >> $GITHUB_ENV
          BUILD_NAME="${GITHUB_REF#refs/tags/v}" # strip the front refs/tags/v off
          BUILD_NAME="${BUILD_NAME%-*}" # strip the junk build number off
          echo "BUILD_NAME=$BUILD_NAME" >> $GITHUB_ENV

      - name: Build iOS
        env:
          TOKEN: ${{ secrets.MACHINE_USER_PAT }}
          MATCH_PASSWORD: ${{ secrets.MATCH_PASSWORD }}
        run: |
          cd ios
          pod install
          fastlane build
          cd -

          # verify that the github token didn't make it into the output
          mkdir -p build/app/test-ios
          cp ios/MobileNebula.ipa build/app/test-ios
          cd build/app/test-ios
          unzip MobileNebula.ipa
          if find . | xargs strings 2>/dev/null | grep -qF "${TOKEN}" ; then
            echo "Token found in iOS build"
            exit 1
          fi

      - name: Collect iOS artifacts
        uses: actions/upload-artifact@v4
        with:
          name: MobileNebula.ipa
          path: ios/MobileNebula.ipa
          retention-days: 5

      - name: Build Android
        env:
          TOKEN: ${{ secrets.MACHINE_USER_PAT }}
          GOOGLE_PLAY_KEYSTORE_PASSWORD: ${{ secrets.GOOGLE_PLAY_KEYSTORE_PASSWORD }}
        run: |
          flutter build appbundle --build-number="$BUILD_NUMBER" --build-name="$BUILD_NAME"

          # verify that the github token didn't make it into the output
          mkdir -p build/app/test-android
          cp build/app/outputs/bundle/release/app-release.aab build/app/test-android
          cd build/app/test-android
          unzip app-release.aab
          if find . | xargs strings 2>/dev/null | grep -qF "${TOKEN}" ; then
            echo "Token found in Android build"
            exit 1
          fi

      - name: Generate universal APK
        env:
          TOKEN: ${{ secrets.MACHINE_USER_PAT }}
          GOOGLE_PLAY_KEYSTORE_PASSWORD: ${{ secrets.GOOGLE_PLAY_KEYSTORE_PASSWORD }}
        run: |
          bundletool build-apks \
            --bundle=build/app/outputs/bundle/release/app-release.aab \
            --output=build/app/outputs/apk/release/MobileNebula.apks \
            --mode=universal \
            --ks=$GOOGLE_PLAY_KEYSTORE_PATH \
            --ks-key-alias=key \
            --ks-pass=pass:$GOOGLE_PLAY_KEYSTORE_PASSWORD
          unzip -p build/app/outputs/apk/release/MobileNebula.apks universal.apk > build/app/outputs/apk/release/MobileNebula.apk

      - name: Collect Android artifacts
        uses: actions/upload-artifact@v4
        with:
          name: MobileNebula.aab
          path: build/app/outputs/bundle/release/app-release.aab
          retention-days: 5

      - name: Publish to iOS TestFlight
        env:
          APP_STORE_CONNECT_API_KEY_KEY_ID: ${{ secrets.AC_API_KEY_ID }}
          APP_STORE_CONNECT_API_KEY_ISSUER_ID: ${{ secrets.AC_API_KEY_ISSUER_ID }}
        run: |
          cd ios
          fastlane release

      - name: Publish to Android internal track
        run: |
          cd android
          fastlane release

      - name: Rename app bundle
        run: |
          mv build/app/outputs/bundle/release/app-release.aab \
            build/app/outputs/bundle/release/MobileNebula.aab

      - name: Create GitHub Release
        id: create_release
        uses: softprops/action-gh-release@v2
        with:
          name: Release ${{ github.ref }}
          draft: true
          prerelease: false
          token: ${{ secrets.GITHUB_TOKEN }}
          files: |
            build/app/outputs/bundle/release/MobileNebula.aab
            build/app/outputs/apk/release/MobileNebula.apk
            ios/MobileNebula.ipa

      - name: Upload debug symbols to Sentry
        run: flutter packages pub run sentry_dart_plugin
        env:
          SENTRY_AUTH_TOKEN: ${{ secrets.SENTRY_AUTH_TOKEN }}
          SENTRY_ORG: ${{ secrets.SENTRY_ORG }}
          SENTRY_PROJECT: ${{ secrets.SENTRY_PROJECT }}