From 46d7ef6c31559eb13124f4a42f23431f474525fa Mon Sep 17 00:00:00 2001 From: AdityaKhatri Date: Tue, 7 Jul 2026 14:37:40 +0545 Subject: [PATCH] fix: update android release asset to aab from apk --- .github/workflows/release-android.yml | 30 ++++++++++++--------- components/CompareMappingSession.tsx | 15 +++++------ components/LocateFeaturesMappingSession.tsx | 15 +++++------ components/TileGridMappingSession.tsx | 15 +++++------ 4 files changed, 38 insertions(+), 37 deletions(-) diff --git a/.github/workflows/release-android.yml b/.github/workflows/release-android.yml index 5443349..e1fd068 100644 --- a/.github/workflows/release-android.yml +++ b/.github/workflows/release-android.yml @@ -145,7 +145,7 @@ jobs: # ─── JOB 2: PRODUCTION BUILD (requires manual approval) ───────────── build-production: - name: Build and Deploy Production APK + name: Build and Deploy Production AAB environment: production runs-on: ubuntu-latest needs: build-staging @@ -221,15 +221,18 @@ jobs: sudo rm -rf /usr/share/dotnet /usr/local/share/powershell /usr/share/swift /opt/ghc /opt/hostedtoolcache/CodeQL df -h - - name: Build production APK + - name: Build production AAB env: KEYSTORE_PATH: ${{ runner.temp }}/mapswipe-prod.keystore STORE_PASSWORD: ${{ secrets.ANDROID_PRODUCTION_KEYSTORE_PASSWORD }} KEY_ALIAS: ${{ secrets.ANDROID_PRODUCTION_KEY_ALIAS }} KEY_PASSWORD: ${{ secrets.ANDROID_PRODUCTION_KEY_PASSWORD }} + # bundleRelease produces an Android App Bundle for the Play Store. No + # -PreactNativeArchitectures override, so all ABIs are included and Play + # splits per device. The prod keystore signs it as the upload key; Play + # App Signing re-signs the delivered APKs. run: | - cd android && ./gradlew assembleRelease --stacktrace \ - -PreactNativeArchitectures=armeabi-v7a,arm64-v8a \ + cd android && ./gradlew bundleRelease --stacktrace \ -Pandroid.injected.signing.store.file=$KEYSTORE_PATH \ -Pandroid.injected.signing.store.password=$STORE_PASSWORD \ -Pandroid.injected.signing.key.alias=$KEY_ALIAS \ @@ -244,11 +247,11 @@ jobs: echo "tag=dev-$(git rev-parse --short HEAD)" >> $GITHUB_OUTPUT fi - - name: Rename APK + - name: Rename AAB run: | mkdir -p generated - cp android/app/build/outputs/apk/release/app-release.apk \ - generated/mapswipe-${{ steps.tag.outputs.tag }}.apk + cp android/app/build/outputs/bundle/release/app-release.aab \ + generated/mapswipe-${{ steps.tag.outputs.tag }}.aab - name: Publish production release env: @@ -258,14 +261,15 @@ jobs: --title "MapSwipe Mobile ${{ steps.tag.outputs.tag }}" \ --notes "## MapSwipe Mobile ${{ steps.tag.outputs.tag }} - ### 📱 Install - 1. Download the APK below - 2. Enable 'Install from unknown sources' in Android settings - 3. Install + ### 🚀 Play Store release + 1. Download the AAB below + 2. Upload it to the Play Console production track (Google re-signs it via Play App Signing) + 3. Review and roll out the release ### 🔧 Build info - Commit: \`${{ github.sha }}\` - Build: #${{ github.run_number }} - Date: $(date +'%Y-%m-%d %H:%M:%S UTC') - - Package: \`org.missingmaps.mapswipe\`" \ - generated/mapswipe-${{ steps.tag.outputs.tag }}.apk + - Package: \`org.missingmaps.mapswipe\` + - Artifact: Android App Bundle (.aab), signed with the upload key" \ + generated/mapswipe-${{ steps.tag.outputs.tag }}.aab diff --git a/components/CompareMappingSession.tsx b/components/CompareMappingSession.tsx index db0e32f..4ed68ba 100644 --- a/components/CompareMappingSession.tsx +++ b/components/CompareMappingSession.tsx @@ -189,17 +189,16 @@ function CompareMappingSession(props: Props) { const flatListRef = useRef>(null); - // "Go Back" on the outro scrolls back to the last task so the user can - // revise their answer (the outro is the page after the final task). + // "Go Back" on the outro returns to the first task so the user reviews the + // group from the start. The jump is instant (not animated): animating all + // the way back from the completion page would render every intermediate + // page and is what made repeated go-backs unstable. const handleOutroGoBack = useCallback(() => { - if (compressedTasks.length === 0) { - return; - } flatListRef.current?.scrollToOffset({ - offset: (compressedTasks.length - 1) * pageWidth, - animated: true, + offset: 0, + animated: false, }); - }, [compressedTasks.length, pageWidth]); + }, []); // FIXME: Discuss with Ankit on how to better define this const tileWidth = Math.min(pageWidth - 20, pageHeight / 2 - 120); diff --git a/components/LocateFeaturesMappingSession.tsx b/components/LocateFeaturesMappingSession.tsx index a14b1c5..f8f4bf2 100644 --- a/components/LocateFeaturesMappingSession.tsx +++ b/components/LocateFeaturesMappingSession.tsx @@ -372,17 +372,16 @@ function LocateFeaturesMappingSession(props: Props) { } }, [pageWidth, tasks.length, onReachedEnd]); - // "Go Back" on the outro scrolls back to the last task so the user can - // revise their answer (the outro is the page after the final task). + // "Go Back" on the outro returns to the first task so the user reviews the + // group from the start. The jump is instant (not animated): animating all + // the way back from the completion page would render every intermediate + // page and is what made repeated go-backs unstable. const handleOutroGoBack = useCallback(() => { - if (tasks.length === 0) { - return; - } flatListRef.current?.scrollToOffset({ - offset: (tasks.length - 1) * pageWidth, - animated: true, + offset: 0, + animated: false, }); - }, [tasks.length, pageWidth]); + }, []); const tileWidth = Math.min(pageWidth - 20, pageHeight / 2); // The tile is vertically centered in the viewport, so its bottom edge sits diff --git a/components/TileGridMappingSession.tsx b/components/TileGridMappingSession.tsx index a5465dc..fc26994 100644 --- a/components/TileGridMappingSession.tsx +++ b/components/TileGridMappingSession.tsx @@ -240,17 +240,16 @@ function TileGridMappingSession(props: Props) { } }, [pageWidth, groupedTasks.length, contentPages, onReachedEnd]); - // "Go Back" on the outro scrolls back to the last task page so the user can - // revise their answers (the outro is the page after the final tasks). + // "Go Back" on the outro returns to the first task so the user reviews the + // group from the start. The jump is instant (not animated): animating all + // the way back from the completion page would render every intermediate + // page and is what made repeated go-backs unstable. const handleOutroGoBack = useCallback(() => { - if (contentPages === 0) { - return; - } flatListRef.current?.scrollToOffset({ - offset: (contentPages - 1) * pageWidth, - animated: true, + offset: 0, + animated: false, }); - }, [contentPages, pageWidth]); + }, []); const handleTilePress = useCallback((taskId: string) => { onResultsChange((prevResults) => {