name: Build all and test

#on:
#  push:
#    branches:
#      - main
#  pull_request:
#on: workflow_dispatch

on:
  push:
    branches:
      - develop
  pull_request:

concurrency:
  group: build-${{ github.ref }}
  cancel-in-progress: true

jobs:
  test_and_apk:
    name: "Local tests and APKs"
    runs-on: ubuntu-latest

    permissions:
      contents: write
      pull-requests: write

    timeout-minutes: 60

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

      - name: Validate Gradle Wrapper
        uses: gradle/wrapper-validation-action@v3

      - name: Copy CI gradle.properties
        run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

      - name: Set up JDK 21
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 21

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4
        with:
          build-scan-publish: true
          build-scan-terms-of-use-url: "https://gradle.com/terms-of-service"
          build-scan-terms-of-use-agree: "yes"

      - name: Check build-logic
        run: ./gradlew check -p build-logic

      - name: Check spotless
        run: ./gradlew spotlessCheck --init-script gradle/init.gradle.kts --no-configuration-cache

      - name: Check Dependency Guard
        id: dependencyguard_verify
        continue-on-error: true
        run: ./gradlew dependencyGuard

      - name: Prevent updating Dependency Guard baselines if this is a fork
        id: checkfork_dependencyguard
        continue-on-error: false
        if: steps.dependencyguard_verify.outcome == 'failure' && github.event.pull_request.head.repo.full_name != github.repository
        run: |
          echo "::error::Dependency Guard failed, please update baselines with: ./gradlew dependencyGuardBaseline" && exit 1

        # Runs if previous job failed
      - name: Generate new Dependency Guard baselines if verification failed and it's a PR
        id: dependencyguard_baseline
        if: steps.dependencyguard_verify.outcome == 'failure' && github.event_name == 'pull_request'
        run: |
          ./gradlew dependencyGuardBaseline

      - name: Push new Dependency Guard baselines if available
        uses: stefanzweifel/git-auto-commit-action@v5
        if: steps.dependencyguard_baseline.outcome == 'success'
        with:
          file_pattern: '**/dependencies/*.txt'
          disable_globbing: true
          commit_message: "🤖 Updates baselines for Dependency Guard"

      - name: Run all local screenshot tests
        id: screenshotsverify
        continue-on-error: true
        run: ./gradlew validateFossReliantDebugScreenshotTest

      - name: Prevent pushing new screenshots if this is a fork
        id: checkfork_screenshots
        continue-on-error: false
        if: steps.screenshotsverify.outcome == 'failure' && github.event.pull_request.head.repo.full_name != github.repository
        run: |
          echo "::error::Screenshot tests failed, please create a PR in your fork first." && exit 1

      # Runs if previous job failed
      - name: Generate new screenshots if verification failed and it's a PR
        id: screenshotsrecord
        if: steps.screenshotsverify.outcome == 'failure' && github.event_name == 'pull_request'
        run: |
          ./gradlew updateFossReliantDebugScreenshotTest

      - name: Push new screenshots if available
        uses: stefanzweifel/git-auto-commit-action@v5
        if: steps.screenshotsrecord.outcome == 'success'
        with:
          file_pattern: '*/*.png'
          disable_globbing: true
          commit_message: "🤖 Updates screenshots"

      # Run local tests after screenshot tests to avoid wrong UP-TO-DATE. TODO: Ignore screenshots.
      - name: Run local tests and create report
        if: always()
        run: ./gradlew jvmTest
      # Replace task exclusions with `-Pandroidx.baselineprofile.skipgeneration` when
      # https://android-review.googlesource.com/c/platform/frameworks/support/+/2602790 landed in a
      # release build

      - name: Build all build type and flavor permutations
        run: ./gradlew assembleFossReliant :benchmarks:assembleFossReliant
          -x pixel6Api33FossReliantNonMinifiedReleaseAndroidTest
          -x pixel6Api33FossReliantNonMinifiedBenchmarkAndroidTest
          -x collectFossReliantNonMinifiedReleaseBaselineProfile
          -x collectFossReliantNonMinifiedBenchmarkBaselineProfile

      - name: Upload build outputs (APKs)
        uses: actions/upload-artifact@v4
        with:
          name: APKs
          path: '**/build/outputs/apk/**/*.apk'

      - name: Upload JVM local results (HTML)
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: local-test-results
          path: '**/build/reports/tests/jvmTest'

      - name: Check lint
        run: ./gradlew lintFossReliantRelease

      - name: Upload lint reports (HTML)
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: lint-reports
          path: '**/build/reports/lint-results-*.html'

      - name: Check badging
        run: ./gradlew checkFossReliantReleaseBadging

      - name: Generate coverage reports for Jvm
        run: ./gradlew koverXmlReportJvm; ./gradlew koverHtmlReportJvm   #koverHtmlReportJvm

      #      - name: Add coverage report to PR
      #        id: kover
      #        uses: mi-kas/kover-report@v1
      #        with:
      #          path: |
      #            ${{ github.workspace }}/modules/analytics/build/reports/kover/reportJvm.xml
      #
      #          title: Code Coverage
      #          update-comment: true
      #          min-coverage-overall: 40
      #          min-coverage-changed-files: 60
      #          token: ${{ secrets.GITHUB_TOKEN }}

      - name: Upload local coverage reports (XML + HTML) (only API 30)
        uses: actions/upload-artifact@v4
        with:
          name: coverage-reports
          if-no-files-found: error
          compression-level: 1
          overwrite: false
          path: '**/build/reports/kover/'

  androidTest:
    runs-on: ubuntu-latest
    timeout-minutes: 55
    strategy:
      matrix:
        api-level: [ 26, 30 ]

    steps:
      - name: Delete unnecessary tools 🔧
        uses: jlumbroso/free-disk-space@v1.3.1
        with:
          android: false # Don't remove Android tools
          tool-cache: true # Remove image tool cache - rm -rf "$AGENT_TOOLSDIRECTORY"
          dotnet: true # rm -rf /usr/share/dotnet
          haskell: true # rm -rf /opt/ghc...
          swap-storage: true # rm -f /mnt/swapfile (4GiB)
          docker-images: false # Takes 16s, enable if needed in the future
          large-packages: false # includes google-cloud-sdk and it's slow

      - name: Enable KVM group perms
        run: |
          echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
          sudo udevadm control --reload-rules
          sudo udevadm trigger --name-match=kvm
          ls /dev/kvm

      - name: Checkout
        uses: actions/checkout@v4

      - name: Copy CI gradle.properties
        run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

      - name: Set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'zulu'
          java-version: 17

      - name: Setup Gradle
        uses: gradle/actions/setup-gradle@v4
        with:
          build-scan-publish: true
          build-scan-terms-of-use-url: "https://gradle.com/terms-of-service"
          build-scan-terms-of-use-agree: "yes"

      - name: Build projects and run instrumentation tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          arch: x86_64
          disable-animations: true
          disk-size: 6000M
          heap-size: 600M
          script: ./gradlew connectedFossReliantDebugAndroidTest --daemon

      - name: Upload test reports
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: test-reports-${{ matrix.api-level }}
          path: '**/build/reports/androidTests'
