diff --git a/.github/workflows/flutter-build.yml b/.github/workflows/flutter-build.yml index 198a2ea41..15bcfbe08 100644 --- a/.github/workflows/flutter-build.yml +++ b/.github/workflows/flutter-build.yml @@ -2,6 +2,10 @@ name: Flutter Mobile Build on: workflow_call: + outputs: + has_app_release_aab: + description: "Whether a signed release AAB artifact was produced" + value: ${{ jobs.build-android.outputs.has_app_release_aab }} workflow_dispatch: permissions: @@ -12,6 +16,8 @@ jobs: name: Build Android APK runs-on: ubuntu-latest timeout-minutes: 30 + outputs: + has_app_release_aab: ${{ steps.check_secrets.outputs.has_keystore }} steps: - name: Checkout code diff --git a/.github/workflows/google-play-upload.yml b/.github/workflows/google-play-upload.yml new file mode 100644 index 000000000..14e63eb15 --- /dev/null +++ b/.github/workflows/google-play-upload.yml @@ -0,0 +1,108 @@ +name: Google Play Upload + +on: + workflow_call: + inputs: + notes: + description: "Google Play release notes" + required: false + type: string + track: + description: "Google Play track (internal, alpha, beta, production)" + required: false + default: "internal" + type: string + secrets: + GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_BASE64: + required: false + +permissions: + contents: read + +jobs: + upload: + name: Upload Android AAB to Google Play + runs-on: ubuntu-latest + timeout-minutes: 30 + + steps: + - name: Check Google Play credentials + id: check_prereqs + env: + GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_BASE64: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_BASE64 }} + run: | + set -eu + + missing=() + if [ -z "${GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_BASE64-}" ]; then + missing+=("GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_BASE64") + fi + + if [ "${#missing[@]}" -eq 0 ]; then + echo "enabled=true" >> "$GITHUB_OUTPUT" + exit 0 + fi + + echo "enabled=false" >> "$GITHUB_OUTPUT" + { + echo "Missing required Google Play secrets:" + printf " - %s\n" "${missing[@]}" + } >> "$GITHUB_STEP_SUMMARY" + + - name: Skip Google Play upload + if: ${{ steps.check_prereqs.outputs.enabled != 'true' }} + run: | + echo "Skipping Google Play upload because required credentials are not configured." + + - name: Download Android AAB artifact + if: ${{ steps.check_prereqs.outputs.enabled == 'true' }} + uses: actions/download-artifact@v4.3.0 + with: + name: app-release-aab + path: ${{ runner.temp }}/android-aab + + - name: Prepare Google Play credentials + id: play_creds + if: ${{ steps.check_prereqs.outputs.enabled == 'true' }} + env: + GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_BASE64: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_BASE64 }} + run: | + set -euo pipefail + CREDENTIALS_PATH="$RUNNER_TEMP/google-play-service-account.json" + echo "$GOOGLE_PLAY_SERVICE_ACCOUNT_JSON_BASE64" | base64 --decode > "$CREDENTIALS_PATH" + echo "credentials-path=$CREDENTIALS_PATH" >> "$GITHUB_OUTPUT" + + - name: Resolve AAB path + id: aab + if: ${{ steps.check_prereqs.outputs.enabled == 'true' }} + run: | + set -euo pipefail + AAB_PATH="$(find "${{ runner.temp }}/android-aab" -name '*.aab' | head -n 1)" + if [ -z "$AAB_PATH" ]; then + echo "::error::No Android App Bundle (.aab) found in downloaded artifacts" + exit 1 + fi + echo "aab-path=$AAB_PATH" >> "$GITHUB_OUTPUT" + + - name: Create release notes file + id: notes + if: ${{ steps.check_prereqs.outputs.enabled == 'true' && inputs.notes != '' }} + env: + NOTES: ${{ inputs.notes }} + run: | + set -euo pipefail + NOTES_DIR="$RUNNER_TEMP/google-play-whatsnew" + mkdir -p "$NOTES_DIR" + printf '%s\n' "$NOTES" > "$NOTES_DIR/whatsnew-en-US" + echo "notes-dir=$NOTES_DIR" >> "$GITHUB_OUTPUT" + + - name: Upload to Google Play + if: ${{ steps.check_prereqs.outputs.enabled == 'true' }} + uses: r0adkll/upload-google-play@v1 + with: + serviceAccountJson: ${{ steps.play_creds.outputs.credentials-path }} + packageName: am.sure.mobile + releaseFiles: ${{ steps.aab.outputs.aab-path }} + tracks: ${{ inputs.track }} + status: completed + whatsNewDirectory: ${{ steps.notes.outputs.notes-dir }} diff --git a/.github/workflows/mobile-release.yml b/.github/workflows/mobile-release.yml index 5de88a6d3..b07959fbb 100644 --- a/.github/workflows/mobile-release.yml +++ b/.github/workflows/mobile-release.yml @@ -71,6 +71,16 @@ jobs: uses: ./.github/workflows/flutter-build.yml secrets: inherit + play-store: + name: Upload Android to Google Play + if: ${{ needs.build.outputs.has_app_release_aab == 'true' }} + needs: [build, prepare_release] + uses: ./.github/workflows/google-play-upload.yml + with: + notes: "Mobile release ${{ needs.prepare_release.outputs.tag_name }}" + track: internal + secrets: inherit + testflight: name: Upload iOS to TestFlight needs: [build, release]