Android CI (Dev)

name: Android CI (Dev)

on:
  push:
    branches: [ version/* ]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - name: Checkout repository
        uses: actions/checkout@v3

      - name: Setup Ruby v3
        uses: ruby/setup-ruby@v1
        with:
          ruby-version: 3.0.2
          bundler-cache: true

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

      - name: Set Build Number
        env:
          APPCENTER_NUMBER: 1210
        run: |
          echo "BUILD_NUMBER_NEW=$(($APPCENTER_NUMBER+$GITHUB_RUN_NUMBER))" >> $GITHUB_ENV

      - name: Fastlane Build
        uses: maierj/fastlane-action@v3.0.0
        with:
          lane: 'app_build'
          options: '{ "app_name": "Unstoppable-Dev", "api_token": "${{secrets.API_TOKEN_DEV}}" }'
        env:
          BUILD_NUMBER: ${{env.BUILD_NUMBER_NEW}}


Build

name: Build
on: [pull_request, push]
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@v4

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

      - name: Build the app
        run: ./gradlew assembleCcc37c3

      - name: Unit Tests
        run: ./gradlew testDebugUnitTest :engelsystem:test testCcc37c3DebugUnitTest assembleCcc37c3Debug lintAnalyzeCcc37c3Debug

      - name: Publish unit-test results
        uses: EnricoMi/publish-unit-test-result-action@v2
        if: always()
        with:
          check_name: Test results (test)
          files: |
            build/test-results/**/*.xml
            */build/test-results/**/*.xml

  android_tests:
    runs-on: ubuntu-latest
    strategy:
      matrix:
        api-level: [ 26 ]
    steps:
      - name: Checkout
        uses: actions/checkout@v4

      - name: Enable KVM
        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

      - name: Gradle cache
        uses: gradle/actions/setup-gradle@v3

      - name: AVD cache
        uses: actions/cache@v4
        id: avd-cache
        with:
          path: |
            ~/.android/avd/*
            ~/.android/adb*
          key: avd-${{ matrix.api-level }}

      - name: Create AVD and generate snapshot for caching
        if: steps.avd-cache.outputs.cache-hit != 'true'
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          force-avd-creation: false
          emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: false
          script: echo "Generated AVD snapshot for caching."

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

      - name: Instrumentation Tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          force-avd-creation: false
          emulator-options: -no-snapshot-save -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: true
          script: ./gradlew :database:connectedAndroidTest

      - name: Publish unit-test results
        uses: EnricoMi/publish-unit-test-result-action/linux@v2
        if: always()
        with:
          check_name: Test results (androidTest), API level ${{ matrix.api-level }}
          files: |
            **/androidTest-results/**/*.xml


KMP library compilation check

---
name: KMP library compilation check
on:
  pull_request:
    branches:
      - master
      - develop
  push:
    branches:
      - master
      - develop

jobs:
  build-library:
    runs-on: macOS-latest
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Check
        run: ./local-check.sh
        shell: bash
      - name: Plugin local publish
        run: ./gradlew -p resources-generator publishToMavenLocal
        shell: bash
      - name: Library local publish
        run: ./gradlew publishToMavenLocal
        shell: bash
      - name: Upload artifacts
        uses: actions/upload-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-sample-android-mpp-app:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - macOS-latest
          - windows-latest
          - ubuntu-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - android-mpp-app
        run: cd samples/android-mpp-app && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-sample-auto-manifest:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - macOS-latest
          - windows-latest
          - ubuntu-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - auto-manifest
        run: cd samples/auto-manifest && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-sample-compose-jvm-app:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - macOS-latest
          - windows-latest
          - ubuntu-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - compose-jvm-app
        run: cd samples/compose-jvm-app && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-sample-resources-gallery:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - macOS-latest
          - windows-latest
          - ubuntu-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - resources-gallery
        run: cd samples/resources-gallery && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-sample-default-hierarchy-resources-gallery-mobile:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - macOS-latest
          - windows-latest
          - ubuntu-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - default-hierarchy-gallery-mobile
        run: cd samples/default-hierarchy-gallery-mobile && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-sample-ios-static-xcframework:
    runs-on: macOS-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - ios-static-xcframework
        run: cd samples/ios-static-xcframework && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-sample-ios-cocoapods-static-framework:
    runs-on: macOS-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - ios-cocoapods-static-framework
        run: cd samples/ios-cocoapods-static-framework && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-sample-kotlin-ios-app:
    runs-on: macOS-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - kotlin-ios-app
        run: cd samples/kotlin-ios-app && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-sample-compose-resources-gallery:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - macOS-latest
          - windows-latest
          - ubuntu-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - compose-resources-gallery
        run: cd samples/compose-resources-gallery && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-kotlin-2-sample:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - macOS-latest
          - windows-latest
          - ubuntu-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - kotlin-2-sample
        run: cd samples/kotlin-2-sample && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"
  check-cm-resources-sample:
    runs-on: ${{ matrix.os }}
    strategy:
      matrix:
        os:
          - macOS-latest
          - windows-latest
          - ubuntu-latest
    needs: build-library
    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Setup Gradle
        uses: gradle/gradle-build-action@v2
        with:
          cache-read-only: ${{ github.ref != 'refs/heads/master' && github.ref !=
            'refs/heads/develop' }}
      - name: Cache .konan
        uses: actions/cache@v2
        with:
          path: ~/.konan
          key: ${{ runner.os }}-konan-${{ hashFiles('**/*.gradle*', 'gradle/**/*') }}
          restore-keys: |
            ${{ runner.os }}-konan-
      - name: Download maven artifacts
        uses: actions/download-artifact@v3
        with:
          name: maven
          path: ~/.m2/repository/dev/icerock
      - name: Sample - cm-resources-sample
        run: cd samples/cm-resources-sample && ./local-check.sh
        shell: bash
      - name: Publish Test Report
        uses: mikepenz/action-junit-report@v2
        if: ${{ always() }}
        with:
          report_paths: "**/build/test-results/**/TEST-*.xml"
          github_token: ${{ secrets.GITHUB_TOKEN }}
      - name: Archive reports
        uses: actions/upload-artifact@v2
        if: ${{ always() }}
        with:
          name: code-coverage-report-${{ github.job }}
          path: "**/build/reports/**/*"


Create release

name: Create release

on:
  workflow_dispatch:
    inputs:
      version:
        description: 'Version'
        default: '0.1.0'
        required: true

jobs:
  publish:
    name: Publish library at mavenCentral
    runs-on: macOS-latest
    env:
      OSSRH_USER: ${{ secrets.OSSRH_USER }}
      OSSRH_KEY: ${{ secrets.OSSRH_KEY }}
      SIGNING_KEY_ID: ${{ secrets.SIGNING_KEYID }}
      SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
      SIGNING_KEY: ${{ secrets.GPG_KEY_CONTENTS }}

    steps:
      - uses: actions/checkout@v1
      - name: Set up JDK 17
        uses: actions/setup-java@v1
        with:
          java-version: 17
      - name: Prebuild library
        run: ./gradlew publishToMavenLocal --rerun-tasks
      - name: Publish library
        run: ./gradlew publish --no-parallel
      - name: Publish plugin
        run: ./gradlew -p resources-generator publishPlugins -Pgradle.publish.key=${{ secrets.GRADLE_PLUGIN_PORTAL_KEY }} -Pgradle.publish.secret=${{ secrets.GRADLE_PLUGIN_PORTAL_SECRET }}
  release:
    name: Create release
    needs: publish
    runs-on: ubuntu-latest
    steps:
      - name: Create Release
        id: create_release
        uses: actions/create-release@v1
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          commitish: ${{ github.ref }}
          tag_name: release/${{ github.event.inputs.version }}
          release_name: ${{ github.event.inputs.version }}
          body: "Will be filled later"
          draft: true


Deploy release

name: Deploy release

on:
  release:
    types: [ created ]

jobs:

  deploy-google-play:
    name: Google Play
    runs-on: ubuntu-latest
    timeout-minutes: 10
    environment: google-play
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
      - name: Decrypt keys
        env:
          ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
          SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
        run: |
          gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/google-services.json.gpg
          gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg
      - name: Upload apk to google play
        env:
          PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
          PLAY_KEY_ALIAS: ${{ secrets.PLAY_KEY_ALIAS }}
          PLAY_KEY_PASSWORD: ${{ secrets.PLAY_KEY_PASSWORD }}
          ANDROID_PUBLISHER_CREDENTIALS: ${{ secrets.ANDROID_PUBLISHER_CREDENTIALS }}
          ADMOB_PROJECT_ID: ${{ secrets.ADMOB_PROJECT_ID }}
          SINGLE_SUPPORT_AD_ID: ${{ secrets.SINGLE_SUPPORT_AD_ID }}
          DASHBOARD_TILE_AD_ID: ${{ secrets.DASHBOARD_TILE_AD_ID }}
          SET_BUILD_TIMESTAMP: ${{ secrets.SET_BUILD_TIMESTAMP }}
        run: ./gradlew publishPlayReleaseApps --stacktrace;

  deploy-app-gallery:
    name: AppGallery
    runs-on: ubuntu-latest
    timeout-minutes: 10
    environment: app-gallery
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
      - name: Decrypt keys
        env:
          ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }}
          SERVICES_ENCRYPT_KEY: ${{ secrets.SERVICES_ENCRYPT_KEY }}
        run: |
          gpg --yes --batch --passphrase=$SERVICES_ENCRYPT_KEY ./app/src/release/agconnect-services.json.gpg
          gpg --yes --batch --passphrase=$ENCRYPT_KEY ./app/upload-key.jks.gpg
      - name: Prepare credentials
        env:
          AGC_CREDENTIALS: ${{ secrets.AGC_CREDENTIALS }}
        run: echo $AGC_CREDENTIALS > ./app/src/release/agconnect-credentials.json
      - name: Build and publish HMS version
        env:
          PLAY_STORE_PASSWORD: ${{ secrets.PLAY_STORE_PASSWORD }}
          PLAY_KEY_ALIAS: ${{ secrets.PLAY_KEY_ALIAS }}
          PLAY_KEY_PASSWORD: ${{ secrets.PLAY_KEY_PASSWORD }}
          SET_BUILD_TIMESTAMP: ${{ secrets.SET_BUILD_TIMESTAMP }}
        run: ./gradlew bundleHmsRelease --stacktrace && ./gradlew publishHuaweiAppGalleryHmsRelease --stacktrace


