name: Reusable workflow for build Android on: workflow_call: inputs: branch: required: true default: main type: string gradlew-command: required: false type: string default: "false" run-tests: required: false type: boolean default: true keystore-file-name: required: false type: string default: "false" keystore-file-base64: required: false type: string default: "false" upload-name: required: false type: string default: "apk" build-debug-tests: required: false type: boolean default: false secrets: # Crowdloan secrets - NOT NEEDED for Pezkuwi (own blockchain) ACALA_PROD_AUTH_TOKEN: required: false ACALA_TEST_AUTH_TOKEN: required: false MOONBEAM_PROD_AUTH_TOKEN: required: false MOONBEAM_TEST_AUTH_TOKEN: required: false # Fiat on-ramp - OPTIONAL (future update) MOONPAY_PRODUCTION_SECRET: required: false MOONPAY_TEST_SECRET: required: false # EVM chain support - REQUIRED for cross-chain EHTERSCAN_API_KEY_MOONBEAM: required: true EHTERSCAN_API_KEY_MOONRIVER: required: true EHTERSCAN_API_KEY_ETHEREUM: required: true INFURA_API_KEY: required: true # RPC provider - use own nodes or Dwellir DWELLIR_API_KEY: required: false # WalletConnect - REQUIRED for dApp connections WALLET_CONNECT_PROJECT_ID: required: true # Google OAuth - REQUIRED for cloud backup DEBUG_GOOGLE_OAUTH_ID: required: true RELEASE_GOOGLE_OAUTH_ID: required: true # Special secrets for signing: CI_MARKET_KEYSTORE_PASS: required: false CI_MARKET_KEYSTORE_KEY_ALIAS: required: false CI_MARKET_KEYSTORE_KEY_PASS: required: false CI_MARKET_KEY_FILE: required: false CI_KEYSTORE_PASS: required: false CI_KEYSTORE_KEY_ALIAS: required: false CI_KEYSTORE_KEY_PASS: required: false CI_GITHUB_KEYSTORE_PASS: required: false CI_GITHUB_KEYSTORE_KEY_ALIAS: required: false CI_GITHUB_KEYSTORE_KEY_PASS: required: false # Secrets for google-services: CI_DEVELOP_GOOGLE_SERVICES: required: true CI_PRODUCTION_GOOGLE_SERVICES: required: true env: ACALA_PROD_AUTH_TOKEN: ${{ secrets.ACALA_PROD_AUTH_TOKEN }} ACALA_TEST_AUTH_TOKEN: ${{ secrets.ACALA_TEST_AUTH_TOKEN }} MOONBEAM_PROD_AUTH_TOKEN: ${{ secrets.MOONBEAM_PROD_AUTH_TOKEN }} MOONBEAM_TEST_AUTH_TOKEN: ${{ secrets.MOONBEAM_TEST_AUTH_TOKEN }} MOONPAY_PRODUCTION_SECRET: ${{ secrets.MOONPAY_PRODUCTION_SECRET }} MOONPAY_TEST_SECRET: ${{ secrets.MOONPAY_TEST_SECRET }} MERCURYO_PRODUCTION_SECRET: ${{ secrets.MERCURYO_PRODUCTION_SECRET }} MERCURYO_TEST_SECRET: ${{ secrets.MERCURYO_TEST_SECRET }} EHTERSCAN_API_KEY_MOONBEAM: ${{ secrets.EHTERSCAN_API_KEY_MOONBEAM }} EHTERSCAN_API_KEY_MOONRIVER: ${{ secrets.EHTERSCAN_API_KEY_MOONRIVER }} EHTERSCAN_API_KEY_ETHEREUM: ${{ secrets.EHTERSCAN_API_KEY_ETHEREUM }} INFURA_API_KEY: ${{ secrets.INFURA_API_KEY }} DWELLIR_API_KEY: ${{ secrets.DWELLIR_API_KEY }} WALLET_CONNECT_PROJECT_ID: ${{ secrets.WALLET_CONNECT_PROJECT_ID }} DEBUG_GOOGLE_OAUTH_ID: ${{ secrets.DEBUG_GOOGLE_OAUTH_ID }} RELEASE_GOOGLE_OAUTH_ID: ${{ secrets.RELEASE_GOOGLE_OAUTH_ID }} CI_MARKET_KEYSTORE_PASS: ${{ secrets.CI_MARKET_KEYSTORE_PASS }} CI_MARKET_KEYSTORE_KEY_ALIAS: ${{ secrets.CI_MARKET_KEYSTORE_KEY_ALIAS }} CI_MARKET_KEYSTORE_KEY_PASS: ${{ secrets.CI_MARKET_KEYSTORE_KEY_PASS }} CI_MARKET_KEY_FILE: ${{ secrets.RELEASE_MARKET_KEY_FILE }} CI_KEYSTORE_PASS: ${{ secrets.CI_KEYSTORE_PASS }} CI_KEYSTORE_KEY_ALIAS: ${{ secrets.CI_KEYSTORE_KEY_ALIAS }} CI_KEYSTORE_KEY_PASS: ${{ secrets.CI_KEYSTORE_KEY_PASS }} CI_GITHUB_KEYSTORE_PASS: ${{ secrets.CI_GITHUB_KEYSTORE_PASS }} CI_GITHUB_KEYSTORE_KEY_ALIAS: ${{ secrets.CI_GITHUB_KEYSTORE_KEY_ALIAS }} CI_GITHUB_KEYSTORE_KEY_PASS: ${{ secrets.CI_GITHUB_KEYSTORE_KEY_PASS }} CI_GITHUB_KEYSTORE_KEY_FILE: ${{ secrets.BASE64_GITHUB_KEYSTORE_FILE }} CI_DEVELOP_GOOGLE_SERVICES_FILE: ${{ secrets.CI_DEVELOP_GOOGLE_SERVICES }} CI_PRODUCTION_GOOGLE_SERVICES_FILE: ${{ secrets.CI_PRODUCTION_GOOGLE_SERVICES }} POLKASSEMBLY_SUMMARY_API_KEY: ${{ secrets.POLKASSEMBLY_SUMMARY_API_KEY }} concurrency: group: ${{ github.workflow }}-${{ github.ref }}-${{inputs.upload-name}} cancel-in-progress: true jobs: build-app: name: Build app and test runs-on: ubuntu-24.04 timeout-minutes: 90 steps: - name: Checkout particular branch uses: actions/checkout@v4 with: ref: ${{ inputs.branch }} fetch-depth: 0 - name: Compute version code from commit count run: | COMMIT_COUNT=$(git rev-list --count HEAD) VERSION_CODE=$((COMMIT_COUNT + 100)) echo "CI_BUILD_ID=$VERSION_CODE" >> $GITHUB_ENV echo "Version code: $VERSION_CODE (commits: $COMMIT_COUNT + offset 100)" - name: ๐Ÿ“‚ Set up DEV Google Services uses: davidSchuppa/base64Secret-toFile-action@v3 with: secret: ${{ env.CI_DEVELOP_GOOGLE_SERVICES_FILE }} filename: google-services.json destination-path: ./app/ - name: ๐Ÿ“‚ Set up PROD Google Services uses: davidSchuppa/base64Secret-toFile-action@v3 with: secret: ${{ env.CI_PRODUCTION_GOOGLE_SERVICES_FILE }} filename: google-services.json destination-path: ./app/src/release/ - name: ๐Ÿ“‚ Copy PROD Google Services to releaseMarket run: | mkdir -p ./app/src/releaseMarket cp ./app/src/release/google-services.json ./app/src/releaseMarket/google-services.json - name: ๐Ÿ“‚ Copy PROD Google Services to releaseGithub run: | mkdir -p ./app/src/releaseGithub cp ./app/src/release/google-services.json ./app/src/releaseGithub/google-services.json - name: ๐Ÿ”ง Install dependencies uses: ./.github/workflows/install/ - name: ๐Ÿงช Run tests if: ${{ inputs.run-tests }} run: ./gradlew runTest - name: ๐Ÿ” Getting github sign key if: ${{ startsWith(inputs.keystore-file-name, 'github_key.jks') }} uses: timheuer/base64-to-file@v1.1 with: fileName: ${{ inputs.keystore-file-name }} fileDir: './app/' encodedString: ${{ env.CI_GITHUB_KEYSTORE_KEY_FILE }} - name: ๐Ÿ” Getting market sign key if: ${{ startsWith(inputs.keystore-file-name, 'market_key.jks') }} uses: timheuer/base64-to-file@v1.1 with: fileName: ${{ inputs.keystore-file-name }} fileDir: './app/' encodedString: ${{ env.CI_MARKET_KEY_FILE }} - name: ๐Ÿ— Build app if: ${{ !startsWith(inputs.gradlew-command, 'false') }} run: ./gradlew ${{ inputs.gradlew-command }} - name: ๐Ÿ— Build debug tests if: ${{ inputs.build-debug-tests }} run: ./gradlew assembleDebugAndroidTest - name: ๐Ÿงน Delete key after building if: ${{ !startsWith(inputs.keystore-file-name, 'false') }} run: rm ./app/${{ inputs.keystore-file-name }} - name: โžก๏ธ Upload build artifacts if: ${{ !startsWith(inputs.gradlew-command, 'false') }} uses: actions/upload-artifact@v4 with: name: ${{ inputs.upload-name }} path: app/build/outputs/apk/ if-no-files-found: ignore - name: โžก๏ธ Upload bundle artifacts if: ${{ !startsWith(inputs.gradlew-command, 'false') }} uses: actions/upload-artifact@v4 with: name: ${{ inputs.upload-name }}-bundle path: app/build/outputs/bundle/ if-no-files-found: ignore - name: โžก๏ธ Upload mapping file if: ${{ !startsWith(inputs.gradlew-command, 'false') }} uses: actions/upload-artifact@v4 with: name: ${{ inputs.upload-name }}-mapping path: app/build/outputs/mapping/ if-no-files-found: ignore - name: โžก๏ธ Upload native debug symbols if: ${{ !startsWith(inputs.gradlew-command, 'false') }} uses: actions/upload-artifact@v4 with: name: ${{ inputs.upload-name }}-native-debug-symbols path: app/build/outputs/native-debug-symbols/ if-no-files-found: ignore