name: Release Android app

on:
  push:
    tags:
      - "v*"
  workflow_dispatch:
    inputs:
      tag:
        description: Existing release tag to build and update
        required: true
        type: string

permissions:
  contents: write

jobs:
  release:
    runs-on: ubuntu-latest
    env:
      RELEASE_TAG: ${{ github.event_name == 'workflow_dispatch' && inputs.tag || github.ref_name }}
    steps:
      - uses: actions/checkout@v5
        with:
          ref: ${{ env.RELEASE_TAG }}
      - uses: actions/setup-java@v5
        with:
          distribution: temurin
          java-version: "17"
      - uses: android-actions/setup-android@v3
      - uses: gradle/actions/setup-gradle@v5
      - name: Restore release signing key
        env:
          SIGNING_KEY_BASE64: ${{ secrets.ANDROID_SIGNING_KEY_BASE64 }}
        run: echo "$SIGNING_KEY_BASE64" | base64 --decode > "$RUNNER_TEMP/timeline-visualizer-release.jks"
      - name: Test and build signed GitHub APK and Play bundle
        env:
          CARTO_BASEMAP_API_KEY: ${{ secrets.CARTO_BASEMAP_API_KEY }}
          ANDROID_SIGNING_STORE_FILE: ${{ runner.temp }}/timeline-visualizer-release.jks
          ANDROID_SIGNING_STORE_PASSWORD: ${{ secrets.ANDROID_SIGNING_STORE_PASSWORD }}
          ANDROID_SIGNING_KEY_ALIAS: ${{ secrets.ANDROID_SIGNING_KEY_ALIAS }}
          ANDROID_SIGNING_KEY_PASSWORD: ${{ secrets.ANDROID_SIGNING_KEY_PASSWORD }}
        run: |
          test -n "$CARTO_BASEMAP_API_KEY"
          ./gradlew test lint assembleGithubRelease bundlePlayRelease --stacktrace
      - name: Verify signed GitHub APK
        run: |
          apk_path="app/build/outputs/apk/github/release/app-github-release.apk"
          build_tools_dir="$(find "$ANDROID_HOME/build-tools" -mindepth 1 -maxdepth 1 -type d | sort -V | tail -n 1)"
          test -n "$build_tools_dir"
          "$build_tools_dir/apksigner" verify --verbose --print-certs "$apk_path"

          package_line="$("$build_tools_dir/aapt" dump badging "$apk_path" | head -n 1)"
          package_name="$(sed -n "s/^package: name='\([^']*\)'.*/\1/p" <<< "$package_line")"
          version_code="$(sed -n "s/.*versionCode='\([^']*\)'.*/\1/p" <<< "$package_line")"
          version_name="$(sed -n "s/.*versionName='\([^']*\)'.*/\1/p" <<< "$package_line")"
          expected_version_code="$(sed -nE 's/^[[:space:]]*versionCode = ([0-9]+).*$/\1/p' app/build.gradle.kts | head -n 1)"
          expected_version_name="$(sed -nE 's/^[[:space:]]*versionName = "([^"]+)".*$/\1/p' app/build.gradle.kts | head -n 1)"

          test "$package_name" = "dev.mahlernim.timelinevisualizer"
          test "$version_code" = "$expected_version_code"
          test "$version_name" = "$expected_version_name"
          test "$version_name" = "${RELEASE_TAG#v}"
          sha256sum "$apk_path"
      - name: Save Play Console bundle
        uses: actions/upload-artifact@v4
        with:
          name: timeline-visualizer-play-${{ env.RELEASE_TAG }}
          path: app/build/outputs/bundle/playRelease/app-play-release.aab
          if-no-files-found: error
          retention-days: 30
      - name: Publish GitHub release
        env:
          GH_TOKEN: ${{ github.token }}
        run: |
          apk="TimelineVisualizer-${RELEASE_TAG}.apk"
          cp app/build/outputs/apk/github/release/app-github-release.apk "$apk"
          sha256sum "$apk" > "$apk.sha256"
          version_code="$(sed -nE 's/^[[:space:]]*versionCode = ([0-9]+).*$/\1/p' app/build.gradle.kts | head -n 1)"
          version_name="$(sed -nE 's/^[[:space:]]*versionName = "([^"]+)".*$/\1/p' app/build.gradle.kts | head -n 1)"
          jq -n \
            --argjson versionCode "$version_code" \
            --arg versionName "$version_name" \
            --arg releaseUrl "https://github.com/${GITHUB_REPOSITORY}/releases/tag/${RELEASE_TAG}" \
            '{versionCode: $versionCode, versionName: $versionName, releaseUrl: $releaseUrl}' \
            > update.json
          if gh release view "$RELEASE_TAG" >/dev/null 2>&1; then
            gh release upload "$RELEASE_TAG" "$apk" "$apk.sha256" update.json --clobber
          else
            gh release create "$RELEASE_TAG" \
              "$apk" \
              "$apk.sha256" \
              update.json \
              --title "Timeline Visualizer ${RELEASE_TAG#v}" \
              --notes-file "docs/release-notes-${RELEASE_TAG}.md" \
              --verify-tag
          fi