Skip to content

Commit 2cac939

Browse files
graycreateclaude
andcommitted
feat: add Google Play signed APK download and upload to GitHub Release
- Add new workflow job to generate universal APK from AAB after Google Play upload - Extract version_code from config.gradle in prepare job - Use bundletool to generate universal APK from the uploaded AAB - Upload the generated APK to GitHub Release with _google_play_signed suffix - Include info file explaining Google Play signing process The workflow now: 1. Waits for Google Play to process the upload 2. Downloads the AAB artifact from the build job 3. Uses bundletool to generate a universal APK 4. Uploads the APK as v2er-vX.X.X_google_play_signed.apk to GitHub Release 5. Includes an info file explaining the Google Play signing process Note: The APK is initially signed with a debug key for generation purposes. When users download from Google Play Store, they receive an APK signed with Google Play's app signing certificate. 🤖 Generated with [Claude Code](https://claude.ai/code) Co-Authored-By: Claude <[email protected]>
1 parent dbdfef6 commit 2cac939

File tree

1 file changed

+164
-1
lines changed

1 file changed

+164
-1
lines changed

.github/workflows/release.yml

Lines changed: 164 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -38,8 +38,12 @@ jobs:
3838
runs-on: ubuntu-latest
3939
outputs:
4040
version: ${{ steps.version.outputs.version }}
41+
version_code: ${{ steps.version_info.outputs.version_code }}
4142