Deploy DEV

name: Deploy DEV

on:
  push:
#    branches: [ develop ]
    branches: [ '!*' ]
  pull_request_target:
#    branches: [ develop ]
    branches: [ '!*' ]

  workflow_dispatch:

jobs:

  deploy-appcenter:
    name: App Center
    runs-on: ubuntu-latest
    timeout-minutes: 10
    environment: app-center
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
      - name: Set run number with offset
        env:
          BUILD_NUMBER_OFFSET: ${{ secrets.BUILD_NUMBER_OFFSET }}
        run: echo "RUN_NUMBER=$((GITHUB_RUN_NUMBER+BUILD_NUMBER_OFFSET))" >> $GITHUB_ENV
      - name: Prepare build configuration
        run: |
          sed -i -e "s#applicationIdSuffix \".dev\"#applicationIdSuffix \".${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/build.gradle
          sed -i -e "s#.dev\"#.${GITHUB_HEAD_REF//[-.\/]/_}\"#" app/google-services.json
          sed -i -e '/versionNameSuffix/d' app/build.gradle
      - name: Add signing config
        run: |
          cat >> app/build.gradle <<EOF
          android.signingConfigs.debug {
              storeFile file("bitrise.jks")
              storePassword System.getenv("BITRISE_KEYSTORE_PASSWORD")
              keyAlias System.getenv("BITRISE_KEY_ALIAS")
              keyPassword System.getenv("BITRISE_KEY_PASSWORD")
          }
          EOF
      - name: Decrypt keys
        env:
          BITRISE_ENCRYPT_KEY: ${{ secrets.BITRISE_ENCRYPT_KEY }}
        run: |
          gpg --yes --batch --passphrase=$BITRISE_ENCRYPT_KEY ./app/bitrise.jks.gpg
      - name: Bump version
        uses: chkfung/android-version-actions@v1.1
        with:
          gradlePath: app/build.gradle
          versionCode: ${{ env.RUN_NUMBER }}
          versionName: ${{ env.RUN_NUMBER }}-${{ github.head_ref }}
      - name: Build apk
        env:
          BITRISE_KEYSTORE_PASSWORD: ${{ secrets.BITRISE_KEYSTORE_PASSWORD }}
          BITRISE_KEY_ALIAS: ${{ secrets.BITRISE_KEY_ALIAS }}
          BITRISE_KEY_PASSWORD: ${{ secrets.BITRISE_KEY_PASSWORD }}
        run: ./gradlew assembleFdroidDebug --stacktrace
      - name: Upload apk to github artifacts
        uses: actions/upload-artifact@v3
        with:
          name: wulkanowyDEV-${{ env.RUN_NUMBER }}.apk
          path: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
      - name: Deploy to app center
        uses: wzieba/AppCenter-Github-Action@v1
        with:
          appName: wulkanowy/wulkanowy
          token: ${{ secrets.APP_CENTER_TOKEN }}
          group: Testers
          file: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk
          notifyTesters: true
          debug: true

  deploy-app-distribution:
    name: App Distribution
    runs-on: ubuntu-latest
    timeout-minutes: 10
    environment: app-distribution
    if: github.event_name != 'pull_request_target'
    steps:
      - uses: actions/checkout@v3
      - uses: actions/setup-java@v3
        with:
          distribution: 'zulu'
          java-version: 17
      - uses: actions/cache@v3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
      - name: Set run number with offset
        env:
          BUILD_NUMBER_OFFSET: ${{ secrets.BUILD_NUMBER_OFFSET }}
        run: echo "RUN_NUMBER=$((GITHUB_RUN_NUMBER+BUILD_NUMBER_OFFSET))" >> $GITHUB_ENV
      - name: Add signing config
        run: |
          cat >> app/build.gradle <<EOF
          android.signingConfigs.debug {
              storeFile file("bitrise.jks")
              storePassword System.getenv("BITRISE_KEYSTORE_PASSWORD")
              keyAlias System.getenv("BITRISE_KEY_ALIAS")
              keyPassword System.getenv("BITRISE_KEY_PASSWORD")
          }
          EOF
      - name: Decrypt keys
        env:
          BITRISE_ENCRYPT_KEY: ${{ secrets.BITRISE_ENCRYPT_KEY }}
          BITRISE_SERVICES_ENCRYPT_KEY: ${{ secrets.BITRISE_SERVICES_ENCRYPT_KEY }}
        run: |
          gpg --yes --batch --passphrase=$BITRISE_SERVICES_ENCRYPT_KEY ./app/src/debug/google-services.json.gpg
          gpg --yes --batch --passphrase=$BITRISE_ENCRYPT_KEY ./app/bitrise.jks.gpg
      - name: Bump version
        uses: chkfung/android-version-actions@v1.1
        with:
          gradlePath: app/build.gradle
          versionCode: ${{ env.RUN_NUMBER }}
          versionName: ${{ env.RUN_NUMBER }}
      - name: Build apk
        env:
          BITRISE_KEYSTORE_PASSWORD: ${{ secrets.BITRISE_KEYSTORE_PASSWORD }}
          BITRISE_KEY_ALIAS: ${{ secrets.BITRISE_KEY_ALIAS }}
          BITRISE_KEY_PASSWORD: ${{ secrets.BITRISE_KEY_PASSWORD }}
        run: ./gradlew assemblePlayDebug --stacktrace
      - name: Upload apk to github artifacts
        uses: actions/upload-artifact@v3
        with:
          name: wulkanowyDEV-${{ env.RUN_NUMBER }}-dev.apk
          path: app/build/outputs/apk/play/debug/app-play-debug.apk
      - name: Deploy to app distribution
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
          appId: ${{ secrets.FIREBASE_APP_ID }}
          token: ${{ secrets.FIREBASE_TOKEN }}
          groups: discord
          file: app/build/outputs/apk/play/debug/app-play-debug.apk


Tests

name: Tests

on:
  push:
    branches:
      - master
      - develop
      - 'hotfix/**'
    tags: [ '*' ]
  pull_request:

jobs:

  tests-fdroid:
      name: F-Droid
      runs-on: ubuntu-latest
      timeout-minutes: 10
      steps:
        - uses: fkirc/skip-duplicate-actions@master
        - uses: actions/checkout@v3
        - uses: gradle/wrapper-validation-action@v1
        - uses: actions/setup-java@v3
          with:
            distribution: 'zulu'
            java-version: 17
        - uses: actions/cache@v3
          with:
            path: |
              ~/.gradle/caches
              ~/.gradle/wrapper
            key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
        - name: Unit tests
          run: |
            ./gradlew testFdroidDebugUnitTest --stacktrace
            ./gradlew jacocoTestReport --stacktrace
        - uses: codecov/codecov-action@v3
          with:
              flags: unit

  tests-play:
      name: Play
      runs-on: ubuntu-latest
      timeout-minutes: 10
      steps:
        - uses: fkirc/skip-duplicate-actions@master
        - uses: actions/checkout@v3
        - uses: gradle/wrapper-validation-action@v1
        - uses: actions/setup-java@v3
          with:
            distribution: 'zulu'
            java-version: 17
        - uses: actions/cache@v3
          with:
            path: |
              ~/.gradle/caches
              ~/.gradle/wrapper
            key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
        - name: Unit tests
          run: |
            ./gradlew testPlayDebugUnitTest --stacktrace
            ./gradlew jacocoTestReport --stacktrace
        - uses: codecov/codecov-action@v3
          with:
              flags: unit

  tests-hms:
      name: HMS
      runs-on: ubuntu-latest
      timeout-minutes: 10
      steps:
        - uses: fkirc/skip-duplicate-actions@master
        - uses: actions/checkout@v3
        - uses: gradle/wrapper-validation-action@v1
        - uses: actions/setup-java@v3
          with:
            distribution: 'zulu'
            java-version: 17
        - uses: actions/cache@v3
          with:
            path: |
              ~/.gradle/caches
              ~/.gradle/wrapper
            key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}
        - name: Unit tests
          run: |
            ./gradlew testHmsDebugUnitTest --stacktrace
            ./gradlew jacocoTestReport --stacktrace
        - uses: codecov/codecov-action@v3
          with:
              flags: unit


Android CI

name: Android CI

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]

