Skip to content

Automate Android release signing and Google Play upload - #225

Merged
richardthe3rd merged 6 commits into
mainfrom
claude/automate-android-releases-AHsnq
May 9, 2026
Merged

Automate Android release signing and Google Play upload#225
richardthe3rd merged 6 commits into
mainfrom
claude/automate-android-releases-AHsnq

Conversation

@richardthe3rd

Copy link
Copy Markdown
Owner
  • Add upload keystore signing to build.gradle via key.properties pattern
    (falls back to debug signing locally when key.properties is absent)
  • Inject ANDROID_KEYSTORE_BASE64 / key.properties in CI before the build
  • Add publish-google-play job that uploads the signed AAB to Internal track
    using r0adkll/upload-google-play and a Google Play service account secret
  • Drop "unsigned" suffix from release artifact filenames
  • Update release notes to reflect Play App Signing model

Required new secrets: ANDROID_KEYSTORE_BASE64, ANDROID_KEYSTORE_PASSWORD,
ANDROID_KEY_PASSWORD, ANDROID_KEY_ALIAS, GOOGLE_PLAY_SERVICE_ACCOUNT_JSON

https://claude.ai/code/session_01LRvsZuXFafSSFLZrcB53fz

claude added 4 commits May 3, 2026 20:50
- Add upload keystore signing to build.gradle via key.properties pattern
  (falls back to debug signing locally when key.properties is absent)
- Inject ANDROID_KEYSTORE_BASE64 / key.properties in CI before the build
- Add publish-google-play job that uploads the signed AAB to Internal track
  using r0adkll/upload-google-play and a Google Play service account secret
- Drop "unsigned" suffix from release artifact filenames
- Update release notes to reflect Play App Signing model

Required new secrets: ANDROID_KEYSTORE_BASE64, ANDROID_KEYSTORE_PASSWORD,
ANDROID_KEY_PASSWORD, ANDROID_KEY_ALIAS, GOOGLE_PLAY_SERVICE_ACCOUNT_JSON

https://claude.ai/code/session_01LRvsZuXFafSSFLZrcB53fz
- android-release.md: replace "future" signing section with current
  implementation; update artifact names (drop -unsigned suffix); update
  step 4 to mention automated Google Play upload
- github-secrets.md: add Android keystore secrets (ANDROID_KEYSTORE_BASE64,
  ANDROID_KEY_ALIAS, ANDROID_KEY_PASSWORD, ANDROID_KEYSTORE_PASSWORD) and
  Google Play service account secret with full setup walkthrough
- ci-cd.md: add Release Android workflow to overview and secrets tables;
  update production release flow to include Play promotion step
- play-store.md: update Quick Start to reflect automated upload via CI;
  add CI secrets to submission checklist; note first upload must be manual

https://claude.ai/code/session_01LRvsZuXFafSSFLZrcB53fz
- Fail fast with a clear error message if ANDROID_KEYSTORE_BASE64 is unset,
  rather than silently producing an unsigned build that Play rejects
- Replace heredoc in key.properties creation with printf to avoid any
  leading-whitespace ambiguity from YAML indentation
- Add prominent warning in android-release.md and play-store.md that the
  Google Play API cannot create a new app listing: first AAB must be
  uploaded manually through Play Console before CI automation kicks in

https://claude.ai/code/session_01LRvsZuXFafSSFLZrcB53fz
The Flutter app replaces an existing self-signed APK app (ralcock.cbf).
For a seamless upgrade, the original signing keystore must be enrolled in
Play App Signing as the app signing key before any CI upload runs.

- android-release.md: replace generic "First-Time Setup" / "Updating an
  Existing App" with a concrete migration guide: version code check,
  pepk-based Play App Signing enrollment, first manual AAB upload, then
  automated CI flow for all subsequent releases
- android-release.md: fix stale package name placeholder → ralcock.cbf
- github-secrets.md: clarify that ANDROID_KEYSTORE_BASE64 must be the
  *original* signing keystore for an existing app (not a newly generated
  one), with a callout explaining why
- play-store.md: replace "new app" Quick Start with a "replacing existing
  app" flow including the pre-migration checklist and version code check;
  fix package name placeholder → ralcock.cbf

https://claude.ai/code/session_01LRvsZuXFafSSFLZrcB53fz
Copilot AI review requested due to automatic review settings May 3, 2026 21:04
@github-actions

github-actions Bot commented May 3, 2026

Copy link
Copy Markdown
Contributor

LCOV of commit eda7070 during CI #68

Summary coverage rate:
  lines......: 77.7% (2242 of 2887 lines)
  functions..: no data found
  branches...: no data found

Files changed coverage rate: n/a

@codecov

codecov Bot commented May 3, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.

📢 Thoughts on this report? Let us know!

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR adds Android release-signing and Google Play upload automation to the existing release pipeline, extending the app’s deployment tooling beyond the current web-focused release flow. It wires CI secrets into the Android build, updates Gradle signing behavior, and refreshes the operational docs to describe Play App Signing and Play Console release handling.

Changes:

  • Add release signing support in android/app/build.gradle using android/key.properties, with a local fallback to debug signing when no keystore is configured.
  • Extend release-android.yml to decode the upload keystore in CI, build signed APK/AAB artifacts, rename release outputs, and upload the AAB to Google Play Internal testing.
  • Update Android/Play Store/CI documentation to describe the new secrets, Play App Signing migration, and the intended first-release/manual-upload workflow.

