2323 build :
2424 name : Build AAB & APK
2525 runs-on : ubuntu-latest
26+ outputs :
27+ signing_enabled : ${{ steps.signing.outputs.enabled }}
28+ build_mode : ${{ steps.build_mode.outputs.mode }}
2629
2730 steps :
2831 - name : Checkout
@@ -58,22 +61,54 @@ jobs:
5861 run : ./gradlew lint
5962 continue-on-error : true
6063
64+ - name : Check release signing secrets
65+ id : signing
66+ env :
67+ KEYSTORE_BASE64 : ${{ secrets.KEYSTORE_BASE64 }}
68+ KEYSTORE_PASSWORD : ${{ secrets.KEYSTORE_PASSWORD }}
69+ KEY_ALIAS : ${{ secrets.KEY_ALIAS }}
70+ KEY_PASSWORD : ${{ secrets.KEY_PASSWORD }}
71+ run : |
72+ if [[ -n "$KEYSTORE_BASE64" && -n "$KEYSTORE_PASSWORD" && -n "$KEY_ALIAS" && -n "$KEY_PASSWORD" ]]; then
73+ echo "enabled=true" >> "$GITHUB_OUTPUT"
74+ else
75+ echo "enabled=false" >> "$GITHUB_OUTPUT"
76+ fi
77+
78+ - name : Resolve build mode
79+ id : build_mode
80+ run : |
81+ if [[ "${{ github.event_name }}" == "pull_request" ]]; then
82+ echo "mode=debug" >> "$GITHUB_OUTPUT"
83+ elif [[ "${{ github.event_name }}" == "workflow_dispatch" && "${{ github.event.inputs.build_type }}" == "debug" ]]; then
84+ echo "mode=debug" >> "$GITHUB_OUTPUT"
85+ elif [[ "${{ steps.signing.outputs.enabled }}" == "true" ]]; then
86+ echo "mode=release" >> "$GITHUB_OUTPUT"
87+ else
88+ echo "mode=debug" >> "$GITHUB_OUTPUT"
89+ fi
90+
91+ - name : Validate release signing secrets
92+ if : (startsWith(github.ref, 'refs/tags/v') || (github.event_name == 'workflow_dispatch' && github.event.inputs.build_type == 'release')) && steps.signing.outputs.enabled != 'true'
93+ run : |
94+ echo "::error::Release builds require KEYSTORE_BASE64, KEYSTORE_PASSWORD, KEY_ALIAS and KEY_PASSWORD secrets."
95+ exit 1
96+
6197 - name : Build Debug AAB
62- if : github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.build_type == 'debug')
98+ if : steps.build_mode.outputs.mode == 'debug'
6399 run : ./gradlew bundleDebug
64100
65101 - name : Build Debug APK
66- if : github.event_name == 'pull_request' || (github.event_name == 'workflow_dispatch' && github.event.inputs.build_type == 'debug')
102+ if : steps.build_mode.outputs.mode == 'debug'
67103 run : ./gradlew assembleDebug
68104
69105 - name : Decode Keystore
70- if : github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || github.event.inputs.build_type == 'release')
106+ if : steps.build_mode.outputs.mode == 'release'
71107 run : |
72108 echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 -d > app/keystore.jks
73- continue-on-error : true
74109
75110 - name : Build Release AAB
76- if : github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || github.event.inputs.build_type == 'release')
111+ if : steps.build_mode.outputs.mode == 'release'
77112 run : ./gradlew bundleRelease
78113 env :
79114 KEYSTORE_FILE : ${{ github.workspace }}/app/keystore.jks
82117 KEY_PASSWORD : ${{ secrets.KEY_PASSWORD }}
83118
84119 - name : Build Release APK
85- if : github.event_name != 'pull_request' && (github.event_name != 'workflow_dispatch' || github.event.inputs.build_type == 'release')
120+ if : steps.build_mode.outputs.mode == 'release'
86121 run : ./gradlew assembleRelease
87122 env :
88123 KEYSTORE_FILE : ${{ github.workspace }}/app/keystore.jks
@@ -93,15 +128,15 @@ jobs:
93128 - name : Upload AAB
94129 uses : actions/upload-artifact@v4
95130 with :
96- name : app-bundle-${{ github.event_name == 'pull_request' && 'debug' || github.event.inputs.build_type || 'release' }}
131+ name : app-bundle-${{ steps.build_mode.outputs.mode }}
97132 path : app/build/outputs/bundle/**/*.aab
98133 retention-days : 30
99134 if : always()
100135
101136 - name : Upload APK
102137 uses : actions/upload-artifact@v4
103138 with :
104- name : app-apk-${{ github.event_name == 'pull_request' && 'debug' || github.event.inputs.build_type || 'release' }}
139+ name : app-apk-${{ steps.build_mode.outputs.mode }}
105140 path : app/build/outputs/apk/**/*.apk
106141 retention-days : 14
107142 if : always()
@@ -118,19 +153,38 @@ jobs:
118153 name : Deploy to Play Store
119154 needs : build
120155 runs-on : ubuntu-latest
121- if : startsWith(github.ref, 'refs/tags/v')
156+ if : startsWith(github.ref, 'refs/tags/v') && needs.build.outputs.signing_enabled == 'true'
122157
123158 steps :
124159 - name : Download AAB
125160 uses : actions/download-artifact@v4
126161 with :
127162 name : app-bundle-release
163+ path : release
164+
165+ - name : Validate Play Store secrets
166+ env :
167+ PLAY_STORE_SERVICE_ACCOUNT : ${{ secrets.PLAY_STORE_SERVICE_ACCOUNT }}
168+ PACKAGE_NAME : ${{ secrets.PACKAGE_NAME }}
169+ run : |
170+ if [[ -z "$PLAY_STORE_SERVICE_ACCOUNT" || -z "$PACKAGE_NAME" ]]; then
171+ echo "::error::Play Store deployment requires PLAY_STORE_SERVICE_ACCOUNT and PACKAGE_NAME secrets."
172+ exit 1
173+ fi
174+
175+ - name : Validate release AAB
176+ run : |
177+ find release -name '*.aab' -print
178+ if ! find release -name '*.aab' -print -quit | grep -q .; then
179+ echo "::error::No release AAB found in downloaded artifact."
180+ exit 1
181+ fi
128182
129183 - name : Deploy to Play Store
130184 uses : r0adkll/upload-google-play@v1
131185 with :
132186 serviceAccountJsonPlainText : ${{ secrets.PLAY_STORE_SERVICE_ACCOUNT }}
133187 packageName : ${{ secrets.PACKAGE_NAME }}
134- releaseFiles : release/*.aab
188+ releaseFiles : release/**/* .aab
135189 track : internal
136190 status : completed
0 commit comments