Add ping endpoint and latency tracking to PostHog (#16) #20
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Release APK | |
| on: | |
| workflow_dispatch: | |
| inputs: | |
| release_name: | |
| description: Override release name (defaults to tag or ref name). | |
| required: false | |
| play_track: | |
| description: Google Play release track (internal, alpha, beta, production). | |
| required: false | |
| default: internal | |
| type: choice | |
| options: | |
| - internal | |
| - alpha | |
| - beta | |
| - production | |
| push: | |
| branches: | |
| - main | |
| permissions: | |
| contents: write | |
| env: | |
| BUILD_TOOLS_VERSION: 35.0.0 | |
| RELEASE_BUNDLE_PATH: app/build/outputs/bundle/release/app-release.aab | |
| jobs: | |
| release: | |
| name: Build and Publish | |
| runs-on: ubuntu-latest | |
| steps: | |
| - name: Checkout repository | |
| uses: actions/checkout@v4 | |
| with: | |
| fetch-depth: 0 | |
| - name: Verify ref on main (workflow_dispatch) | |
| if: github.event_name == 'workflow_dispatch' | |
| run: | | |
| if [ "${GITHUB_REF}" != "refs/heads/main" ]; then | |
| echo "Workflow must target the main branch. Ref: ${GITHUB_REF}" >&2 | |
| exit 1 | |
| fi | |
| - name: Set up Java | |
| uses: actions/setup-java@v4 | |
| with: | |
| distribution: temurin | |
| java-version: 17 | |
| cache: gradle | |
| - name: Set up Android SDK | |
| uses: android-actions/setup-android@v3 | |
| - name: Accept Android SDK licenses and install packages | |
| run: | | |
| # Find sdkmanager in common locations | |
| if [ -f "$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" ]; then | |
| SDK_MANAGER="$ANDROID_HOME/cmdline-tools/latest/bin/sdkmanager" | |
| elif [ -f "$ANDROID_HOME/cmdline-tools/bin/sdkmanager" ]; then | |
| SDK_MANAGER="$ANDROID_HOME/cmdline-tools/bin/sdkmanager" | |
| elif [ -f "$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" ]; then | |
| SDK_MANAGER="$ANDROID_SDK_ROOT/cmdline-tools/latest/bin/sdkmanager" | |
| else | |
| echo "Error: sdkmanager not found" | |
| exit 1 | |
| fi | |
| echo "Using sdkmanager at: $SDK_MANAGER" | |
| # Accept all licenses first | |
| yes | "$SDK_MANAGER" --licenses | |
| # Install packages separately (as per Stack Overflow solution) | |
| # Install platform-tools first | |
| yes | "$SDK_MANAGER" "platform-tools" | |
| # Install Android API 35 | |
| yes | "$SDK_MANAGER" "platforms;android-35" | |
| # Install build-tools | |
| yes | "$SDK_MANAGER" "build-tools;${{ env.BUILD_TOOLS_VERSION }}" | |
| # Install Android API 36 | |
| yes | "$SDK_MANAGER" "platforms;android-36" | |
| - name: Cache Gradle | |
| uses: gradle/actions/setup-gradle@v4 | |
| - name: Grant execute permission for Gradle wrapper | |
| run: chmod +x gradlew | |
| - name: Auto-increment version code from Google Play | |
| continue-on-error: true | |
| env: | |
| GOOGLE_PLAY_SERVICE_ACCOUNT_JSON: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} | |
| run: | | |
| if [ -z "$GOOGLE_PLAY_SERVICE_ACCOUNT_JSON" ]; then | |
| echo "Google Play service account not configured, skipping version code check" | |
| exit 0 | |
| fi | |
| # Write service account JSON to file | |
| echo "$GOOGLE_PLAY_SERVICE_ACCOUNT_JSON" > /tmp/service_account.json | |
| # Install Python dependencies | |
| python3 -m pip install --quiet google-api-python-client google-auth-httplib2 google-auth-oauthlib | |
| # Run the version code increment script | |
| python3 scripts/increment_version_code.py | |
| - name: Build release bundle | |
| run: ./gradlew bundleRelease | |
| - name: Decode keystore | |
| run: | | |
| if [ -z "${{ secrets.ANDROID_SIGNING_KEYSTORE_BASE64 }}" ]; then | |
| echo "ERROR: ANDROID_SIGNING_KEYSTORE_BASE64 secret is missing. Signing secrets are required for release builds." >&2 | |
| exit 1 | |
| fi | |
| echo "${{ secrets.ANDROID_SIGNING_KEYSTORE_BASE64 }}" | base64 --decode > release.keystore | |
| if [ ! -f "release.keystore" ] || [ ! -s "release.keystore" ]; then | |
| echo "ERROR: Failed to decode keystore. The secret may be invalid." >&2 | |
| exit 1 | |
| fi | |
| - name: Sign AAB | |
| env: | |
| KEY_ALIAS: ${{ secrets.ANDROID_SIGNING_KEY_ALIAS }} | |
| KEY_PASSWORD: ${{ secrets.ANDROID_SIGNING_KEY_PASSWORD }} | |
| STORE_PASSWORD: ${{ secrets.ANDROID_SIGNING_KEYSTORE_PASSWORD }} | |
| run: | | |
| # Validate all signing secrets are present | |
| if [ -z "$KEY_ALIAS" ] || [ -z "$KEY_PASSWORD" ] || [ -z "$STORE_PASSWORD" ]; then | |
| echo "ERROR: One or more signing secrets are missing:" >&2 | |
| echo " - ANDROID_SIGNING_KEY_ALIAS: $([ -z "$KEY_ALIAS" ] && echo 'MISSING' || echo 'present')" >&2 | |
| echo " - ANDROID_SIGNING_KEY_PASSWORD: $([ -z "$KEY_PASSWORD" ] && echo 'MISSING' || echo 'present')" >&2 | |
| echo " - ANDROID_SIGNING_KEYSTORE_PASSWORD: $([ -z "$STORE_PASSWORD" ] && echo 'MISSING' || echo 'present')" >&2 | |
| exit 1 | |
| fi | |
| if [ ! -f "release.keystore" ]; then | |
| echo "ERROR: Keystore file not found. Decode keystore step must have failed." >&2 | |
| exit 1 | |
| fi | |
| AAB_PATH=$(ls app/build/outputs/bundle/release/*.aab | head -n 1) | |
| if [ -z "$AAB_PATH" ]; then | |
| echo "ERROR: No AAB produced at app/build/outputs/bundle/release." >&2 | |
| exit 1 | |
| fi | |
| # Sign AAB using jarsigner | |
| jarsigner -verbose -sigalg SHA256withRSA -digestalg SHA-256 \ | |
| -keystore release.keystore \ | |
| -storepass "$STORE_PASSWORD" \ | |
| -keypass "$KEY_PASSWORD" \ | |
| "$AAB_PATH" \ | |
| "$KEY_ALIAS" | |
| # Verify the signature | |
| jarsigner -verify -verbose -certs "$AAB_PATH" | |
| if [ $? -ne 0 ]; then | |
| echo "ERROR: Signature verification failed." >&2 | |
| exit 1 | |
| fi | |
| echo "✓ AAB signed and verified successfully" | |
| - name: Set release variables | |
| id: release_vars | |
| run: | | |
| if [ "${{ github.event_name }}" = "workflow_dispatch" ]; then | |
| echo "play_track=${{ github.event.inputs.play_track || 'internal' }}" >> $GITHUB_OUTPUT | |
| echo "release_name=${{ github.event.inputs.release_name || github.ref_name }}" >> $GITHUB_OUTPUT | |
| else | |
| # Automatic upload to internal track for main branch pushes | |
| echo "play_track=internal" >> $GITHUB_OUTPUT | |
| echo "release_name=main-${GITHUB_SHA::7}" >> $GITHUB_OUTPUT | |
| fi | |
| - name: Upload release artifact | |
| uses: actions/upload-artifact@v4 | |
| with: | |
| name: release-bundle | |
| path: app/build/outputs/bundle/release/*.aab | |
| - name: Upload to Google Play Console | |
| continue-on-error: true | |
| uses: r0adkll/upload-google-play@v1 | |
| with: | |
| serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }} | |
| packageName: llc.fungee.IngrediCheck | |
| releaseFiles: app/build/outputs/bundle/release/*.aab | |
| track: ${{ steps.release_vars.outputs.play_track }} | |
| status: completed | |