name: Build

on:
  push:
    branches:
      - main
  workflow_dispatch:
    inputs:
      version-name:
        description: "Optional. Version string to use, in X.Y.Z format. Overrides default in the project."
        required: false
        type: string
      version-code:
        description: "Optional. Build number to use. Overrides default of GitHub run number."
        required: false
        type: number
      distribute-to-firebase:
        description: "Optional. Distribute artifacts to Firebase."
        required: false
        default: false
        type: boolean
      publish-to-play-store:
        description: "Optional. Deploy bundle artifact to Google Play Store"
        required: false
        default: false
        type: boolean

env:
  GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
  JAVA_VERSION: 17
  GITHUB_ACTION_RUN_URL: "https://github.com/${{ github.repository }}/actions/runs/${{ github.run_id }}"

jobs:
  build:
    name: Build
    runs-on: ubuntu-24.04

    steps:
      - name: Check out repo
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Validate Gradle wrapper
        uses: gradle/actions/wrapper-validation@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1

      - name: Cache Gradle files
        uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-v2-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }}
          restore-keys: |
            ${{ runner.os }}-gradle-v2-

      - name: Cache build output
        uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
        with:
          path: |
            ${{ github.workspace }}/build-cache
          key: ${{ runner.os }}-build-cache-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-build-

      - name: Configure JDK
        uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
        with:
          distribution: "temurin"
          java-version: ${{ env.JAVA_VERSION }}

      - name: Configure Ruby
        uses: ruby/setup-ruby@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.0
        with:
          bundler-cache: true

      - name: Install Fastlane
        run: |
          gem install bundler:2.2.27
          bundle config path vendor/bundle
          bundle install --jobs 4 --retry 3

      - name: Check
        run: bundle exec fastlane check

      - name: Build
        run: bundle exec fastlane assembleDebugApks

      - name: Upload test reports on failure
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        if: failure()
        with:
          name: test-reports
          path: app/build/reports/tests/

  publish_playstore:
    name: Publish Play Store artifacts
    needs:
      - build
    runs-on: ubuntu-24.04
    strategy:
      fail-fast: false
      matrix:
        variant: ["prod", "dev"]
        artifact: ["apk", "aab"]
    steps:
      - name: Check out repo
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Configure Ruby
        uses: ruby/setup-ruby@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.0
        with:
          bundler-cache: true

      - name: Install Fastlane
        run: |
          gem install bundler:2.2.27
          bundle config path vendor/bundle
          bundle install --jobs 4 --retry 3

      - name: Log in to Azure
        uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
        with:
          creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}

      - name: Retrieve secrets
        env:
          ACCOUNT_NAME: bitwardenci
          CONTAINER_NAME: mobile
        run: |
          mkdir -p ${{ github.workspace }}/secrets
          mkdir -p ${{ github.workspace }}/app/src/standardBeta
          mkdir -p ${{ github.workspace }}/app/src/standardRelease

          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name app_play-keystore.jks --file ${{ github.workspace }}/keystores/app_play-keystore.jks --output none
          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name app_upload-keystore.jks --file ${{ github.workspace }}/keystores/app_upload-keystore.jks --output none
          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name play_creds.json --file ${{ github.workspace }}/secrets/play_creds.json --output none
          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name app_beta_play-keystore.jks --file ${{ github.workspace }}/keystores/app_beta_play-keystore.jks --output none
          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name app_beta_upload-keystore.jks --file ${{ github.workspace }}/keystores/app_beta_upload-keystore.jks --output none
          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name google-services.json --file ${{ github.workspace }}/app/src/standardRelease/google-services.json --output none
          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name google-services.json --file ${{ github.workspace }}/app/src/standardBeta/google-services.json --output none

      - name: Download Firebase credentials
        if: ${{ matrix.variant == 'prod' && (inputs.distribute-to-firebase || github.event_name == 'push') }}
        env:
          ACCOUNT_NAME: bitwardenci
          CONTAINER_NAME: mobile
        run: |
          mkdir -p ${{ github.workspace }}/secrets

          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name app_play_prod_firebase-creds.json --file ${{ github.workspace }}/secrets/app_play_prod_firebase-creds.json --output none

      - name: Validate Gradle wrapper
        uses: gradle/actions/wrapper-validation@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1

      - name: Cache Gradle files
        uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-v2-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }}
          restore-keys: |
            ${{ runner.os }}-gradle-v2-

      - name: Cache build output
        uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
        with:
          path: |
            ${{ github.workspace }}/build-cache
          key: ${{ runner.os }}-build-cache-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-build-

      - name: Configure JDK
        uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
        with:
          distribution: "temurin"
          java-version: ${{ env.JAVA_VERSION }}

      - name: Update app CI Build info
        run: |
          ./scripts/update_app_ci_build_info.sh \
          $GITHUB_REPOSITORY \
          $GITHUB_REF_NAME \
          $GITHUB_SHA \
          $GITHUB_RUN_ID \
          $GITHUB_RUN_ATTEMPT

      - name: Increment version
        run: |
          DEFAULT_VERSION_CODE=$((11000+$GITHUB_RUN_NUMBER))
          bundle exec fastlane setBuildVersionInfo \
          versionCode:${{ inputs.version-code || '$DEFAULT_VERSION_CODE' }} \
          versionName:${{ inputs.version-name }}

      - name: Generate release Play Store bundle
        if: ${{ matrix.variant == 'prod' && matrix.artifact == 'aab' }}
        env:
          UPLOAD_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_KEYSTORE_PASSWORD }}
        run: |
          bundle exec fastlane bundlePlayStoreRelease \
          storeFile:app_upload-keystore.jks \
          storePassword:${{ env.UPLOAD_KEYSTORE_PASSWORD }} \
          keyAlias:upload \
          keyPassword:${{ env.UPLOAD_KEYSTORE_PASSWORD }}

      - name: Generate beta Play Store bundle
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
        env:
          UPLOAD_BETA_KEYSTORE_PASSWORD: ${{ secrets.UPLOAD_BETA_KEYSTORE_PASSWORD }}
          UPLOAD_BETA_KEY_PASSWORD: ${{ secrets.UPLOAD_BETA_KEY_PASSWORD }}
        run: |
          bundle exec fastlane bundlePlayStoreBeta \
          storeFile:app_beta_upload-keystore.jks \
          storePassword:${{ env.UPLOAD_BETA_KEYSTORE_PASSWORD }} \
          keyAlias:bitwarden-beta-upload \
          keyPassword:${{ env.UPLOAD_BETA_KEY_PASSWORD }}

      - name: Generate release Play Store APK
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
        env:
          PLAY_KEYSTORE_PASSWORD: ${{ secrets.PLAY_KEYSTORE_PASSWORD }}
        run: |
          bundle exec fastlane assemblePlayStoreReleaseApk \
          storeFile:app_play-keystore.jks \
          storePassword:${{ env.PLAY_KEYSTORE_PASSWORD }} \
          keyAlias:bitwarden \
          keyPassword:${{ env.PLAY_KEYSTORE_PASSWORD }}

      - name: Generate beta Play Store APK
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
        env:
          PLAY_BETA_KEYSTORE_PASSWORD: ${{ secrets.PLAY_BETA_KEYSTORE_PASSWORD }}
          PLAY_BETA_KEY_PASSWORD: ${{ secrets.PLAY_BETA_KEY_PASSWORD }}
        run: |
          bundle exec fastlane assemblePlayStoreBetaApk \
          storeFile:app_beta_play-keystore.jks \
          storePassword:${{ env.PLAY_BETA_KEYSTORE_PASSWORD }} \
          keyAlias:bitwarden-beta \
          keyPassword:${{ env.PLAY_BETA_KEY_PASSWORD }}

      - name: Generate debug Play Store APKs
        if: ${{ (matrix.variant != 'prod') && (matrix.artifact == 'apk') }}
        run: |
          bundle exec fastlane assembleDebugApks

      - name: Upload release Play Store .aab artifact
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.aab
          path: app/build/outputs/bundle/standardRelease/com.x8bit.bitwarden.aab
          if-no-files-found: error

      - name: Upload beta Play Store .aab artifact
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.beta.aab
          path: app/build/outputs/bundle/standardBeta/com.x8bit.bitwarden.beta.aab
          if-no-files-found: error

      - name: Upload release .apk artifact
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.apk
          path: app/build/outputs/apk/standard/release/com.x8bit.bitwarden.apk
          if-no-files-found: error

      - name: Upload beta .apk artifact
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.beta.apk
          path: app/build/outputs/apk/standard/beta/com.x8bit.bitwarden.beta.apk
          if-no-files-found: error

      # When building variants other than 'prod'
      - name: Upload debug .apk artifact
        if: ${{ (matrix.variant != 'prod') && (matrix.artifact == 'apk') }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.${{ matrix.variant }}.apk
          path: app/build/outputs/apk/standard/debug/com.x8bit.bitwarden.dev.apk
          if-no-files-found: error

      - name: Create checksum for release .apk artifact
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
        run: |
          sha256sum "app/build/outputs/apk/standard/release/com.x8bit.bitwarden.apk" \
            > ./com.x8bit.bitwarden.apk-sha256.txt

      - name: Create checksum for beta .apk artifact
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
        run: |
          sha256sum "app/build/outputs/apk/standard/beta/com.x8bit.bitwarden.beta.apk" \
            > ./com.x8bit.bitwarden.beta.apk-sha256.txt

      - name: Create checksum for release .aab artifact
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
        run: |
          sha256sum "app/build/outputs/bundle/standardRelease/com.x8bit.bitwarden.aab" \
            > ./com.x8bit.bitwarden.aab-sha256.txt

      - name: Create checksum for beta .aab artifact
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
        run: |
          sha256sum "app/build/outputs/bundle/standardBeta/com.x8bit.bitwarden.beta.aab" \
            > ./com.x8bit.bitwarden.beta.aab-sha256.txt

      - name: Create checksum for Debug .apk artifact
        if: ${{ (matrix.variant != 'prod') && (matrix.artifact == 'apk') }}
        run: |
          sha256sum "app/build/outputs/apk/standard/debug/com.x8bit.bitwarden.dev.apk" \
           > ./com.x8bit.bitwarden.${{ matrix.variant }}.apk-sha256.txt

      - name: Upload .apk SHA file for release
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.apk-sha256.txt
          path: ./com.x8bit.bitwarden.apk-sha256.txt
          if-no-files-found: error

      - name: Upload .apk SHA file for beta
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'apk') }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.beta.apk-sha256.txt
          path: ./com.x8bit.bitwarden.beta.apk-sha256.txt
          if-no-files-found: error

      - name: Upload .aab SHA file for release
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.aab-sha256.txt
          path: ./com.x8bit.bitwarden.aab-sha256.txt
          if-no-files-found: error

      - name: Upload .aab SHA file for beta
        if: ${{ (matrix.variant == 'prod') && (matrix.artifact == 'aab') }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.beta.aab-sha256.txt
          path: ./com.x8bit.bitwarden.beta.aab-sha256.txt
          if-no-files-found: error

      - name: Upload .apk SHA file for debug
        if: ${{ (matrix.variant != 'prod') && (matrix.artifact == 'apk') }}
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.${{ matrix.variant }}.apk-sha256.txt
          path: ./com.x8bit.bitwarden.${{ matrix.variant }}.apk-sha256.txt
          if-no-files-found: error

      - name: Install Firebase app distribution plugin
        if: ${{ matrix.variant == 'prod' && (inputs.distribute-to-firebase || github.event_name == 'push') }}
        run: bundle exec fastlane add_plugin firebase_app_distribution

      - name: Publish release artifacts to Firebase
        if: ${{ matrix.variant == 'prod' && matrix.artifact == 'apk' && (inputs.distribute-to-firebase || github.event_name == 'push') }}
        env:
          APP_PLAY_FIREBASE_CREDS_PATH: ${{ github.workspace }}/secrets/app_play_prod_firebase-creds.json
        run: |
          bundle exec fastlane distributeReleasePlayStoreToFirebase \
          actionUrl:${{ env.GITHUB_ACTION_RUN_URL }} \
          service_credentials_file:${{ env.APP_PLAY_FIREBASE_CREDS_PATH }}

      - name: Publish beta artifacts to Firebase
        if: ${{ (matrix.variant == 'prod' && matrix.artifact == 'apk') && (inputs.distribute-to-firebase || github.event_name == 'push') }}
        env:
          APP_PLAY_FIREBASE_CREDS_PATH: ${{ github.workspace }}/secrets/app_play_prod_firebase-creds.json
        run: |
          bundle exec fastlane distributeBetaPlayStoreToFirebase \
          actionUrl:${{ env.GITHUB_ACTION_RUN_URL }} \
          service_credentials_file:${{ env.APP_PLAY_FIREBASE_CREDS_PATH }}

      - name: Verify Play Store credentials
        if: ${{ matrix.variant == 'prod' && inputs.publish-to-play-store }}
        run: |
          bundle exec fastlane run validate_play_store_json_key

      - name: Publish Play Store bundle
        if: ${{ matrix.variant == 'prod' && matrix.artifact == 'aab' && (inputs.publish-to-play-store || github.ref_name == 'main') }}
        run: |
          bundle exec fastlane publishProdToPlayStore
          bundle exec fastlane publishBetaToPlayStore

  publish_fdroid:
    name: Publish F-Droid artifacts
    needs:
      - build
    runs-on: ubuntu-24.04
    steps:
      - name: Check out repo
        uses: actions/checkout@11bd71901bbe5b1630ceea73d27597364c9af683 # v4.2.2

      - name: Configure Ruby
        uses: ruby/setup-ruby@ca041f971d66735f3e5ff1e21cc13e2d51e7e535 # v1.233.0
        with:
          bundler-cache: true

      - name: Install Fastlane
        run: |
          gem install bundler:2.2.27
          bundle config path vendor/bundle
          bundle install --jobs 4 --retry 3

      - name: Log in to Azure
        uses: Azure/login@e15b166166a8746d1a47596803bd8c1b595455cf # v1.6.0
        with:
          creds: ${{ secrets.AZURE_KV_CI_SERVICE_PRINCIPAL }}

      - name: Retrieve secrets
        env:
          ACCOUNT_NAME: bitwardenci
          CONTAINER_NAME: mobile
        run: |
          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name app_fdroid-keystore.jks --file ${{ github.workspace }}/keystores/app_fdroid-keystore.jks --output none
          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name app_beta_fdroid-keystore.jks --file ${{ github.workspace }}/keystores/app_beta_fdroid-keystore.jks --output none

      - name: Download Firebase credentials
        if: ${{ inputs.distribute-to-firebase || github.event_name == 'push' }}
        env:
          ACCOUNT_NAME: bitwardenci
          CONTAINER_NAME: mobile
        run: |
          mkdir -p ${{ github.workspace }}/secrets

          az storage blob download --account-name $ACCOUNT_NAME --container-name $CONTAINER_NAME \
          --name app_fdroid_firebase-creds.json --file ${{ github.workspace }}/secrets/app_fdroid_firebase-creds.json --output none

      - name: Validate Gradle wrapper
        uses: gradle/actions/wrapper-validation@06832c7b30a0129d7fb559bcc6e43d26f6374244 # v4.3.1

      - name: Cache Gradle files
        uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
        with:
          path: |
            ~/.gradle/caches
            ~/.gradle/wrapper
          key: ${{ runner.os }}-gradle-v2-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties', '**/libs.versions.toml') }}
          restore-keys: |
            ${{ runner.os }}-gradle-v2-

      - name: Cache build output
        uses: actions/cache@5a3ec84eff668545956fd18022155c47e93e2684 # v4.2.3
        with:
          path: |
            ${{ github.workspace }}/build-cache
          key: ${{ runner.os }}-build-cache-${{ github.sha }}
          restore-keys: |
            ${{ runner.os }}-build-

      - name: Configure JDK
        uses: actions/setup-java@c5195efecf7bdfc987ee8bae7a71cb8b11521c00 # v4.7.1
        with:
          distribution: "temurin"
          java-version: ${{ env.JAVA_VERSION }}

      - name: Update app CI Build info
        run: |
          ./scripts/update_app_ci_build_info.sh \
          $GITHUB_REPOSITORY \
          $GITHUB_REF_NAME \
          $GITHUB_SHA \
          $GITHUB_RUN_ID \
          $GITHUB_RUN_ATTEMPT

      # Start from 11000 to prevent collisions with mobile build version codes
      - name: Increment version
        run: |
          DEFAULT_VERSION_CODE=$((11000+$GITHUB_RUN_NUMBER))
          VERSION_CODE="${{ inputs.version-code || '$DEFAULT_VERSION_CODE' }}"
          bundle exec fastlane setBuildVersionInfo \
          versionCode:$VERSION_CODE \
          versionName:${{ inputs.version-name || '' }}

          regex='versionName = "([^"]+)"'
          if [[ "$(cat app/build.gradle.kts)" =~ $regex ]]; then
            VERSION_NAME="${BASH_REMATCH[1]}"
          fi
          echo "Version Name: ${VERSION_NAME}" >> $GITHUB_STEP_SUMMARY
          echo "Version Number: $VERSION_CODE" >> $GITHUB_STEP_SUMMARY
      - name: Generate F-Droid artifacts
        env:
          FDROID_STORE_PASSWORD: ${{ secrets.FDROID_KEYSTORE_PASSWORD }}
        run: |
          bundle exec fastlane assembleFDroidReleaseApk \
          storeFile:app_fdroid-keystore.jks \
          storePassword:"${{ env.FDROID_STORE_PASSWORD }}" \
          keyAlias:bitwarden \
          keyPassword:"${{ env.FDROID_STORE_PASSWORD }}"

      - name: Generate F-Droid Beta Artifacts
        env:
          FDROID_BETA_KEYSTORE_PASSWORD: ${{ secrets.FDROID_BETA_KEYSTORE_PASSWORD }}
          FDROID_BETA_KEY_PASSWORD: ${{ secrets.FDROID_BETA_KEY_PASSWORD }}
        run: |
          bundle exec fastlane assembleFDroidBetaApk \
          storeFile:app_beta_fdroid-keystore.jks \
          storePassword:"${{ env.FDROID_BETA_KEYSTORE_PASSWORD }}" \
          keyAlias:bitwarden-beta \
          keyPassword:"${{ env.FDROID_BETA_KEY_PASSWORD }}"

      - name: Upload F-Droid .apk artifact
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden-fdroid.apk
          path: app/build/outputs/apk/fdroid/release/com.x8bit.bitwarden-fdroid.apk
          if-no-files-found: error

      - name: Create checksum for F-Droid artifact
        run: |
          sha256sum "app/build/outputs/apk/fdroid/release/com.x8bit.bitwarden-fdroid.apk" \
          > ./com.x8bit.bitwarden-fdroid.apk-sha256.txt

      - name: Upload F-Droid SHA file
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden-fdroid.apk-sha256.txt
          path: ./com.x8bit.bitwarden-fdroid.apk-sha256.txt
          if-no-files-found: error

      - name: Upload F-Droid Beta .apk artifact
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.beta-fdroid.apk
          path: app/build/outputs/apk/fdroid/beta/com.x8bit.bitwarden.beta-fdroid.apk
          if-no-files-found: error

      - name: Create checksum for F-Droid Beta artifact
        run: |
          sha256sum "app/build/outputs/apk/fdroid/beta/com.x8bit.bitwarden.beta-fdroid.apk" \
          > ./com.x8bit.bitwarden.beta-fdroid.apk-sha256.txt

      - name: Upload F-Droid Beta SHA file
        uses: actions/upload-artifact@ea165f8d65b6e75b540449e92b4886f43607fa02 # v4.6.2
        with:
          name: com.x8bit.bitwarden.beta-fdroid.apk-sha256.txt
          path: ./com.x8bit.bitwarden.beta-fdroid.apk-sha256.txt
          if-no-files-found: error

      - name: Install Firebase app distribution plugin
        if: ${{ inputs.distribute-to-firebase || github.event_name == 'push' }}
        run: bundle exec fastlane add_plugin firebase_app_distribution

      - name: Publish release F-Droid artifacts to Firebase
        if: ${{ inputs.distribute-to-firebase || github.event_name == 'push' }}
        env:
          APP_FDROID_FIREBASE_CREDS_PATH: ${{ github.workspace }}/secrets/app_fdroid_firebase-creds.json
        run: |
          bundle exec fastlane distributeReleaseFDroidToFirebase \
          actionUrl:${{ env.GITHUB_ACTION_RUN_URL }} \
          service_credentials_file:${{ env.APP_FDROID_FIREBASE_CREDS_PATH }}
