Skip to content

Commit 929ce80

Browse files
feat: add Google Play Store deployment with Fastlane integration
- Add Fastlane configuration for Play Store deployment - Create GitHub Actions workflows for automated deployment - Implement multi-track support (internal, alpha, beta, production) - Add rollout management workflow for production releases - Configure secure authentication via GitHub Secrets - Add comprehensive deployment documentation Workflows: - play-store-deploy.yml: Manual deployments and track promotions - play-store-post-release.yml: Auto-deployment after GitHub release - play-store-rollout.yml: Production rollout management Features: - Automatic internal testing deployment after releases - Gradual rollout support (10% → 20% → 50% → 100%) - Emergency halt/resume capabilities - Metadata synchronization with existing fastlane structure - Version code handling and changelog integration
1 parent 6288fed commit 929ce80

File tree

7 files changed

+1052
-0
lines changed

7 files changed

+1052
-0
lines changed
Lines changed: 186 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,186 @@
1+
name: Google Play Store Deployment
2+
3+
on:
4+
workflow_dispatch:
5+
inputs:
6+
track:
7+
description: 'Deployment track'
8+
required: true
9+
default: 'internal'
10+
type: choice
11+
options:
12+
- internal
13+
- alpha
14+
- beta
15+
- production
16+
promote:
17+
description: 'Promote from previous track (only for alpha/beta/production)'
18+
required: false
19+
default: false
20+
type: boolean
21+
rollout_percentage:
22+
description: 'Rollout percentage for production (0.1, 0.2, 0.5, 1.0)'
23+
required: false
24+
default: '0.1'
25+
type: choice
26+
options:
27+
- '0.1'
28+
- '0.2'
29+
- '0.5'
30+
- '1.0'
31+
update_metadata:
32+
description: 'Update store metadata'
33+
required: false
34+
default: false
35+
type: boolean
36+
37+
jobs:
38+
deploy:
39+
runs-on: ubuntu-latest
40+
if: ${{ github.event_name == 'workflow_dispatch' }}
41+
42+
steps:
43+
- name: Checkout code
44+
uses: actions/checkout@v4
45+
with:
46+
ref: ${{ github.event.workflow_run && github.event.workflow_run.head_sha || github.ref }}
47+
submodules: false
48+
49+
- name: Initialize Submodules
50+
uses: ./.github/actions/setup-repository
51+
52+
- name: Setup Flutter with FVM
53+
uses: ./.github/actions/setup-fvm
54+
with:
55+
cache-key-suffix: "play-store"
56+
57+
- name: Install Flutter Dependencies
58+
uses: ./.github/actions/install-flutter-deps
59+
60+
- name: Install OpenJDK 17
61+
run: |
62+
sudo apt-get update -y
63+
sudo apt-get install -y openjdk-17-jdk-headless
64+
65+
- name: Setup Android SDK
66+
uses: android-actions/setup-android@v3
67+
68+
- name: Setup Ruby and Fastlane
69+
uses: ruby/setup-ruby@v1
70+
with:
71+
ruby-version: '3.2'
72+
bundler-cache: true
73+
working-directory: fastlane
74+
75+
- name: Install Fastlane dependencies
76+
run: |
77+
cd fastlane
78+
bundle install
79+
working-directory: fastlane
80+
81+
- name: Setup Keystore
82+
run: |
83+
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > src/android/app/whph-release.keystore
84+
85+
- name: Update Gradle Properties
86+
run: |
87+
cat << EOF > src/android/key.properties
88+
storePassword=${{ secrets.KEYSTORE_PASSWORD }}
89+
keyPassword=${{ secrets.KEY_PASSWORD }}
90+
keyAlias=${{ secrets.KEY_ALIAS }}
91+
storeFile=whph-release.keystore
92+
EOF
93+
94+
- name: Setup Google Play Service Account
95+
run: |
96+
echo "${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_KEY }}" | base64 --decode > fastlane/google-play-service-account.json
97+
98+
- name: Get application version
99+
id: app_version
100+
uses: ./.github/actions/get-app-version
101+
102+
- name: Remove non-Android platforms
103+
run: |
104+
cd src
105+
rm -rf ios linux macos web windows
106+
107+
- name: Build Android App Bundle
108+
run: |
109+
cd src
110+
fvm flutter build appbundle --release
111+
112+
- name: Deploy to Google Play Store
113+
run: |
114+
cd fastlane
115+
116+
# Set environment variables for Fastlane
117+
export GOOGLE_PLAY_SERVICE_ACCOUNT_KEY="./google-play-service-account.json"
118+
export KEYSTORE_FILE_PATH="../src/android/app/whph-release.keystore"
119+
export KEYSTORE_PASSWORD="${{ secrets.KEYSTORE_PASSWORD }}"
120+
export KEY_ALIAS="${{ secrets.KEY_ALIAS }}"
121+
export KEY_PASSWORD="${{ secrets.KEY_PASSWORD }}"
122+
123+
# Determine deployment strategy
124+
if [[ "${{ github.event.inputs.promote }}" == "true" ]]; then
125+
case "${{ github.event.inputs.track }}" in
126+
"alpha")
127+
echo "Promoting to alpha track..."
128+
bundle exec fastlane promote_to_alpha
129+
;;
130+
"beta")
131+
echo "Promoting to beta track..."
132+
bundle exec fastlane promote_to_beta
133+
;;
134+
"production")
135+
echo "Promoting to production track..."
136+
bundle exec fastlane promote_to_production
137+
;;
138+
esac
139+
else
140+
case "${{ github.event.inputs.track }}" in
141+
"internal")
142+
echo "Deploying to internal testing..."
143+
bundle exec fastlane deploy_internal
144+
;;
145+
"alpha")
146+
echo "Deploying to alpha track..."
147+
bundle exec fastlane deploy_alpha
148+
;;
149+
"beta")
150+
echo "Deploying to beta track..."
151+
bundle exec fastlane deploy_beta
152+
;;
153+
"production")
154+
if [[ "${{ github.event.inputs.rollout_percentage }}" == "1.0" ]]; then
155+
echo "Deploying to production with full rollout..."
156+
bundle exec fastlane deploy_production_full
157+
else
158+
echo "Deploying to production with staged rollout..."
159+
bundle exec fastlane deploy_production
160+
fi
161+
;;
162+
esac
163+
fi
164+
165+
- name: Update metadata if requested
166+
if: ${{ github.event.inputs.update_metadata == 'true' }}
167+
run: |
168+
cd fastlane
169+
export GOOGLE_PLAY_SERVICE_ACCOUNT_KEY="./google-play-service-account.json"
170+
bundle exec fastlane update_metadata
171+
172+
- name: Create deployment summary
173+
run: |
174+
echo "## 🚀 Google Play Store Deployment Summary" >> $GITHUB_STEP_SUMMARY
175+
echo "" >> $GITHUB_STEP_SUMMARY
176+
echo "**Track:** ${{ github.event.inputs.track || 'internal' }}" >> $GITHUB_STEP_SUMMARY
177+
echo "**Version:** ${{ steps.app_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
178+
echo "**Promotion:** ${{ github.event.inputs.promote == 'true' && 'Yes' || 'No' }}" >> $GITHUB_STEP_SUMMARY
179+
echo "**Rollout:** ${{ github.event.inputs.rollout_percentage || 'N/A' }}" >> $GITHUB_STEP_SUMMARY
180+
echo "**Metadata Updated:** ${{ github.event.inputs.update_metadata == 'true' && 'Yes' || 'No' }}" >> $GITHUB_STEP_SUMMARY
181+
echo "" >> $GITHUB_STEP_SUMMARY
182+
echo "### 📱 App Information" >> $GITHUB_STEP_SUMMARY
183+
echo "- **Package:** me.ahmetcetinkaya.whph" >> $GITHUB_STEP_SUMMARY
184+
echo "- **Version Code:** ${{ steps.app_version.outputs.build-number }}" >> $GITHUB_STEP_SUMMARY
185+
echo "- **Version Name:** ${{ steps.app_version.outputs.version-number }}" >> $GITHUB_STEP_SUMMARY
186+
Lines changed: 120 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,120 @@
1+
name: Google Play Store Post-Release Deployment
2+
3+
on:
4+
workflow_run:
5+
workflows: ["Release All Platforms"]
6+
types:
7+
- completed
8+
9+
jobs:
10+
deploy-to-internal:
11+
runs-on: ubuntu-latest
12+
if: ${{ github.event.workflow_run.conclusion == 'success' && startsWith(github.event.workflow_run.head_branch, 'v') }}
13+
14+
steps:
15+
- name: Checkout code
16+
uses: actions/checkout@v4
17+
with:
18+
ref: ${{ github.event.workflow_run.head_sha }}
19+
submodules: false
20+
21+
- name: Initialize Submodules
22+
uses: ./.github/actions/setup-repository
23+
24+
- name: Setup Flutter with FVM
25+
uses: ./.github/actions/setup-fvm
26+
with:
27+
cache-key-suffix: "play-store-post-release"
28+
29+
- name: Install Flutter Dependencies
30+
uses: ./.github/actions/install-flutter-deps
31+
32+
- name: Install OpenJDK 17
33+
run: |
34+
sudo apt-get update -y
35+
sudo apt-get install -y openjdk-17-jdk-headless
36+
37+
- name: Setup Android SDK
38+
uses: android-actions/setup-android@v3
39+
40+
- name: Setup Ruby and Fastlane
41+
uses: ruby/setup-ruby@v1
42+
with:
43+
ruby-version: '3.2'
44+
bundler-cache: true
45+
working-directory: fastlane
46+
47+
- name: Install Fastlane dependencies
48+
run: |
49+
cd fastlane
50+
bundle install
51+
working-directory: fastlane
52+
53+
- name: Setup Keystore
54+
run: |
55+
echo "${{ secrets.KEYSTORE_BASE64 }}" | base64 --decode > src/android/app/whph-release.keystore
56+
57+
- name: Update Gradle Properties
58+
run: |
59+
cat << EOF > src/android/key.properties
60+
storePassword=${{ secrets.KEYSTORE_PASSWORD }}
61+
keyPassword=${{ secrets.KEY_PASSWORD }}
62+
keyAlias=${{ secrets.KEY_ALIAS }}
63+
storeFile=whph-release.keystore
64+
EOF
65+
66+
- name: Setup Google Play Service Account
67+
run: |
68+
echo "${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT_KEY }}" | base64 --decode > fastlane/google-play-service-account.json
69+
70+
- name: Get application version
71+
id: app_version
72+
uses: ./.github/actions/get-app-version
73+
74+
- name: Remove non-Android platforms
75+
run: |
76+
cd src
77+
rm -rf ios linux macos web windows
78+
79+
- name: Build Android App Bundle
80+
run: |
81+
cd src
82+
fvm flutter build appbundle --release
83+
84+
- name: Deploy to Internal Testing
85+
run: |
86+
cd fastlane
87+
88+
# Set environment variables for Fastlane
89+
export GOOGLE_PLAY_SERVICE_ACCOUNT_KEY="./google-play-service-account.json"
90+
export KEYSTORE_FILE_PATH="../src/android/app/whph-release.keystore"
91+
export KEYSTORE_PASSWORD="${{ secrets.KEYSTORE_PASSWORD }}"
92+
export KEY_ALIAS="${{ secrets.KEY_ALIAS }}"
93+
export KEY_PASSWORD="${{ secrets.KEY_PASSWORD }}"
94+
95+
echo "🚀 Auto-deploying version ${{ steps.app_version.outputs.version }} to internal testing after GitHub release..."
96+
bundle exec fastlane deploy_internal
97+
98+
- name: Create post-release deployment summary
99+
run: |
100+
echo "## 🎮 Post-Release Deployment to Internal Testing" >> $GITHUB_STEP_SUMMARY
101+
echo "" >> $GITHUB_STEP_SUMMARY
102+
echo "**Version:** ${{ steps.app_version.outputs.version }}" >> $GITHUB_STEP_SUMMARY
103+
echo "**Track:** Internal Testing" >> $GITHUB_STEP_SUMMARY
104+
echo "**Trigger:** Release workflow completion (${{ github.event.workflow_run.head_branch }})" >> $GITHUB_STEP_SUMMARY
105+
echo "" >> $GITHUB_STEP_SUMMARY
106+
echo "### 📱 App Information" >> $GITHUB_STEP_SUMMARY
107+
echo "- **Package:** me.ahmetcetinkaya.whph" >> $GITHUB_STEP_SUMMARY
108+
echo "- **Version Code:** ${{ steps.app_version.outputs.build-number }}" >> $GITHUB_STEP_SUMMARY
109+
echo "- **Version Name:** ${{ steps.app_version.outputs.version-number }}" >> $GITHUB_STEP_SUMMARY
110+
echo "" >> $GITHUB_STEP_SUMMARY
111+
echo "### 🔄 Next Steps" >> $GITHUB_STEP_SUMMARY
112+
echo "1. ✅ GitHub release created successfully" >> $GITHUB_STEP_SUMMARY
113+
echo "2. ✅ Deployed to Google Play internal testing" >> $GITHUB_STEP_SUMMARY
114+
echo "3. 🔄 Test the app in internal testing" >> $GITHUB_STEP_SUMMARY
115+
echo "4. 🔄 Promote to alpha when ready" >> $GITHUB_STEP_SUMMARY
116+
echo "5. 🔄 Continue through beta to production" >> $GITHUB_STEP_SUMMARY
117+
echo "" >> $GITHUB_STEP_SUMMARY
118+
echo "### 📋 Manual Actions Required" >> $GITHUB_STEP_SUMMARY
119+
echo "- Use 'Google Play Store Deployment' workflow to promote to other tracks" >> $GITHUB_STEP_SUMMARY
120+
echo "- Use 'Google Play Store Rollout Management' workflow for production rollouts" >> $GITHUB_STEP_SUMMARY

0 commit comments

Comments
 (0)