jobs:
  build:

    runs-on: ubuntu-latest

    steps:
    - name: Checkout
      uses: actions/checkout@v4
    - name: set up JDK
      uses: actions/setup-java@v3
      with:
        java-version: '17'
        distribution: 'temurin'
        cache: gradle

    - name: Grant execute permission for gradlew
      run: chmod +x gradlew
    - name: Build with Gradle
      if: success()
      run: ./gradlew assembleWebsiteFullDebug --info --warning-mode all


MobSF

# 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.

name: MobSF

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  schedule:
    - cron: '17 23 * * 2'

permissions:
  contents: read

jobs:
  mobile-security:
    permissions:
      contents: read # for actions/checkout to fetch code
      security-events: write # for github/codeql-action/upload-sarif to upload SARIF results
      actions: read # only required for a private repository by github/codeql-action/upload-sarif to get the Action run status
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3

      - name: Setup python
        uses: actions/setup-python@v3
        with:
          python-version: 3.8

      - name: Run mobsfscan
        uses: MobSF/mobsfscan@a60d10a83af68e23e0b30611c6515da604f06f65
        with:
          args: . --sarif --output results.sarif || true

      - name: Upload mobsfscan report
        uses: github/codeql-action/upload-sarif@v2
        with:
          sarif_file: results.sarif


Monthly alpha

name: Monthly alpha

on:
  workflow_dispatch: # to be able to run it manually
  schedule:
    - cron: '53 21 27 * *' # on 27 every month

jobs:
  evaluateChanges:
    name: Evaluate changes
    runs-on: ubuntu-latest
    outputs:
      SHOULD_BUILD: ${{ steps.check.outputs.shouldBuild }}
    steps:
      - name: Check
        id: check
        run: |
          echo shouldBuild=true >> $GITHUB_OUTPUT

  build:
    name: Monthlies
    runs-on: ubuntu-latest
    needs: evaluateChanges
    if: needs.evaluateChanges.outputs.SHOULD_BUILD == 'true'
    env:
      TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHANNEL_ID }}
      TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
      SCHEDULED_BUILD_VARIANT: "assembleWebsiteFullAlpha"
    steps:
      - name: Checkout
        uses: actions/checkout@v4
        with:
          fetch-depth: 1

      - name: JDK17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      - name: Alpha keystore
        run: |
          echo "${{ secrets.ALPHA_KS_ASC }}" > alphaKeystore.jks.asc
          gpg -d --passphrase "${{ secrets.ALPHA_KS_PASSPHRASE }}" --batch alphaKeystore.jks.asc > app/rdnsAlpha.jks
          wc -wcl alphaKeystore.jks.asc app/rdnsAlpha.jks

      - name: Build & notify
        if: env.TELEGRAM_CHAT_ID && env.SCHEDULED_BUILD_VARIANT && env.TELEGRAM_TOKEN
        run: |
          ./gradlew ${SCHEDULED_BUILD_VARIANT} --info --warning-mode all
        env:
          ALPHA_KS_ALIAS: ${{ vars.ALPHA_KS_ALIAS }}
          ALPHA_KS_FILE: ${{ vars.ALPHA_KS_FILE }}
          ALPHA_KS_STORE_PASSPHRASE: ${{ secrets.ALPHA_KS_STORE_PASSPHRASE }}
          ALPHA_KS_PASSPHRASE: ${{ secrets.ALPHA_KS_PASSPHRASE }}
          VERSION_CODE: ${{ github.run_number }}
          # version-code: archive.is/y8uCB

      - name: Grab APK
        run: |
          apk_path="$(find . -type f -iname '*.apk' | head -n1)"
          echo $apk_path
          echo "APKFILE=${apk_path}" >> $GITHUB_ENV

      # github.com/actions/upload-artifact
      - name: Artifact
        uses: actions/upload-artifact@v3
        if: success()
        with:
          name: rdns-${{ github.sha }}
          path: ${{ env.APKFILE }}
          if-no-files-found: error

      # github.com/softprops/action-gh-release
      - name: Release
        uses: softprops/action-gh-release@v1
        with:
          prerelease: true
          files: |
            ${{ env. APKFILE }}

      - name: Telegram
        run: |
          # exit okay on errors
          set +e
          apk_path="$(find . -type f -iname '*.apk' | head -n1)"
          echo $apk_path
          echo "APKFILE=${apk_path}" >> $GITHUB_ENV
          curl https://api.telegram.org/bot$TELEGRAM_TOKEN/sendDocument \
            -F chat_id="$TELEGRAM_CHAT_ID" \
            -F "caption=Size: $(ls -l --block-size=K "$apk_path" | awk '{ print $5 }')" \
            -F parse_mode=HTML \
            -F document=@"$apk_path"


Static Analyser

name: Static Analyser
on:
  push:
    branches: [ "main" ]

jobs:
  detekt:
    name: detekt
    runs-on: ubuntu-latest

    steps:
      - name: "checkout"
        uses: actions/checkout@v3

      - name: "run"
        uses: natiginfo/action-detekt-all@1.23.6
        # from: https://github.com/natiginfo/action-detekt-all
        with:
          args:  --config .github/detekt-config.yml


supply-chain scorecard

# 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.

name: supply-chain scorecard
on:
  # For Branch-Protection check. Only the default branch is supported. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#branch-protection
  branch_protection_rule:
  # To guarantee Maintained check is occasionally updated. See
  # https://github.com/ossf/scorecard/blob/main/docs/checks.md#maintained
  schedule:
    - cron: '52 12 * * 3'
  push:
    branches: [ "main" ]

# Declare default permissions as read only.
permissions: read-all

jobs:
  analysis:
    name: Scorecard analysis
    runs-on: ubuntu-latest
    permissions:
      # Needed to upload the results to code-scanning dashboard.
      security-events: write
      # Needed to publish results and get a badge (see publish_results below).
      id-token: write
      # Uncomment the permissions below if installing in a private repository.
      # contents: read
      # actions: read

    steps:
      - name: "Checkout code"
        uses: actions/checkout@v4
        with:
          persist-credentials: false

      - name: "Run analysis"
        uses: ossf/scorecard-action@v2.3.1
        with:
          results_file: results.sarif
          results_format: sarif
          # (Optional) "write" PAT token. Uncomment the `repo_token` line below if:
          # - you want to enable the Branch-Protection check on a *public* repository, or
          # - you are installing Scorecard on a *private* repository
          # To create the PAT, follow the steps in https://github.com/ossf/scorecard-action#authentication-with-pat.
          # repo_token: ${{ secrets.SCORECARD_TOKEN }}

          # Public repositories:
          #   - Publish results to OpenSSF REST API for easy access by consumers
          #   - Allows the repository to include the Scorecard badge.
          #   - See https://github.com/ossf/scorecard-action#publishing-results.
          # For private repositories:
          #   - `publish_results` will always be set to `false`, regardless
          #     of the value entered here.
          publish_results: true

      # Upload the results as artifacts (optional). Commenting out will disable uploads of run results in SARIF
      # format to the repository Actions tab.
      - name: "Upload artifact"
        uses: actions/upload-artifact@3cea5372237819ed00197afe530f5a7ea3e805c8 # v3.1.0
        with:
          name: SARIF file
          path: results.sarif
          retention-days: 21

      # Upload the results to GitHub's code scanning dashboard.
      - name: "Upload to code-scanning"
        uses: github/codeql-action/upload-sarif@17573ee1cc1b9d061760f3a006fc4aac4f944fd5 # v2.2.4
        with:
          sarif_file: results.sarif


⚛ Native Sym

name: ⚛ Native Sym

on:
  push:
    tags:
      - "v*"
  # docs.github.com/en/actions/managing-workflow-runs/manually-running-a-workflow
  # docs.github.com/en/actions/learn-github-actions/events-that-trigger-workflows#workflow_dispatch
  # docs.github.com/en/actions/learn-github-actions/workflow-syntax-for-github-actions#onworkflow_dispatchinputs
  workflow_dispatch:
    # github.blog/changelog/2020-07-06-github-actions-manual-triggers-with-workflow_dispatch/
    # docs.github.com/en/actions/creating-actions/metadata-syntax-for-github-actions#inputs
    inputs:
      commit:
        description: 'commit sha'
        default: ''
        required: true

jobs:
  # from: github.com/Menci/acme/blob/5a12d53/action.yml
  Symbols:
    name: 🔥 Firebase
    runs-on: ubuntu-latest

    env:
      COMMIT: ${{ github.event.inputs.commit || github.sha }}
      GIT_REF: ${{ github.event.inputs.git-ref || github.ref }}

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

      - name: 🎱 Setup node
        uses: actions/setup-node@v4
        with:
          node-version: 22.x

      - name: 🚨 Release?
        # docs.github.com/en/actions/learn-github-actions/contexts#github-context
        if: ${{ github.event_name != 'workflow_dispatch' && github.ref_type == 'tag' }}
        run: |
          # playImplementation 'com.github.celzero:firestack:ee0a5ac71f:debug@aar' -> firestack:ee0a5ac71f -> ee0a5ac71f
          LOI=$(grep -m1 app/build.gradle "playImplementation 'com.github.celzero:firestack")
          HASH=$(echo $LOI | grep -o "firestack:[^@]*" | cut -d':' -f2)
          echo "COMMIT=${HASH}" >> $GITHUB_ENV
          echo "https://github.com/celzero/firestack/tree/${HASH}"
          echo "::notice::Releasing SYMs for ${GIT_REF} @ ${LOI}"
        shell: bash

      - name: 🎨 Deps
        run: npm install -g firebase-tools

      - name: 🚀 Firestack AAR
        run: |
          # wget opts: superuser.com/a/689340
          wgetopts="--tries=3 --retry-on-http-error=404 --waitretry=3 --no-dns-cache"
          wget $wgetopts "https://jitpack.io/com/github/celzero/firestack/${COMMIT:0:10}/firestack-${COMMIT:0:10}-debug.aar" -O "firestack.aar"
          ls -ltr .
          unzip ./firestack.aar
          firebase crashlytics:symbols:upload --app=${{ secrets.FIREBASE_APP_ID_ANDROID }} --debug jni/
        shell: bash
        env:
          COMMIT: ${{ env.COMMIT }}
          FIREBASE_TOKEN: ${{ secrets.FIREBASE_TOKEN }}


Notify

name: Notify

permissions:
  contents: read

on:
  push:
    branches:
      - main

jobs:
  notify:
    name: Notify via Telegram
    runs-on: ubuntu-latest
    env:
      TELEGRAM_CHAT_ID: ${{ secrets.TELEGRAM_CHANNEL_ID }}
      TELEGRAM_TOKEN: ${{ secrets.TELEGRAM_TOKEN }}
    steps:
      - name: Notify
        if: env.TELEGRAM_CHAT_ID && env.TELEGRAM_TOKEN
        env:
          COMMITS: ${{ toJson(github.event.commits) }}
          TEMPLATE: '.[] | "\(.id[:8]) • \(.author.username | @html)

          \(.message | gsub("(?[<>&\"])"; .a|@html))

          "'
        run: |
          (
            printenv COMMITS | jq -r "$TEMPLATE"
            printf '@RethinkDNS_Channel'
          ) | \
          jq -R --slurp '{
            text: .,
            disable_web_page_preview: true,
            chat_id: "$TELEGRAM_CHAT_ID",
            parse_mode: "HTML"
          }' | \
          curl -X POST https://api.telegram.org/bot$TELEGRAM_TOKEN/sendMessage \
            -H 'Content-Type: application/json' \
            --data-binary @-


release-build

name: release-build

on:
  push:
    tags:
    - 'v*'

jobs:
  release:

    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
        with:
          ref: ${{ github.ref }}
          fetch-depth: 0
      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
      - name: Build release
        uses: burrunan/gradle-cache-action@v1
        with:
          job-id: jdk17
          arguments: bootJar bootWar
          properties: vaadin.productionMode=true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Extract version
        id: version
        run: echo ::set-output name=value::$(git describe --abbrev=0 | sed -e "s/^v//")
      - name: Create Release
        id: create_release
        uses: actions/create-release@v1.1.4
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          tag_name: ${{ github.ref }}
          release_name: ${{ github.ref }}
          draft: false
      - name: Upload Release War
        id: upload-release-asset-1
        uses: actions/upload-release-asset@v1.0.2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./acrarium/build/libs/acrarium-${{ steps.version.outputs.value }}.war
          asset_name: acrarium-${{ steps.version.outputs.value }}.war
          asset_content_type: application/zip
      - name: Upload Release Jar
        id: upload-release-asset-2
        uses: actions/upload-release-asset@v1.0.2
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
        with:
          upload_url: ${{ steps.create_release.outputs.upload_url }}
          asset_path: ./acrarium/build/libs/acrarium-${{ steps.version.outputs.value }}.jar
          asset_name: acrarium-${{ steps.version.outputs.value }}.jar
          asset_content_type: application/zip


release-docker

name: release-docker

on:
  push:
    tags:
      - 'v*'

jobs:
  release:
    runs-on: ubuntu-latest
    steps:
      - name: Check out Project
        uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
        with:
          ref: ${{ github.ref }}
          fetch-depth: 0
      - name: Set up Java
        uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: '17'
      - name: Set up QEMU
        uses: docker/setup-qemu-action@v3
      - name: Set up Docker Buildx
        uses: docker/setup-buildx-action@v3
      - name: Login to Docker Hub
        uses: docker/login-action@v3.1.0
        with:
          username: ${{ secrets.DOCKER_USERNAME }}
          password: ${{ secrets.DOCKER_PASSWORD }}
      - name: Login to GitHub Container Registry
        uses: docker/login-action@v3.1.0
        with:
          registry: ghcr.io
          username: ${{ github.repository_owner }}
          password: ${{ secrets.GITHUB_TOKEN }}
      - name: Build release
        uses: burrunan/gradle-cache-action@v1
        with:
          job-id: jdk17
          arguments: bootJar
          properties: vaadin.productionMode=true
      - name: Get docker tags
        id: tags
        run: |
          delimiter="$(openssl rand -hex 8)"
          {
            echo "TAGS<<${delimiter}"
            ./listDockerTags.sh
            echo "${delimiter}"
          } >> $GITHUB_OUTPUT
      - name: Build and push docker images
        uses: docker/build-push-action@v5
        with:
          context: "./acrarium"
          push: true
          tags: ${{ steps.tags.outputs.TAGS }}
          platforms: |
            linux/amd64
            linux/arm64/v8


tests

name: tests

on: [push]

jobs:
  tests:

    runs-on: ubuntu-latest
    strategy:
      fail-fast: false
      matrix:
        java: ['17']
    steps:
      - uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4.1.7
        with:
          fetch-depth: 0
      - uses: actions/setup-java@v4
        with:
          distribution: 'temurin'
          java-version: ${{ matrix.java }}
      - name: Tests on Java ${{ matrix.java }}
        uses: burrunan/gradle-cache-action@v1
        with:
          job-id: jdk${{ matrix.java }}
          arguments: test
          properties: vaadinProKey=${{ secrets.VAADIN_PROKEY }}
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
      - name: Upload Test Results
        if: always()
        uses: actions/upload-artifact@v4
        with:
          name: Unit Test Results (Java ${{ matrix.java }})
          path: acrarium/build/test-results/**/*.xml

  publish-test-results:
    name: "Publish Unit Tests Results"
    needs: tests
    runs-on: ubuntu-latest
    # the build-and-test job might be skipped, we don't need to run this job then
    if: success() || failure()

    steps:
      - name: Download Artifacts
        uses: actions/download-artifact@v4
        with:
          path: artifacts
      - name: Publish Unit Test Results
        uses: EnricoMi/publish-unit-test-result-action@v2
        with:
          files: artifacts/**/*.xml


Android CI

name: Android CI

on:
  push:
    branches:
      - main
  pull_request:
    branches:
      - main

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: "temurin"
          java-version: 17

      - name: Make gradlew executable
        run: chmod +x gradlew

      - name: Build
        run: ./gradlew assembleDebug

      - name: Run unit tests
        run: ./gradlew testDebugUnitTest


Update Contributors

name: Update Contributors

on:
  schedule:
    # Run every sunday at midnight
    - cron: '0 0 * * 0'
  workflow_dispatch:

jobs:
  update_contributors:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout code
        uses: actions/checkout@v3

      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.x'

      - name: Install dependencies
        run: |
          python -m pip install --upgrade pip
          pip install requests

      - name: Run script
        run: python scripts/update_contributors.py

      - name: Check for changes
        id: git-diff
        run: echo "::set-output name=changes::$(git diff --exit-code)"

      - name: Create Pull Request
        if: steps.git-diff.outputs.changes != ''
        uses: peter-evans/create-pull-request@v3
        with:
          title: "Update contributors"
          body: "This PR updates the list of contributors in the Licenses.kt file."
          branch: "update-contributors"


Fix String Translations

name: Fix String Translations

on:
  schedule:
    # Run every day at midnight
    - cron: '0 0 * * *'
  workflow_dispatch:

jobs:
  fix_translations:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.x'

      - name: Run script
        run: python scripts/string-fixer.py

      - name: Check for changes
        id: git-diff
        run: echo "::set-output name=changes::$(git diff --exit-code)"

      - name: Create Pull Request
        if: steps.git-diff.outputs.changes != ''
        uses: peter-evans/create-pull-request@v3
        with:
          title: "Fix translations"
          body: "This PR fixes malformed string translations."
          branch: "fix-string-translations"


Update Guide Translations

name: Update Guide Translations

on:
  schedule:
    # Run every sunday at midnight
    - cron: '0 0 * * 0'
  workflow_dispatch:

jobs:
  update_guides:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Set up Python
        uses: actions/setup-python@v2
        with:
          python-version: '3.x'

      - name: Run script
        run: python scripts/update-guide.py

      - name: Check for changes
        id: git-diff
        run: echo "::set-output name=changes::$(git diff --exit-code)"

      - name: Create Pull Request
        if: steps.git-diff.outputs.changes != ''
        uses: peter-evans/create-pull-request@v3
        with:
          title: "Update guides"
          body: "This PR updates the user guide translations."
          branch: "update-user-guide-translations"


Nightly

name: Nightly

