# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.

# This workflow uses perl regex. For better syntaxis understading see these docs:
# https://perldoc.perl.org/perlrequick#Search-and-replace
# https://perldoc.perl.org/perlre#Other-Modifiers

name: Create new release

run-name: Release v${{ inputs.version }}${{ inputs.release-track == 'beta' && '-Beta' || ''  }}

on:
  workflow_dispatch:
    inputs:
      version:
        description: "Version"
        required: true
        type: string
      release-notes:
        description: "Release notes"
        required: true
        type: string
      run-integration-tests:
        description: "Run integration tests"
        required: true
        type: boolean
        default: true
      release-track:
        description: "Release track"
        type: choice
        required: true
        options:
          - production
          - beta
        default: production

env:
  RELEASE_NOTES_ARTIFACT_NAME: release_notes_en_${{ inputs.version }}
  RELEASE_NOTES_FILE: release_notes_en_${{ inputs.version }}.md
  RELEASE_NOTES_PATH: "assets/release_notes"

jobs:
  run-integration-tests:
    name: Run integration tests
    if: ${{ inputs.run-integration-tests }}
    uses: ./.github/workflows/run_integration_tests.yml
    secrets: inherit

  generate-release-notes:
    name: Generate release notes
    needs: [run-integration-tests]
    if: ${{ always() && !failure() && !cancelled() }}
    runs-on: ubuntu-latest
    steps:
      - name: Generate release notes
        run: |
          echo ${{ inputs.release-notes }} > ${{ env.RELEASE_NOTES_FILE }}
          perl -i -pe 's/\s{1}(-{1})/\n$1/g' ${{ env.RELEASE_NOTES_FILE }}
      - name: Upload merged_native_libs.zip to artifacts
        uses: actions/upload-artifact@v3
        with:
          name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
          path: ${{ env.RELEASE_NOTES_FILE }}

  build-android:
    name: Build Android
    needs: [generate-release-notes]
    if: ${{ always() && !failure() && !cancelled() }}
    strategy:
      matrix:
        binary-type: [apk, appbundle]
    uses: ./.github/workflows/build_apk.yml
    secrets: inherit
    with:
      binary-type: ${{ matrix.binary-type }}
      flavor: prod
      stage-backend: false
      version: ${{ inputs.version }}

  build-ios:
    name: Build iOS
    needs: [generate-release-notes]
    if: ${{ always() && !failure() && !cancelled() }}
    uses: ./.github/workflows/build_ipa.yml
    secrets: inherit
    with:
      stage-backend: false
      version: ${{ inputs.version }}

  create-github-release:
    name: Create Github release
    needs: [build-android, build-ios]
    if: ${{ always() && !failure() && !cancelled() }}
    runs-on: ubuntu-latest
    permissions:
      contents: write
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive

      - name: Increment build number & replace version number
        run: bash ./.github/scripts/increment_build_number.sh ${{ github.event.inputs.version }}

      - name: Download release notes
        uses: actions/download-artifact@v3
        with:
          name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}
          path: ${{ env.RELEASE_NOTES_PATH }}

      - name: Commit changes
        run: |
          git config --local user.email "github-actions[bot]@users.noreply.github.com"
          git config --local user.name "github-actions[bot]"
          git add -A
          git commit -m "Release v${{ inputs.version }}"

      - name: Push to main
        uses: CasperWA/push-protected@v2
        with:
          token: ${{ secrets.PUSH_TO_MAIN_TOKEN }}
          branch: ${{ github.ref_name }}
          unprotect_reviews: true

      - name: Download apk
        uses: actions/download-artifact@v3
        with:
          name: m3_lightmeter_apk

      - name: Rename apk
        run: mv app-prod-release.apk m3_lightmeter.apk

      - uses: ncipollo/release-action@v1.12.0
        with:
          artifacts: "m3_lightmeter.apk"
          skipIfReleaseExists: true
          prerelease: ${{ inputs.release-track == 'beta' }}
          tag: "v${{ github.event.inputs.version }}${{ inputs.release-track == 'beta' && '-beta' || ''  }}"
          bodyFile: "${{ env.RELEASE_NOTES_PATH }}/${{ env.RELEASE_NOTES_FILE }}"

  create-google-play-release:
    name: Create Google Play release
    needs: [build-android, build-ios]
    if: ${{ always() && !failure() && !cancelled() }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive

      - name: Download app bundle
        uses: actions/download-artifact@v3
        with:
          name: m3_lightmeter_appbundle

      - name: Extract & zip merged_native_libs
        run: |
          unzip app-prod-release.aab
          (cd base/lib && zip -r "$OLDPWD/merged_native_libs.zip" .)

      - name: Download release notes
        uses: actions/download-artifact@v3
        with:
          name: ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}

      - name: Move release notes to a folder
        run: |
          mv ${{ env.RELEASE_NOTES_FILE }} whatsnew-en-US
          mkdir whatsnew
          mv whatsnew-en-US whatsnew

      # https://unix.stackexchange.com/questions/13466/can-grep-output-only-specified-groupings-that-match'
      # https://stackoverflow.com/questions/74353311/github-workflow-unable-to-process-file-command-env-successfully
      - name: Create Google Play release name
        id: release-name
        run: |
          RELEASE_NAME=$(echo "$(cat pubspec.yaml)" | sed -n -r "s/^version:\s{1}(.*)[+](.*)$/700\2 (\1)/p")
          echo "release_name=$RELEASE_NAME" >> $GITHUB_ENV

      - name: Create Google Play release
        id: create-google-play-release-step
        uses: r0adkll/upload-google-play@v1.1.1
        with:
          serviceAccountJsonPlainText: ${{ secrets.GH_ACTIONS_SERVICE_ACCOUNT_JSON }}
          packageName: com.vodemn.lightmeter
          releaseFiles: app-prod-release.aab
          releaseName: ${{ env.release_name }}
          track: ${{ inputs.release-track }}
          status: completed
          debugSymbols: merged_native_libs.zip
          whatsNewDirectory: whatsnew

  upload-to-app-store:
    name: Upload to App Store
    needs: [build-android, build-ios]
    if: ${{ always() && !failure() && !cancelled() }}
    runs-on: macos-13
    steps:
      - uses: actions/checkout@v3
        with:
          submodules: recursive

      - name: Download ipa
        uses: actions/download-artifact@v3
        with:
          name: m3_lightmeter_ipa

      - name: Upload app to TestFlight
        run: xcrun altool --upload-app -f lightmeter.ipa -t ios -u ${{ secrets.APP_STORE_USERNAME }} -p ${{ secrets.APP_STORE_PASSWORD }}

  cleanup:
    name: Cleanup
    if: ${{ always() }}
    needs:
      [create-github-release, create-google-play-release, upload-to-app-store]
    runs-on: ubuntu-latest
    steps:
      - name: Delete release artifacts
        uses: geekyeggo/delete-artifact@v2
        with:
          failOnError: false
          name: |
            m3_lightmeter_apk
            m3_lightmeter_appbundle
            m3_lightmeter_ipa
            ${{ env.RELEASE_NOTES_ARTIFACT_NAME }}