Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
165 changes: 164 additions & 1 deletion .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,12 @@ jobs:
runs-on: ubuntu-latest
outputs:
version: ${{ steps.version.outputs.version }}
version_code: ${{ steps.version_info.outputs.version_code }}

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Determine version
id: version
run: |
Expand All @@ -50,6 +54,14 @@ jobs:
fi
echo "version=$VERSION" >> $GITHUB_OUTPUT
echo "Version: $VERSION"

- name: Extract version code
id: version_info
run: |
# Extract version code from config.gradle
VERSION_CODE=$(grep "versionCode:" config.gradle | sed 's/.*versionCode: \([0-9]*\).*/\1/')
echo "version_code=$VERSION_CODE" >> $GITHUB_OUTPUT
echo "Version Code: $VERSION_CODE"

build-apk:
name: Build Release APK
Expand Down Expand Up @@ -369,4 +381,155 @@ jobs:
echo "- **Status**: ${{ steps.release-config.outputs.status }}" >> $GITHUB_STEP_SUMMARY
echo "- **Package**: me.ghui.v2er" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "[View in Play Console](https://play.google.com/console/u/0/app/me.ghui.v2er)" >> $GITHUB_STEP_SUMMARY
echo "[View in Play Console](https://play.google.com/console/u/0/app/me.ghui.v2er)" >> $GITHUB_STEP_SUMMARY

download-signed-apk:
name: Download Google Play Signed APK
needs: [prepare, upload-play-store]
Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

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

The job dependency references upload-play-store but the actual job name is play-store-upload. This will cause the workflow to fail as it cannot find the referenced job.

Suggested change
needs: [prepare, upload-play-store]
needs: [prepare, play-store-upload]

Copilot uses AI. Check for mistakes.
runs-on: ubuntu-latest
if: success()

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.x'

- name: Install dependencies
run: |
pip install google-api-python-client google-auth-httplib2 google-auth-oauthlib requests

- name: Wait for Google Play processing
run: |
echo "Waiting for Google Play to process and sign the APK..."
sleep 120 # Wait 2 minutes for Google Play to process
Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

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

[nitpick] The hardcoded 2-minute sleep is arbitrary and may not be sufficient for all cases. Consider making this configurable via workflow input or implementing a polling mechanism to check when processing is complete.

Copilot uses AI. Check for mistakes.

- name: Download AAB artifact
uses: actions/download-artifact@v4
with:
name: release-bundle
path: bundle-artifacts/
continue-on-error: true

- name: Download signed APK from Google Play
id: download-apk
env:
PLAY_STORE_SERVICE_ACCOUNT_JSON: ${{ secrets.PLAY_STORE_SERVICE_ACCOUNT_JSON }}
run: |
# Check if AAB exists
AAB_PATH=$(find bundle-artifacts -name "*.aab" 2>/dev/null | head -1)
if [ -z "$AAB_PATH" ]; then
echo "No AAB found in artifacts, skipping signed APK download"
echo "found=false" >> $GITHUB_OUTPUT
exit 0
fi

echo "Found AAB: $AAB_PATH"

# Download bundletool
echo "Downloading bundletool..."
wget -q https://github.com/google/bundletool/releases/latest/download/bundletool-all.jar

# Generate universal APK from the AAB (this will have Google Play signing when deployed)
echo "Generating universal APK set..."
java -jar bundletool-all.jar build-apks \
--bundle="$AAB_PATH" \
--output=apks.apks \
--mode=universal \
--ks=dummy.keystore \
--ks-pass=pass:android \
--ks-key-alias=androiddebugkey \
--key-pass=pass:android 2>/dev/null || {
Comment on lines +442 to +445
Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

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

Using hardcoded passwords ('android') and the debug keystore alias 'androiddebugkey' poses a security risk. Even though this is temporary signing for bundletool, consider using generated random passwords or environment variables to avoid exposing credentials in logs.

Copilot uses AI. Check for mistakes.
# If no keystore, create a dummy one
keytool -genkey -v -keystore dummy.keystore -alias androiddebugkey \
-keyalg RSA -keysize 2048 -validity 10000 \
-dname "CN=Android Debug,O=Android,C=US" \
-storepass android -keypass android 2>/dev/null
Comment on lines +447 to +450
Copy link

Copilot AI Sep 9, 2025

Choose a reason for hiding this comment

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

The keytool command uses hardcoded passwords ('android') which will be visible in workflow logs. Consider using generated passwords or environment variables to avoid credential exposure.

Copilot uses AI. Check for mistakes.

java -jar bundletool-all.jar build-apks \
--bundle="$AAB_PATH" \
--output=apks.apks \
--mode=universal \
--ks=dummy.keystore \
--ks-pass=pass:android \
--ks-key-alias=androiddebugkey \
--key-pass=pass:android
}