on:
  schedule:
    - cron: "0 0 * * *"
  workflow_dispatch:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Generate changelog
        run: |
          echo "## Changelog" >> $GITHUB_STEP_SUMMARY
          sh ./scripts/list-nightly-commits.sh >> $GITHUB_STEP_SUMMARY

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: "temurin"
          java-version: 17

      - name: Make gradlew executable
        run: chmod +x ./gradlew

      - name: Build APK
        run: |
          echo ${NIGHTLY_STORE_FILE} | base64 -d > KEY_NIGHTLY.jks
          NIGHTLY_KEY_ALIAS=$(echo -n $NIGHTLY_KEY_ALIAS | base64 -d)
          ./gradlew assembleNightly -Dnightly_store_file=../KEY_NIGHTLY.jks -Dnightly_store_password="${NIGHTLY_STORE_PASSWORD}" -Dnightly_key_alias="${NIGHTLY_KEY_ALIAS}" -Dnightly_key_password="${NIGHTLY_STORE_PASSWORD}"
        env:
          NIGHTLY_STORE_PASSWORD: ${{ secrets.NIGHTLY_STORE_PASSWORD }}
          NIGHTLY_KEY_ALIAS: ${{ secrets.NIGHTLY_KEY_ALIAS }}
          NIGHTLY_STORE_FILE: ${{ secrets.NIGHTLY_STORE_FILE }}

      - name: Upload APK
        uses: actions/upload-artifact@v3
        with:
          name: Trail-Sense-Nightly.apk
          path: ./app/build/outputs/apk/nightly/*.apk
          retention-days: 7


Release Upload

name: Release Upload

on:
  release:
    types: [published]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v3
        with:
          ref: ${{ github.event.release.tag_name }}

      - name: Setup Java
        uses: actions/setup-java@v4
        with:
          distribution: "temurin"
          java-version: 17

      - name: Make gradlew executable
        run: chmod +x ./gradlew

      - name: Build APK
        run: |
          echo ${DEV_STORE_FILE} | base64 -d > KEY_DEV.jks
          DEV_KEY_ALIAS=$(echo -n $DEV_KEY_ALIAS | base64 -d)
          ./gradlew assembleDev -Ddev_store_file=../KEY_DEV.jks -Ddev_store_password="${DEV_STORE_PASSWORD}" -Ddev_key_alias="${DEV_KEY_ALIAS}" -Ddev_key_password="${DEV_STORE_PASSWORD}"
        env:
          DEV_STORE_PASSWORD: ${{ secrets.DEV_STORE_PASSWORD }}
          DEV_KEY_ALIAS: ${{ secrets.DEV_KEY_ALIAS }}
          DEV_STORE_FILE: ${{ secrets.DEV_STORE_FILE }}

      - name: Upload to release
        uses: Shopify/upload-to-release@v1.0.1
        with:
          name: Trail-Sense-${{ github.event.release.tag_name }}-dev.apk
          path: ./app/build/outputs/apk/dev/app-dev.apk
          repo-token: ${{ secrets.GITHUB_TOKEN }}


Website

name: Website

on:
  push:
    branches:
      - "main"
    paths:
      - "site/**"
  workflow_dispatch:

# Sets permissions of the GITHUB_TOKEN to allow deployment to GitHub Pages
permissions:
  contents: read
  pages: write
  id-token: write

# Allow only one concurrent deployment, skipping runs queued between the run in-progress and latest queued.
# However, do NOT cancel in-progress runs as we want to allow these production deployments to complete.
concurrency:
  group: "pages"
  cancel-in-progress: false

jobs:
  deploy:
    environment:
      name: github-pages
      url: ${{ steps.deployment.outputs.page_url }}
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v3
        with:
          fetch-depth: 0

      - name: Setup Pages
        uses: actions/configure-pages@v3

      - name: Upload artifact
        uses: actions/upload-pages-artifact@v2
        with:
          path: "site"

      - name: Deploy to GitHub Pages
        id: deployment
        uses: actions/deploy-pages@v2


Notify PR events

name: Notify PR events

on:
  pull_request:

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2
      - name: Notify to Telegrem
        uses: appleboy/telegram-action@master
        with:
          to: ${{secrets.TELEGRAM_TO}}
          token: ${{secrets.TELEGRAM_TOKEN}}
          disable_web_page_preview: true
          message: |
            ${{ github.event.pull_request.html_url }}

            Title: ${{github.event.pull_request.title}}
            Author: ${{github.actor}}


check

name: check
on:
  push:
    branches:
      - master
  pull_request:
    branches:
      - master
jobs:
  gradle:
    strategy:
      matrix:
        os: [ubuntu-latest, macos-latest]
        java: [17]
    runs-on: ${{ matrix.os }}
    env:
      NO_FS_ROOTS_ACCESS_CHECK: true
    steps:
    - uses: actions/checkout@v2
      with:
        path: intellij-arend
    - uses: actions/checkout@v2
      with:
        repository: JetBrains/Arend
        path: Arend
    - uses: actions/setup-java@v1
      with:
        java-version: ${{ matrix.java }}
    - uses: eskatos/gradle-command-action@v1
      with:
        wrapper-cache-enabled: false
        cache-disabled: true
        build-root-directory: intellij-arend
        wrapper-directory: intellij-arend
        arguments: clean test --info --no-daemon --stacktrace
    - uses: eskatos/gradle-command-action@v1
      # Normally, macOS runs faster than the other two
      if: matrix.os == 'macOS-latest' && matrix.java == '17'
      with:
        wrapper-cache-enabled: false
        cache-disabled: true
        build-root-directory: intellij-arend
        wrapper-directory: intellij-arend
        arguments: assemble --info --no-daemon --stacktrace
    - uses: actions/upload-artifact@master
      if: matrix.os == 'macOS-latest' && matrix.java == '17'
      with:
        name: Plugin
        path: intellij-arend/build/distributions


build

name: build

on:
  push:
    branches:
      - "**"
  pull_request:

jobs:
  build:
    name: Build
    runs-on: "ubuntu-latest"

    steps:
      - uses: actions/checkout@v2

      - uses: actions/setup-java@v2
        with:
          distribution: temurin
          java-version: 8

      - uses: actions/cache@v2
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      - name: Build
        run: ./gradlew --no-daemon setupCiWorkspace build

      - name: Get Short SHA
        id: sha
        run: echo "::set-output name=sha_short::$(git rev-parse --short HEAD)"

      - name: Publish Artifacts
        uses: actions/upload-artifact@v2
        with:
          name: ChatTriggers-artifacts-${{ steps.sha.outputs.sha_short }}
          path: |
            build/libs/*


javadocs

name: javadocs

on:
  push:
    tags:
      - '**'
  workflow_dispatch:

jobs:
  build:
    name: Deploy Javadocs
    runs-on: "ubuntu-latest"
    if:
      ${{ github.repository == 'ChatTriggers/ChatTriggers' }}

    steps:
      - uses: actions/checkout@v2

      - uses: actions/setup-java@v2
        with:
          distribution: temurin
          java-version: 8

      - uses: actions/cache@v2
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }}
          restore-keys: |
            ${{ runner.os }}-gradle-

      - name: Build Javadocs
        run: ./gradlew --no-daemon setupCiWorkspace userdocs

      - name: Publish Javadocs
        uses: appleboy/scp-action@master
        with:
          host: ${{ secrets.REMOTE_HOST }}
          username: ${{ secrets.ACTIONS_DEPLOYER_USERNAME }}
          key: ${{ secrets.ACTIONS_DEPLOYER_SSH_KEY }}
          passphrase: ${{ secrets.ACTIONS_DEPLOYER_PASSPHRASE }}
          source: build/javadoc/
          target: /srv/www/static/home/javadocs
          strip_components: 2
          rm: true

      - name: Set File Permissions
        uses: appleboy/ssh-action@master
        with:
          host: ${{ secrets.REMOTE_HOST }}
          username: ${{ secrets.ACTIONS_DEPLOYER_USERNAME }}
          key: ${{ secrets.ACTIONS_DEPLOYER_SSH_KEY }}
          passphrase: ${{ secrets.ACTIONS_DEPLOYER_PASSPHRASE }}
          script: chmod -R g+w /srv/www/static/home/javadocs


Android tests

name: Android tests
on: pull_request
env:
  GRADLE_OPTS: "-Dorg.gradle.jvmargs=\"-Xmx8G -XX:MaxMetaspaceSize=512m -Dorg.gradle.daemon=false -Dkotlin.incremental=false\" -Dorg.gradle.daemon=false -Dkotlin.incremental=false -Dkotlin.daemon.jvm.options=-Xmx8G,-XX:MaxMetaspaceSize=512m,-Dorg.gradle.daemon=false,-Dkotlin.incremental=false"
  JAVA_OPTS: "-Xmx8G -XX:MaxMetaspaceSize=512m -Dorg.gradle.daemon=false -Dkotlin.incremental=false"

jobs:
  test:
    runs-on: ubuntu-latest
    steps:
      - name: checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive

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

      - name: run Android unit tests
        run: ./gradlew testDebugUnitTest koverHtmlReport koverXmlReport
      - name: add coverage report to PR
        id: kover
        uses: mi-kas/kover-report@v1
        # this action fails if there is no report, unlike the above actions, so check if there are files
        if: ${{ always() && hashFiles(format('{0}/build/reports/kover/report.xml', github.workspace)) != '' }}
        with:
          path: ${{ github.workspace }}/build/reports/kover/report.xml
          token: ${{ secrets.CI_SPLENDO_PAT }}
          title: Code coverage
          update-comment: true
          coverage-counter-type: LINE
      - name: Upload Android test artifact
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: "Android Test Report HTML"
          path: "**/build/reports/tests/testDebugUnitTest"
      - name: Upload Coverage report
        uses: actions/upload-artifact@v4
        if: ${{ always() && hashFiles(format('{0}/build/reports/kover/html/index.html', github.workspace)) != '' }}
        with:
          name: "Android Test Report HTML"
          path: "**/build/reports/kover/html"
      - name: run apiCheck
        run: ./gradlew apiCheck


