name: Capacitor Android on: workflow_call: inputs: node-version: type: string default: '24.16.0' java-version: type: string default: '21' runner: type: string default: 'ubuntu-latest' build-type: description: 'debug | release' type: string default: 'debug' output-format: description: 'apk (sideload/test) | aab (Play Store)' type: string default: 'apk' secrets: NPM_TOKEN: required: false KEYSTORE_BASE64: required: false KEYSTORE_PASSWORD: required: false KEY_ALIAS: required: false KEY_PASSWORD: required: false GOOGLE_SERVICES_JSON: required: false jobs: android-build: runs-on: ${{ inputs.runner }} steps: - name: Checkout uses: https://gitea.com/actions/checkout@v6 - name: Setup Node.js uses: https://gitea.com/actions/setup-node@v4 with: node-version: ${{ inputs.node-version || '24.16.0' }} - name: Setup Java uses: https://github.com/actions/setup-java@v4 with: distribution: temurin java-version: ${{ inputs.java-version || '17' }} - name: Setup Android SDK uses: https://github.com/android-actions/setup-android@v4 - name: Cache npm uses: https://github.com/actions/cache@v4 with: path: ~/.npm key: ${{ runner.os }}-node-${{ hashFiles('**/package-lock.json') }} restore-keys: | ${{ runner.os }}-node- - name: Cache Gradle uses: https://github.com/actions/cache@v4 with: path: | ~/.gradle/caches ~/.gradle/wrapper key: ${{ runner.os }}-gradle-${{ hashFiles('**/*.gradle*', '**/gradle-wrapper.properties') }} restore-keys: | ${{ runner.os }}-gradle- - name: Configure npm private registry run: | echo "@pzeta:registry=https://gitea.pzetatouch.it/api/packages/pzeta_touch/npm/" >> ~/.npmrc echo "//gitea.pzetatouch.it/api/packages/pzeta_touch/npm/:_authToken=${{ secrets.NPM_TOKEN }}" >> ~/.npmrc - name: Read app info from package.json id: app-info run: | echo "name=$(node -e \"console.log(require('./package.json').name)\")" >> $GITHUB_OUTPUT echo "version=$(node -e \"console.log(require('./package.json').version)\")" >> $GITHUB_OUTPUT - name: Install dependencies run: npm ci - name: Build web app run: npm run build - name: Add Android platform run: npx cap add android || true - name: Sync Capacitor run: npx cap sync android - name: Setup google-services.json if: secrets.GOOGLE_SERVICES_JSON != '' run: echo '${{ secrets.GOOGLE_SERVICES_JSON }}' > android/app/google-services.json - name: Setup release keystore if: inputs.build-type == 'release' run: echo '${{ secrets.KEYSTORE_BASE64 }}' | base64 -d > android/app/keystore.jks - name: Build Android (APK) if: inputs.output-format == 'apk' working-directory: android env: KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} KEY_ALIAS: ${{ secrets.KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} run: | if [ "${{ inputs.build-type }}" = "release" ]; then ./gradlew assembleRelease else ./gradlew assembleDebug fi - name: Rename APK if: inputs.output-format == 'apk' run: | APP="${{ steps.app-info.outputs.name }}-${{ steps.app-info.outputs.version }}-${{ inputs.build-type }}" APK_DIR="android/app/build/outputs/apk/${{ inputs.build-type }}" mv "$APK_DIR"/app-${{ inputs.build-type }}.apk "$APK_DIR/${APP}.apk" 2>/dev/null || \ mv "$APK_DIR"/app-${{ inputs.build-type }}-unsigned.apk "$APK_DIR/${APP}.apk" 2>/dev/null || \ find "$APK_DIR" -name "*.apk" ! -name "${APP}.apk" -exec mv {} "$APK_DIR/${APP}.apk" \; - name: Build Android (AAB) if: inputs.output-format == 'aab' working-directory: android env: KEYSTORE_PASSWORD: ${{ secrets.KEYSTORE_PASSWORD }} KEY_ALIAS: ${{ secrets.KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.KEY_PASSWORD }} run: ./gradlew bundleRelease - name: Rename AAB if: inputs.output-format == 'aab' run: | APP="${{ steps.app-info.outputs.name }}-${{ steps.app-info.outputs.version }}-release" AAB_DIR="android/app/build/outputs/bundle/release" find "$AAB_DIR" -name "*.aab" ! -name "${APP}.aab" -exec mv {} "$AAB_DIR/${APP}.aab" \; - name: Upload APK artifact if: inputs.output-format == 'apk' uses: https://github.com/actions/upload-artifact@v4 with: name: ${{ steps.app-info.outputs.name }}-${{ steps.app-info.outputs.version }}-${{ inputs.build-type }}-apk path: android/app/build/outputs/apk/${{ inputs.build-type }}/${{ steps.app-info.outputs.name }}-${{ steps.app-info.outputs.version }}-${{ inputs.build-type }}.apk retention-days: 14 - name: Upload AAB artifact if: inputs.output-format == 'aab' uses: https://github.com/actions/upload-artifact@v4 with: name: ${{ steps.app-info.outputs.name }}-${{ steps.app-info.outputs.version }}-release-aab path: android/app/build/outputs/bundle/release/${{ steps.app-info.outputs.name }}-${{ steps.app-info.outputs.version }}-release.aab retention-days: 14 - name: Upload Gradle build reports if: always() uses: https://github.com/actions/upload-artifact@v4 with: name: gradle-build-reports path: android/build/reports/ retention-days: 7 if-no-files-found: ignore