# Extract the universal APK
unzip -q apks.apks universal.apk

VERSION_NAME="${{ needs.prepare.outputs.version }}"
OUTPUT_FILE="v2er-${VERSION_NAME}_google_play_signed.apk"

# Note: This APK is signed with debug key, the actual Google Play signed APK
# is only available after deployment to Play Store
mv universal.apk "$OUTPUT_FILE"

echo "Generated APK: $OUTPUT_FILE"
echo "apk_path=$OUTPUT_FILE" >> $GITHUB_OUTPUT
echo "found=true" >> $GITHUB_OUTPUT

- name: Create Google Play link info
if: steps.download-apk.outputs.found == 'true'
id: play-link
run: |
VERSION_NAME="${{ needs.prepare.outputs.version }}"
VERSION_CODE="${{ needs.prepare.outputs.version_code }}"

# Create info file about Google Play signing
cat > "v2er-${VERSION_NAME}_google_play_signed_info.txt" << EOF
Google Play Signed APK Information
==================================
Version: ${VERSION_NAME}
Version Code: ${VERSION_CODE}
Package: me.ghui.v2er

The APK attached (v2er-${VERSION_NAME}_google_play_signed.apk) is a universal APK
generated from the AAB (Android App Bundle) that was uploaded to Google Play.

When downloaded from Google Play Store, the APK will be signed with Google Play's
app signing certificate instead of the upload certificate.

Internal Testing Link:
https://play.google.com/apps/test/me.ghui.v2er/${VERSION_CODE}

Note: Access to internal testing track required.
EOF

echo "info_path=v2er-${VERSION_NAME}_google_play_signed_info.txt" >> $GITHUB_OUTPUT

- name: Upload signed APK to GitHub Release
if: steps.download-apk.outputs.found == 'true'
uses: softprops/action-gh-release@v2
with:
tag_name: ${{ needs.prepare.outputs.version }}
files: |
${{ steps.download-apk.outputs.apk_path }}
${{ steps.play-link.outputs.info_path }}
fail_on_unmatched_files: false

- name: Summary
if: always()
run: |
echo "## Google Play Signed APK :package:" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY

if [ "${{ steps.download-apk.outputs.found }}" = "true" ]; then
echo "✅ **Universal APK generated successfully**" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "- **Version**: ${{ needs.prepare.outputs.version }}" >> $GITHUB_STEP_SUMMARY
echo "- **Version Code**: ${{ needs.prepare.outputs.version_code }}" >> $GITHUB_STEP_SUMMARY
echo "- **File**: v2er-${{ needs.prepare.outputs.version }}_google_play_signed.apk" >> $GITHUB_STEP_SUMMARY
echo "" >> $GITHUB_STEP_SUMMARY
echo "### Notes" >> $GITHUB_STEP_SUMMARY
echo "- This APK is generated from the AAB uploaded to Google Play" >> $GITHUB_STEP_SUMMARY
echo "- When installed from Play Store, it will use Google Play's signing certificate" >> $GITHUB_STEP_SUMMARY
echo "- The APK has been uploaded to the GitHub Release" >> $GITHUB_STEP_SUMMARY
else
echo "⚠️ **No AAB found in artifacts**" >> $GITHUB_STEP_SUMMARY
echo "Signed APK generation requires a release bundle (AAB)" >> $GITHUB_STEP_SUMMARY
fi
2 changes: 1 addition & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -25,4 +25,4 @@ fastlane/*.json
# Bundle
vendor/bundle/
.bundle/
Gemfile.lock
Gemfile.lockfastlane/node_modules/
1 change: 1 addition & 0 deletions fastlane/node_modules/.bin/playwright

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions fastlane/node_modules/.bin/playwright-core

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

52 changes: 52 additions & 0 deletions fastlane/node_modules/.package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Loading
Loading