Android Emulator tests

name: Android Emulator tests
on:
  pull_request:
  workflow_dispatch:
    inputs:
      project:
        description: 'Project (Gradle module) to run tests for'
        required: false
        type: string
      video:
        description: 'Record video'
        required: false
        type: boolean

concurrency:
  group: ${{ github.workflow }}-${{ github.ref || github.run_id }}
  cancel-in-progress: true

env:
  GRADLE_OPTS: "-Dorg.gradle.jvmargs=\"-Xmx8G -XX:MaxMetaspaceSize=512m -Dorg.gradle.daemon=false -Dkotlin.incremental=false\" -Dorg.gradle.daemon=false -Dkotlin.incremental=false -Dkotlin.daemon.jvm.options=-Xmx8G,-XX:MaxMetaspaceSize=512m,-Dorg.gradle.daemon=false,-Dkotlin.incremental=false"
  JAVA_OPTS: "-Xmx8G -XX:MaxMetaspaceSize=512m -Dorg.gradle.daemon=false -Dkotlin.incremental=false"
  ANDROID_EMULATOR_WAIT_TIME_BEFORE_KILL: 120

jobs:
  build:
    uses: ./.github/workflows/setup_macos.yaml
    with:
      gradleTask: bundleLibRuntimeToJarDebug
      project: ${{ inputs.project }}
      projectBlacklist: hud

  test:
    needs: build
    runs-on: macos-13
    strategy:
      fail-fast: false
      matrix:
        api-level: [24, 34]
        project: ${{ fromJSON(needs.build.outputs.projects) }}
    steps:
      - name: checkout
        uses: actions/checkout@v3
        with:
          submodules: recursive

      - name: Setup tools and cache for workspace
        uses: ./.github/workflows/setup_tools_macos/
        with:
          kotlinVersion: ${{ needs.build.outputs.kotlinVersion }}
          arch: ${{ runner.arch == 'X86' && 'x86' || runner.arch == 'X64' && 'x86_64' || runner.arch == 'ARM' && 'arm32' || 'arm64' }}

      - name: AVD cache
        uses: actions/cache@v4
        id: avd-cache
        with:
          path: |
            ~/.android/avd/*
            ~/.android/adb*
          key: avd.v11-${{ matrix.api-level }}

      - name: create AVD and generate snapshot for caching
        if: steps.avd-cache.outputs.cache-hit != 'true'
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          target: google_apis
          force-avd-creation: false
          emulator-options: -no-window -gpu swiftshader_indirect -noaudio -no-boot-anim -camera-back none
          disable-animations: true
          arch: x86_64
          disk-size: 3G
          ram-size: 3G
          heap-size: 1500M
          profile: 3.4in WQVGA
          channel: canary
          cores: 6
          script: ./script/check_emulator.sh

      - name: install ffmpeg
        if: inputs.video
        uses: FedericoCarboni/setup-ffmpeg@v2

      - name: pregenerate test package
        if: inputs.video
        run: ./gradlew :${{ matrix.project }}:packageDebugAndroidTest

      - name: run tests
        uses: reactivecircus/android-emulator-runner@v2
        with:
          api-level: ${{ matrix.api-level }}
          target: google_apis
          force-avd-creation: false
          emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot-save -noaudio -no-boot-anim -camera-back none
          disable-animations: true
          arch: x86_64
          disk-size: 3G
          ram-size: 3G
          heap-size: 1500M
          profile: 3.4in WQVGA
          channel: canary
          cores: 6
          script: |
            ./script/check_emulator.sh
            ./gradlew ${{ inputs.video && 'recordAndroid' }} :${{ matrix.project }}:connectedDebugAndroidTest

      - name: rename video
        if: always() && inputs.video
        run: mv build/video.mp4 recording-${{ matrix.project }}-${{ matrix.api-level }}.mp4

      - name: upload video
        if: always() && inputs.video
        continue-on-error: true
        uses: actions/upload-artifact@master
        with:
          name: recording-${{ matrix.project }}-${{ matrix.api-level }}
          path: recording-${{ matrix.project }}-${{ matrix.api-level }}.mp4


iOS tests

name: iOS tests
on: pull_request
env:
  GRADLE_OPTS: "-Dorg.gradle.jvmargs=\"-Xmx8G -XX:MaxMetaspaceSize=512m -Dorg.gradle.daemon=false -Dkotlin.incremental=false\" -Dorg.gradle.daemon=false -Dkotlin.incremental=false -Dkotlin.daemon.jvm.options=-Xmx8G,-XX:MaxMetaspaceSize=512m,-Dorg.gradle.daemon=false,-Dkotlin.incremental=false"
  JAVA_OPTS: "-Xmx8G -XX:MaxMetaspaceSize=512m -Dorg.gradle.daemon=false -Dkotlin.incremental=false"

jobs:
  build:
    uses: ./.github/workflows/setup_macos.yaml
    with:
      gradleTask: compileKotlinIosSimulatorArm64

  lint:
    needs: build
    runs-on: macos-14
    steps:
    - name: checkout
      uses: actions/checkout@v3
      with:
        submodules: recursive

    - name: Setup tools and cache for workspace
      uses: ./.github/workflows/setup_tools_macos/
      with:
        kotlinVersion: ${{ needs.build.outputs.kotlinVersion }}
        arch: ${{ runner.arch == 'X86' && 'x86' || runner.arch == 'X64' && 'x86_64' || runner.arch == 'ARM' && 'arm32' || 'arm64' }}

    - name: ktLint
      run: ./gradlew lintKotlin

    - name: ktLint report
      uses: actions/upload-artifact@v3
      with:
        name: ktLint report
        path: build/reports/ktlint
      if: ${{ failure() }}

  test:
    needs: build
    runs-on: macos-14
    strategy:
      fail-fast: false
      matrix:
        module: ${{ fromJSON(needs.build.outputs.projects) }}
    steps:
      - name: checkout
        uses: actions/checkout@v4

      - name: Setup tools and cache for workspace
        uses: ./.github/workflows/setup_tools_macos/
        with:
          kotlinVersion: ${{ needs.build.outputs.kotlinVersion }}
          arch: ${{ runner.arch == 'X86' && 'x86' || runner.arch == 'X64' && 'x86_64' || runner.arch == 'ARM' && 'arm32' || 'arm64' }}

      - name: run iOS tests
        run: ./gradlew :${{ matrix.module }}:ios${{ runner.arch == 'X86' && 'X86' || runner.arch == 'X64' && 'x86_64' || runner.arch == 'ARM' && 'SimulatorArm32' || 'SimulatorArm64' }}Test
      - name: Upload iOS test artifact
        uses: actions/upload-artifact@v4
        if: failure()
        with:
          name: ${{ matrix.module}} iOS Test Report HTML
          path: ${{ format('**{0}/build/reports/tests/ios{1}Test', matrix.module, runner.arch == 'X86' && 'X86' || runner.arch == 'X64' && 'x86_64' || runner.arch == 'ARM' && 'SimulatorArm32' || 'SimulatorArm64') }}


Publish

name: Publish
on: push

env:
  GRADLE_OPTS: "-Dorg.gradle.jvmargs=\"-Xmx8G -XX:MaxMetaspaceSize=512m -Dorg.gradle.daemon=false -Dkotlin.incremental=false\" -Dorg.gradle.daemon=false -Dkotlin.incremental=false -Dkotlin.daemon.jvm.options=-Xmx8G,-XX:MaxMetaspaceSize=512m,-Dorg.gradle.daemon=false,-Dkotlin.incremental=false"
  JAVA_OPTS: "-Xmx8G -XX:MaxMetaspaceSize=512m -Dorg.gradle.daemon=false -Dkotlin.incremental=false"
  SIGNING_SECRET_KEY_RING_FILE: ${{ github.workspace }}/kaluga-library-components/keys/secret-keys.gpg

concurrency: publish-${{ github.ref_name }}

jobs:
  publish:
    env:
      OSSRH_PASSWORD: ${{ secrets.OSSRH_PASSWORD }}
      OSSRH_USERNAME: ${{ secrets.OSSRH_USERNAME }}
      SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }}
      SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
    runs-on: ${{ github.ref_name == 'master' && 'tartelet' || 'macos-14' }}
    steps:
      - name: checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive

      # remove VM settings as defined for using the IDE
      - run: sed -i '' -e '/org.gradle.jvmargs/d' gradle.properties; cat gradle.properties

      # TODO: use setup_tools_macos

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

      - name: Konan cache
        uses: actions/cache@v4
        id: konan-cache
        with:
          path: ~/.konan/*
          key: konan
      - name: Install Android SDK
        id: android_sdk_install
        uses: android-actions/setup-android@v3
        with:
          log-accepted-android-sdk-licenses: false
      # We're seeing some issues with publishing to Sonatype due to split up repos. By publishing to MavenLocal first we might circumvent this
      - name: "Publish MavenLocal"
        env:
            MAVEN_CENTRAL_RELEASE: ${{ github.ref_name == 'master' }}
        run: ./gradlew publishToMavenLocal --stacktrace
      - name: "Publish SNAPSHOT"
        if: ${{ github.ref_name != 'master' }}
        run: ./gradlew publishAllPublicationsToSnapshotsRepository --stacktrace

      - name: "Publish Maven Central"
        if: ${{ github.ref_name == 'master' }}
        env:
          MAVEN_CENTRAL_RELEASE: "true"
        run: ./gradlew publishAllPublicationsToSonatypeRepository --stacktrace --no-parallel


Rerun failed emulator tests

name: Rerun failed emulator tests
permissions:
  contents: write

on:
  workflow_run:
    workflows: ["Android Emulator tests"]
    types:
      - completed

jobs:
  on-failure:
    runs-on: ubuntu-latest
    if: ${{ github.event.workflow_run.conclusion == 'failure' && github.event.workflow_run.run_attempt < 2 }}
    env:
      GH_TOKEN: ${{ secrets.GITHUB_TOKEN }}
    steps:
      - name: checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive
      - run: gh run rerun ${{ github.event.workflow_run.id }} --failed


Setup macOS workspace reusable workflow

name: 'Setup macOS workspace reusable workflow'

env:
  GRADLE_OPTS: "-Dorg.gradle.jvmargs=\"-Xmx8G -XX:MaxMetaspaceSize=512m -Dorg.gradle.daemon=false -Dkotlin.incremental=false\" -Dorg.gradle.daemon=false -Dkotlin.incremental=false -Dkotlin.daemon.jvm.options=-Xmx8G,-XX:MaxMetaspaceSize=512m,-Dorg.gradle.daemon=false,-Dkotlin.incremental=false"
  JAVA_OPTS: "-Xmx8G -XX:MaxMetaspaceSize=512m -Dorg.gradle.daemon=false -Dkotlin.incremental=false"

on:
  workflow_call:
    inputs:
      gradleTask:
        required: false
        type: string
      project:
        required: false
        type: string
      projectBlacklist:
        required: false
        type: string

    outputs:
      kotlinVersion:
        description: "kaluga.kotlinVersion property from gradle.properties"
        value: ${{ jobs.setup.outputs.kotlinVersion }}
      projects:
        description: "Gradle projects that do not dependent on another project or have other projects dependent on them"
        value: ${{ jobs.setup.outputs.projects }}
jobs:
  setup:

    runs-on: macos-14

    outputs:
      projects: ${{ steps.envFile.outputs.projects }}
      kotlinVersion: ${{ steps.kotlinVersion.outputs.kotlinVersion }}

    steps:
      - name: checkout
        uses: actions/checkout@v4
        with:
          submodules: recursive

      - name: remove VM settings as defined in gradle.properties (for using in the IDE)
        run: sed -i '' -e '/org.gradle.jvmargs/d' gradle.properties; cat gradle.properties

      - name: get Kotlin version
        id: kotlinVersion
        run: grep kaluga.kotlinVersion= gradle.properties | sed s/"kaluga."// >> $GITHUB_OUTPUT

      - name: setup tools and enable Gradle cache writing
        uses: ./.github/workflows/setup_tools_macos/
        with:
          gradle-cache-read-only: 'false'
          restore-workspace-cache: 'false'
          kotlinVersion: ${{ steps.kotlinVersion.outputs.kotlinVersion }}
          arch: ${{ runner.arch == 'X86' && 'x86' || runner.arch == 'X64' && 'x86_64' || runner.arch == 'ARM' && 'arm32' || 'arm64' }}
          project: ${{ inputs.project }}

      - name: generate file with projects for build matrix
        if: inputs.project == ''
        run: ./gradlew generateNonDependentProjectsFile -PgenerateNonDependentProjectsFile.blacklist=${{ inputs.projectBlacklist }}

      - name: generate file with single requested project for build matrix
        if: inputs.project != ''
        run: echo "projects=['${{ inputs.project }}']" > non_dependent_projects.properties

      - name: show projects for Matrix
        run: cat non_dependent_projects.properties

      - name: load projects for build matrix
        uses: cardinalby/export-env-action@v2
        id: envFile
        with:
          envFile: 'non_dependent_projects.properties'
          export: 'false'

      - name: run custom Gradle task for all projects
        if: inputs.project == ''
        run: ./gradlew ${{ inputs.gradleTask }}

      - name: run custom Gradle task for single project
        if: inputs.project != ''
        run: ./gradlew :${{ inputs.project }}:${{ inputs.gradleTask }}

      - name: Make cache of workspace
        uses: actions/cache/save@v4
        id: store-build
        with:
          path: |
            ./*
            !/.gradle
          key: build-iOS-${{ github.sha }}-${{ inputs.project }}


Master

name: Master

on:
  push:
    branches: [ master ]

jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-version: 17
      - name: setup gradle cache
        uses: gradle/actions/setup-gradle@v3
        with:
          cache-read-only: false
      - name: run assemble
        run: ./gradlew assemble
      - name: run kover
        run: ./gradlew koverXmlReport
      - uses: codecov/codecov-action@v4
      - name: run lint
        run: ./gradlew :app:lint
      - name: run detektCheck
        run: ./gradlew detektCheck


Pre-Merge

name: Pre-Merge

on:
  pull_request:

jobs:
  assemble:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-version: 17
      - name: setup gradle cache
        uses: gradle/actions/setup-gradle@v3
      - name: run assemble
        run: ./gradlew assemble

  test:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-version: 17
      - name: setup gradle cache
        uses: gradle/actions/setup-gradle@v3
      - name: run kover
        run: ./gradlew koverXmlReport
      - uses: codecov/codecov-action@v4
      - name: publish results
        uses: EnricoMi/publish-unit-test-result-action@v2
        if: always()
        with:
          files: ./**/build/test-results/**/*.xml
          action_fail: true
          action_fail_on_inconclusive: true

  ktlint:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-version: 17
      - name: setup gradle cache
        uses: gradle/actions/setup-gradle@v3
      - name: run ktlintCheck
        run: ./gradlew ktlintCheck

  analyze:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          fetch-depth: 100
      - name: set up JDK 17
        uses: actions/setup-java@v4
        with:
          distribution: 'adopt'
          java-version: 17
      - name: setup gradle cache
        uses: gradle/actions/setup-gradle@v3
      - name: run lint
        run: ./gradlew :app:lint
      - name: run detektCheck
        run: ./gradlew detektCheck
      - uses: ruby/setup-ruby@v1
        with:
          ruby-version: '2.7'
          bundler-cache: true
      - name: danger
        run: bundle exec danger
        env:
          DANGER_GITHUB_API_TOKEN: ${{ secrets.DANGER_GITHUB_API_TOKEN }}