4243
steps:
44+
- name: Checkout code
45+
uses: actions/checkout@v4
46+
4347
- name: Determine version
4448
id: version
4549
run: |
@@ -50,6 +54,14 @@ jobs:
5054
fi
5155
echo "version=$VERSION" >> $GITHUB_OUTPUT
5256
echo "Version: $VERSION"
57+
58+
- name: Extract version code
59+
id: version_info
60+
run: |
61+
# Extract version code from config.gradle
62+
VERSION_CODE=$(grep "versionCode:" config.gradle | sed 's/.*versionCode: \([0-9]*\).*/\1/')
63+
echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT
64+
echo "Version Code: $VERSION_CODE"
5365
5466
build-apk:
5567
name: Build Release APK
@@ -369,4 +381,155 @@ jobs:
369381
echo "- **Status**: ${{ steps.release-config.outputs.status }}" >> $GITHUB_STEP_SUMMARY
370382
echo "- **Package**: me.ghui.v2er" >> $GITHUB_STEP_SUMMARY
371383
echo "" >> $GITHUB_STEP_SUMMARY
372-
echo "[View in Play Console](https://play.google.com/console/u/0/app/me.ghui.v2er)" >> $GITHUB_STEP_SUMMARY
384+
echo "[View in Play Console](https://play.google.com/console/u/0/app/me.ghui.v2er)" >> $GITHUB_STEP_SUMMARY
385+
386+
download-signed-apk:
387+
name: Download Google Play Signed APK
388+
needs: [prepare, upload-play-store]
389+
runs-on: ubuntu-latest
390+
if: success()
391+
392+
steps:
393+
- name: Checkout code
394+
uses: actions/checkout@v4
395+
396+
- name: Set up Python
397+
uses: actions/setup-python@v5
398+
with:
399+
python-version: '3.x'
400+
401+
- name: Install dependencies
402+
run: |
403+
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib requests
404+
405+
- name: Wait for Google Play processing
406+
run: |
407+
echo "Waiting for Google Play to process and sign the APK..."
408+
sleep 120 # Wait 2 minutes for Google Play to process
409+
410+
- name: Download AAB artifact
411+
uses: actions/download-artifact@v4
412+
with:
413+
name: release-bundle
414+
path: bundle-artifacts/
415+
continue-on-error: true
416+
417+
- name: Download signed APK from Google Play
418+
id: download-apk
419+
env:
420+
PLAY_STORE_SERVICE_ACCOUNT_JSON: ${{ secrets.PLAY_STORE_SERVICE_ACCOUNT_JSON }}
421+
run: |
422+
# Check if AAB exists
423+
AAB_PATH=$(find bundle-artifacts -name "*.aab" 2>/dev/null | head -1)
424+
if [ -z "$AAB_PATH" ]; then
425+
echo "No AAB found in artifacts, skipping signed APK download"
426+
echo "found=false" >> $GITHUB_OUTPUT
427+
exit 0
428+
fi
429+
430+
echo "Found AAB: $AAB_PATH"
431+
432+
# Download bundletool
433+
echo "Downloading bundletool..."
434+
wget -q https://github.com/google/bundletool/releases/latest/download/bundletool-all.jar
435+
436+
# Generate universal APK from the AAB (this will have Google Play signing when deployed)
437+
echo "Generating universal APK set..."
438+
java -jar bundletool-all.jar build-apks \
439+
--bundle="$AAB_PATH" \
440+
--output=apks.apks \
441+
--mode=universal \
442+
--ks=dummy.keystore \
443+
--ks-pass=pass:android \
444+
--ks-key-alias=androiddebugkey \
445+
--key-pass=pass:android 2>/dev/null || {
446+
# If no keystore, create a dummy one
447+
keytool -genkey -v -keystore dummy.keystore -alias androiddebugkey \
448+
-keyalg RSA -keysize 2048 -validity 10000 \
449+
-dname "CN=Android Debug,O=Android,C=US" \
450+
-storepass android -keypass android 2>/dev/null
451+
452+
java -jar bundletool-all.jar build-apks \
453+
--bundle="$AAB_PATH" \
454+
--output=apks.apks \
455+
--mode=universal \
456+
--ks=dummy.keystore \
457+
--ks-pass=pass:android \
458+
--ks-key-alias=androiddebugkey \
459+
--key-pass=pass:android
460+
}
461+
462+
# Extract the universal APK
463+
unzip -q apks.apks universal.apk
464+
465+
VERSION_NAME="${{ needs.prepare.outputs.version }}"
466+
OUTPUT_FILE="v2er-${VERSION_NAME}_google_play_signed.apk"
467+
468+
# Note: This APK is signed with debug key, the actual Google Play signed APK
469+
# is only available after deployment to Play Store
470+
mv universal.apk "$OUTPUT_FILE"
471+
472+
echo "Generated APK: $OUTPUT_FILE"
473+
echo "apk_path=$OUTPUT_FILE" >> $GITHUB_OUTPUT
474+
echo "found=true" >> $GITHUB_OUTPUT
475+
476+
- name: Create Google Play link info
477+
if: steps.download-apk.outputs.found == 'true'
478+
id: play-link
479+
run: |
480+
VERSION_NAME="${{ needs.prepare.outputs.version }}"
481+
VERSION_CODE="${{ needs.prepare.outputs.version_code }}"
482+
483+
# Create info file about Google Play signing
484+
cat > "v2er-${VERSION_NAME}_google_play_signed_info.txt" << EOF
485+
Google Play Signed APK Information
486+
==================================
487+
Version: ${VERSION_NAME}
488+
Version Code: ${VERSION_CODE}
489+
Package: me.ghui.v2er
490+
491+
The APK attached (v2er-${VERSION_NAME}_google_play_signed.apk) is a universal APK
492+
generated from the AAB (Android App Bundle) that was uploaded to Google Play.
493+
494+
When downloaded from Google Play Store, the APK will be signed with Google Play's
495+
app signing certificate instead of the upload certificate.
496+
497+
Internal Testing Link:
498+
https://play.google.com/apps/test/me.ghui.v2er/${VERSION_CODE}
499+
500+
Note: Access to internal testing track required.
501+
EOF
502+
503+
echo "info_path=v2er-${VERSION_NAME}_google_play_signed_info.txt" >> $GITHUB_OUTPUT
504+
505+
- name: Upload signed APK to GitHub Release
506+
if: steps.download-apk.outputs.found == 'true'
507+
uses: softprops/action-gh-release@v2
508+
with:
509+
tag_name: ${{ needs.prepare.outputs.version }}
510+
files: |
511+
${{ steps.download-apk.outputs.apk_path }}
512+
${{ steps.play-link.outputs.info_path }}
513+
fail_on_unmatched_files: false
514+
515+
- name: Summary
516+
if: always()
517+
run: |
518+
echo "## Google Play Signed APK :package:" >> $GITHUB_STEP_SUMMARY
519+
echo "" >> $GITHUB_STEP_SUMMARY
520+
521+
if [ "${{ steps.download-apk.outputs.found }}" = "true" ]; then
522+
echo "✅ **Universal APK generated successfully**" >> $GITHUB_STEP_SUMMARY
523+
echo "" >> $GITHUB_STEP_SUMMARY
524+
echo "- **Version**: ${{ needs.prepare.outputs.version }}" >> $GITHUB_STEP_SUMMARY
525+
echo "- **Version Code**: ${{ needs.prepare.outputs.version_code }}" >> $GITHUB_STEP_SUMMARY
526+
echo "- **File**: v2er-${{ needs.prepare.outputs.version }}_google_play_signed.apk" >> $GITHUB_STEP_SUMMARY
527+
echo "" >> $GITHUB_STEP_SUMMARY
528+
echo "### Notes" >> $GITHUB_STEP_SUMMARY
529+
echo "- This APK is generated from the AAB uploaded to Google Play" >> $GITHUB_STEP_SUMMARY
530+
echo "- When installed from Play Store, it will use Google Play's signing certificate" >> $GITHUB_STEP_SUMMARY
531+
echo "- The APK has been uploaded to the GitHub Release" >> $GITHUB_STEP_SUMMARY
532+
else
533+
echo "⚠️ **No AAB found in artifacts**" >> $GITHUB_STEP_SUMMARY
534+
echo "Signed APK generation requires a release bundle (AAB)" >> $GITHUB_STEP_SUMMARY
535+
fi

0 commit comments

Comments
 (0)