name: Reusable Android Build and Test on: workflow_call: secrets: GRADLE_ENCRYPTION_KEY: required: false DATADOG_APPLICATION_ID: required: false DATADOG_CLIENT_TOKEN: required: false CODECOV_TOKEN: required: false GRADLE_CACHE_URL: required: false GRADLE_CACHE_USERNAME: required: false GRADLE_CACHE_PASSWORD: required: false inputs: upload_artifacts: description: 'Whether to upload build and Detekt artifacts' required: false type: boolean default: true test_flavors: description: 'Which flavors to build and test: "google", "fdroid", or "both"' required: false type: string default: 'both' jobs: build: runs-on: ubuntu-latest permissions: id-token: write contents: read attestations: write timeout-minutes: 35 env: DATADOG_APPLICATION_ID: ${{ secrets.DATADOG_APPLICATION_ID }} DATADOG_CLIENT_TOKEN: ${{ secrets.DATADOG_CLIENT_TOKEN }} MAPS_API_KEY: ${{ secrets.GOOGLE_MAPS_API_KEY }} GRADLE_CACHE_URL: ${{ secrets.GRADLE_CACHE_URL }} GRADLE_CACHE_USERNAME: ${{ secrets.GRADLE_CACHE_USERNAME }} GRADLE_CACHE_PASSWORD: ${{ secrets.GRADLE_CACHE_PASSWORD }} steps: - name: Checkout code uses: actions/checkout@v6 with: fetch-depth: 0 submodules: 'recursive' - name: Set up JDK 17 uses: actions/setup-java@v5 with: java-version: '17' distribution: 'jetbrains' env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Setup Gradle uses: gradle/actions/setup-gradle@v5 with: cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} build-scan-publish: true build-scan-terms-of-use-url: 'https://gradle.com/terms-of-service' build-scan-terms-of-use-agree: 'yes' add-job-summary: always - name: Calculate Version Code id: calculate_version_code uses: ./.github/actions/calculate-version-code - name: Expose Version Code as Environment Variable run: echo "VERSION_CODE=${{ steps.calculate_version_code.outputs.versionCode }}" >> $GITHUB_ENV - name: Load secrets if: env.DATADOG_APPLICATION_ID != '' && env.DATADOG_CLIENT_TOKEN != '' run: | echo "datadogApplicationId=$DATADOG_APPLICATION_ID" >> ./secrets.properties echo "datadogClientToken=$DATADOG_CLIENT_TOKEN" >> ./secrets.properties - name: Determine build tasks id: build-tasks run: | FLAVOR="${{ inputs.test_flavors }}" if [ "$FLAVOR" = "google" ]; then echo "tasks=assembleGoogleDebug testGoogleDebugUnitTest" >> $GITHUB_OUTPUT elif [ "$FLAVOR" = "fdroid" ]; then echo "tasks=assembleFdroidDebug testFdroidDebugUnitTest" >> $GITHUB_OUTPUT else echo "tasks=assembleDebug testGoogleDebugUnitTest testFdroidDebugUnitTest" >> $GITHUB_OUTPUT fi - name: Build and Run Unit Tests run: ./gradlew ${{ steps.build-tasks.outputs.tasks }} koverXmlReport -Pci=true --continue --scan env: VERSION_CODE: ${{ env.VERSION_CODE }} - name: Upload coverage reports to Codecov uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} slug: meshtastic/Meshtastic-Android report_type: coverage directory: . files: "**/build/reports/kover/report.xml" - name: Upload test results to Codecov if: ${{ !cancelled() }} uses: codecov/codecov-action@v5 with: token: ${{ secrets.CODECOV_TOKEN }} report_type: test_results directory: . files: "**/build/test-results/**/*.xml,**/build/outputs/androidTest-results/**/*.xml" - name: Upload F-Droid debug artifact if: ${{ inputs.upload_artifacts && (inputs.test_flavors == 'fdroid' || inputs.test_flavors == 'both') }} uses: actions/upload-artifact@v6 with: name: fdroidDebug path: app/build/outputs/apk/fdroid/debug/app-fdroid-debug.apk retention-days: 14 - name: Upload Google debug artifact if: ${{ inputs.upload_artifacts && (inputs.test_flavors == 'google' || inputs.test_flavors == 'both') }} uses: actions/upload-artifact@v6 with: name: googleDebug path: app/build/outputs/apk/google/debug/app-google-debug.apk retention-days: 14 - name: Upload reports if: ${{ inputs.upload_artifacts }} uses: actions/upload-artifact@v6 with: name: upload-reports path: | build/reports **/build/reports retention-days: 14