CI Workflow

name: CI Workflow
# Run this workflow every time a new commit pushed to your repository
on: push

jobs:
  unit-tests:
    name: Run Unit Tests
    runs-on: macos-latest
    steps:
      # Checks out a copy of your repository on the ubuntu-latest machine
      - name: Checkout code
        uses: actions/checkout@v2

      # Set up Java JDK
      - name: Set up JDK 17
        uses: actions/setup-java@v3
        with:
          java-version: '17'
          distribution: 'temurin'

      # Get the secrets from GitHub and add them to local.properties
      # https://blog.jakelee.co.uk/accessing-android-app-secret-from-github-actions-using-gradle/
      - name: Access PLATFORM_CLIENT_ID
        env:
          PLATFORM_CLIENT_ID: ${{ secrets.PLATFORM_CLIENT_ID }}
        run: echo PLATFORM_CLIENT_ID=\"$PLATFORM_CLIENT_ID\" >> ./local.properties

      - name: Access PLATFORM_REDIRECT_URI
        env:
          PLATFORM_REDIRECT_URI: ${{ secrets.PLATFORM_REDIRECT_URI }}
        run: echo PLATFORM_REDIRECT_URI=\"$PLATFORM_REDIRECT_URI\" >> ./local.properties

      # Create google-services.json
      - name: Create google-services.json
        run: |
            cat << EOF > PennMobile/google-services.json
            ${{ secrets.GOOGLE_SERVICES_JSON }}
            EOF

      # Run unit tests
      - name: Run Unit Tests
        run: ./gradlew testDebugUnitTest

  # If tests pass, generate and upload APK
  generate-apk:
    name: Generate apk
    runs-on: ubuntu-latest
    needs: unit-tests
    # Generate APK only if we are pushing to master or pushing a new release tag
    if: github.ref == 'refs/heads/master' || startsWith(github.ref, 'refs/tags/v')
    steps:
      - name: Checkout code
        uses: actions/checkout@v1

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

      # Get the secrets from GitHub and add them to local.properties
      - name: Access PLATFORM_CLIENT_ID
        env:
          PLATFORM_CLIENT_ID: ${{ secrets.PLATFORM_CLIENT_ID }}
        run: echo PLATFORM_CLIENT_ID=\"$PLATFORM_CLIENT_ID\" >> ./local.properties

      - name: Access PLATFORM_REDIRECT_URI
        env:
          PLATFORM_REDIRECT_URI: ${{ secrets.PLATFORM_REDIRECT_URI }}
        run: echo PLATFORM_REDIRECT_URI=\"$PLATFORM_REDIRECT_URI\" >> ./local.properties

      # Create google-services.json
      - name: Create google-services.json
        run: |
          cat << EOF > PennMobile/google-services.json
          ${{ secrets.GOOGLE_SERVICES_JSON }}
          EOF

      # Generate Signed APK
      - name: Generate Release APK
        run: ./gradlew assembleRelease

      - name: Setup build tool version variable
        shell: bash
        run: |
          BUILD_TOOL_VERSION=$(ls /usr/local/lib/android/sdk/build-tools/ | tail -n 1)
          echo "BUILD_TOOL_VERSION=$BUILD_TOOL_VERSION" >> $GITHUB_ENV
          echo Last build tool version is: $BUILD_TOOL_VERSION

      - name: Sign app APK
        uses: r0adkll/sign-android-release@v1
        # ID used to access action output
        id: sign_app
        with:
          releaseDirectory: PennMobile/build/outputs/apk/release
          signingKeyBase64: ${{ secrets.SIGNING_KEY }}
          alias: ${{ secrets.ALIAS }}
          keyStorePassword: ${{ secrets.KEY_STORE_PASSWORD }}
          keyPassword: ${{ secrets.KEY_PASSWORD }}
        env:
          BUILD_TOOLS_VERSION: ${{ env.BUILD_TOOL_VERSION }}

      # Upload signed APK
      - uses: actions/upload-artifact@v4
        with:
          name: release.apk
          path: ${{steps.sign_app.outputs.signedReleaseFile}}

  code-cov:
    name: JaCoCo Code Coverage
    # Set the type of machine to run on, macOS is better for running Android emulators
    runs-on: macos-latest
    needs: unit-tests
    steps:
      - name: Checkout code
        uses: actions/checkout@v1

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

      # Get the secrets from GitHub and add them to local.properties
      - name: Access PLATFORM_CLIENT_ID
        env:
          PLATFORM_CLIENT_ID: ${{ secrets.PLATFORM_CLIENT_ID }}
        run: echo PLATFORM_CLIENT_ID=\"$PLATFORM_CLIENT_ID\" >> ./local.properties

      - name: Access PLATFORM_REDIRECT_URI
        env:
          PLATFORM_REDIRECT_URI: ${{ secrets.PLATFORM_REDIRECT_URI }}
        run: echo PLATFORM_REDIRECT_URI=\"$PLATFORM_REDIRECT_URI\" >> ./local.properties

      # Create google-services.json
      - name: Create google-services.json
        run: |
          cat << EOF > PennMobile/google-services.json
          ${{ secrets.GOOGLE_SERVICES_JSON }}
          EOF

      # Run JaCoCo, generate Test Report
      - name: Check Code Coverage
        run: ./gradlew jacocoTestReport --stacktrace

      # Upload reports to GitHub Actions
      - name: Upload Reports
        uses: actions/upload-artifact@v4
        with:
          name: reports
          path: PennMobile/build/reports

  ktlint-check:
      name: Check Kotlin Code Style
      runs-on: ubuntu-latest
      steps:
        - name: Checkout code
          uses: actions/checkout@v2

        - name: Setup JDK 17
          uses: actions/setup-java@v3
          with:
            java-version: '17'
            distribution: 'temurin'

        - name: Install ktlint
          run: |
            curl -sSLO https://github.com/pinterest/ktlint/releases/download/1.2.1/ktlint
            chmod a+x ktlint
            sudo mv ktlint /usr/local/bin/

        - name: Run ktlint
          run: |
            set -o pipefail
            ktlint --reporter=plain > ktlint_errors.txt

        - name: Check for ktlint errors
          if: ${{ failure() || steps.run_ktlint.exitCode == 1 }}
          run: cat ktlint_errors.txt

  # Publish to Firebase App Distribution
  # https://github.com/wzieba/Firebase-Distribution-Github-Action
  deploy-firebase:
    needs: generate-apk
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: release.apk
      - name: Upload APK to Firebase App Distribution
        uses: wzieba/Firebase-Distribution-Github-Action@v1
        with:
          appId: ${{secrets.FIREBASE_APP_ID}}
          serviceCredentialsFileContent: ${{ secrets.CREDENTIAL_FILE_CONTENT }}
          groups: tester
          file: PennMobile-release-unsigned-signed.apk

  # Publish to Play Store test track
  deploy-play-store:
    needs: generate-apk
    if: startsWith(github.ref, 'refs/tags/v')
    runs-on: ubuntu-latest
    steps:
      - uses: actions/download-artifact@v4
        with:
          name: release.apk
      - name: Publish to Play Store internal test track
        uses: r0adkll/upload-google-play@v1
        with:
          serviceAccountJsonPlainText: ${{ secrets.SERVICE_ACCOUNT_JSON }}
          packageName: com.pennapps.labs.pennmobile
          releaseFiles: PennMobile-release-unsigned-signed.apk
          track: internal
          status: completed
          # userFraction: 0.50


CodeQL

name: "CodeQL"

on:
  push:
    branches: [ "**" ]
  pull_request:
    # The branches below must be a subset of the branches above
    branches: [ "master", "develop", "release/**", "feature/**" ]

jobs:
  analyze:
    name: Analyze
    runs-on: ubuntu-20.04
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'java' ]
        # CodeQL supports [ 'cpp', 'csharp', 'go', 'java', 'javascript', 'python', 'ruby' ]
        # Use only 'java' to analyze code written in Java, Kotlin or both
        # Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support

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

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

    # Initializes the CodeQL tools for scanning.
    - name: Initialize CodeQL
      uses: github/codeql-action/init@v3
      with:
        languages: ${{ matrix.language }}
        # If you wish to specify custom queries, you can do so here or in a config file.
        # By default, queries listed here will override any specified in a config file.
        # Prefix the list here with "+" to use these queries and those in the config file.
        # Details on CodeQL's query packs refer to : https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
        # queries: security-extended,security-and-quality

    - name: Setup Gradle
      uses: gradle/actions/setup-gradle@v3
      with:
        gradle-version: 8.1.1

    # Manually build the java bytecode
    - name: Execute Gradle build
      run: ./gradlew assembleLibrariesRelease

    # Perform the analysis
    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v3
      with:
        category: "/language:${{matrix.language}}"


Issue Needs Attention

# NOTE: This is a common file that is overwritten by realm/ci-actions sync service
# and should only be modified in that repository.

name: Issue Needs Attention
# This workflow is triggered on issue comments.
on:
  issue_comment:
    types: created

jobs:
  applyNeedsAttentionLabel:
    uses: realm/ci-actions/.github/workflows/issue-needs-attention.yml@main


Auto Assign

# NOTE: This is a common file that is overwritten by realm/ci-actions sync service
# and should only be modified in that repository.

name: 'Auto Assign'
on:
  pull_request:
    types: [opened]

jobs:
  add-assignee:
    runs-on: ubuntu-latest
    steps:
      - uses: kentaro-m/auto-assign-action@248761c4feb3917c1b0444e33fad1a50093b9847


Auto merge change between branches

# This workflow is intended to keep certain branches in sync and will automatically create PR's between
# these branches. For now these PR's must be manually reviewed and merged. Consider if we should just
# automatically do this if there are no conflicts.
#
# This step will fail if a PR already exists, so we ignore failures. This also
# mean that if some other error occur, the error will also be swallowed. This is acceptable.
name: Auto merge change between branches

on:
  push:
    branches:
      # List of "from" branches. Targets are defined by the `find-target-branch`-step below.
      - releases
      - main

jobs:
  main:
    name: Create PR with changes that should be merged into another branch
    runs-on: ubuntu-latest
    steps:
      - name: git checkout
        uses: actions/checkout@v3

      # Set the branch we want to merge changes into as step output. This step should list each branch name found in the `push`
      # trigger in the top of this file.
      - name: Set target branch
        id: find-target-branch
        shell: sh
        run: |
          if [ "${GITHUB_REF#refs/heads/}" = "releases" ]; then echo 'branch=${{ github.event.repository.default_branch }}' >> $GITHUB_OUTPUT; fi

      # Unconditionally create a PR with the changes that needs to be manually reviewed.
      # https://cli.github.com/manual/gh_pr_create
      - name: Create Pull Request
        id: open-pr
        run: |
          gh pr create \
          --base '${{ steps.find-target-branch.outputs.branch }}' \
          --head '${{ github.ref_name }}' \
          --title "[Automated] Merge ${{ github.ref_name }} into ${{ steps.find-target-branch.outputs.branch }}" \
          --body 'Automated Pull Request. Remember to choose "Create a merge commit" before merging.' \
          || true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


Check Changelog

# NOTE: This is a common file that is overwritten by realm/ci-actions sync service
# and should only be modified in that repository.

name: "Check Changelog"
on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled]

jobs:
  changelog:
    runs-on: ubuntu-latest
    steps:
      - name: Checkout
        uses: actions/checkout@8230315d06ad95c617244d2f265d237a1682d445
        with:
          submodules: false
      - name: Enforce Changelog
        uses: dangoslen/changelog-enforcer@c0b9fd225180a405c5f21f7a74b99e2eccc3e951
        with:
          skipLabels: no-changelog
          missingUpdateErrorMessage: Please add an entry in CHANGELOG.md or apply the 'no-changelog' label to skip this check.


Check PR Title

# NOTE: This is a common file that is overwritten by realm/ci-actions sync service
# and should only be modified in that repository.

name: "Check PR Title"
on:
  pull_request:
    types: [opened, synchronize, reopened, ready_for_review, labeled, unlabeled, converted_to_draft, edited]

jobs:
  check-pr-title:
    name: Check PR Title
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
        with:
          submodules: false
      - name: Enforce PR title
        uses: realm/ci-actions/title-checker@main
        with:
          regex: R[A-Z]{2,6}-[0-9]{1,6}
          error-hint: Invalid PR title. Make sure it's prefixed with the JIRA ticket the PR addresses or add the no-jira-ticket label.
          ignore-labels: 'no-jira-ticket'