Reviewed changes

Copilot reviewed 6 out of 6 changed files in this pull request and generated 6 comments.

Show a summary per file
File Description
docs/tooling/play-store.md Updates Play Store setup guidance for replacing the existing Android app and documents the manual first-upload flow.
docs/tooling/github-secrets.md Expands GitHub Actions secret setup to include Android signing and Google Play service account credentials.
docs/tooling/android-release.md Revises Android release docs for signed artifacts, Play App Signing, and CI-driven Play uploads.
docs/processes/ci-cd.md Documents the new Android release workflow and its required secrets/manual promotion steps.
android/app/build.gradle Adds key.properties-based release signing configuration with a debug-signing fallback for local builds.
.github/workflows/release-android.yml Injects signing material, builds signed Android artifacts, creates release assets, and uploads AABs to Google Play.

Comment on lines +477 to +481
Every push of a `v*` tag will automatically:
1. Build the signed AAB
2. Upload it to the **Internal track** in Play Console
3. The release appears immediately for internal testers

Comment thread docs/tooling/play-store.md Outdated
Comment on lines +309 to +315
> For the **very first Flutter release** you must upload manually:
> 1. Wait for the GitHub Actions `Release Android` workflow to complete
> 2. Download the AAB from the GitHub Release
> 3. In Play Console → **Internal testing** → **Create new release** → upload the AAB
> 4. Submit and confirm testers can install
>
> From the **second release onwards**, CI uploads to Internal track automatically.
Comment on lines +111 to +118
- name: Create key.properties
run: |
printf 'storePassword=%s\nkeyPassword=%s\nkeyAlias=%s\nstoreFile=%s\n' \
"${{ secrets.ANDROID_KEYSTORE_PASSWORD }}" \
"${{ secrets.ANDROID_KEY_PASSWORD }}" \
"${{ secrets.ANDROID_KEY_ALIAS }}" \
"../upload-keystore.jks" \
> android/key.properties
Comment on lines +225 to +232
- name: Upload to Google Play (Internal track)
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
packageName: ralcock.cbf
releaseFiles: artifacts/aab/app-release.aab
track: internal
status: completed
Comment on lines +225 to +232
- name: Upload to Google Play (Internal track)
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJsonPlainText: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_JSON }}
packageName: ralcock.cbf
releaseFiles: artifacts/aab/app-release.aab
track: internal
status: completed
Comment thread docs/tooling/android-release.md Outdated
Comment on lines +650 to +658
### One-Time Setup: Create the Upload Keystore

**Go to**: Repository Settings → Secrets and variables → Actions → New repository secret
Run this once locally and store the `.jks` file somewhere safe (password manager, etc.):

| Secret Name | Description | How to Get |
|-------------|-------------|------------|
| `KEYSTORE_BASE64` | Base64-encoded keystore file | `base64 -i upload-keystore.jks \| tr -d '\n'` |
| `KEYSTORE_PASSWORD` | Keystore password | The password you used when creating the keystore |
| `KEY_ALIAS` | Key alias | Usually `upload` (or whatever you specified) |
| `KEY_PASSWORD` | Key password | Usually same as keystore password |
```bash
keytool -genkey -v -keystore upload-keystore.jks \
-keyalg RSA -keysize 2048 -validity 10000 \
-alias upload
```
Workflow fixes:
- Validate all four signing secrets upfront (not just ANDROID_KEYSTORE_BASE64)
  so missing secrets produce clear error messages rather than cryptic Gradle failures
- Gate publish-google-play to tag pushes only (if: push + refs/tags/v*) so
  workflow_dispatch test runs cannot accidentally ship untagged builds to testers
- Add continue-on-error: true to publish-google-play so the first tag push
  (before the app listing exists in Play Console) fails gracefully rather than
  marking the whole workflow as failed

Doc fixes:
- android-release.md: replace keytool -genkey instruction with a callout
  directing readers to use the original signing keystore (generating a new one
  would break the seamless upgrade path for existing ralcock.cbf users)
- github-secrets.md: add first-manual-upload caveat to "What happens when
  it's configured" section
- play-store.md: clarify that the workflow succeeds on first run but skips
  the Play upload step until the app listing exists

https://claude.ai/code/session_01LRvsZuXFafSSFLZrcB53fz
@github-actions

github-actions Bot commented May 3, 2026

Copy link
Copy Markdown
Contributor

🚀 Cloudflare Pages Preview

Your preview deployment is ready!

Preview URL: https://claude-automate-android-rele.staging-cambeerfestival.pages.dev

This preview will be automatically updated when you push new commits to this PR.

…nterpolation

Prevents issues with shell metacharacters (e.g. % in printf, special chars
in base64 decode) by binding secrets to environment variables rather than
expanding them directly into the shell script.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
@github-actions

github-actions Bot commented May 9, 2026

Copy link
Copy Markdown
Contributor

🚀 Cloudflare Pages Preview

Your preview deployment is ready!

Preview URL: https://claude-automate-android-rele.staging-cambeerfestival.pages.dev

This preview will be automatically updated when you push new commits to this PR.

@richardthe3rd
richardthe3rd merged commit 1871b46 into main May 9, 2026
10 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants