Are you tired of manually deploying your Flutter apps every time you make a change? It’s time to level up your CI/CD game with GitHub Actions! 💡
GitHub Actions offers a seamless way to automate your Flutter app’s build, test, and deployment processes for both Android and iOS, saving you time and effort. With just a few lines of YAML, you can create workflows that:
✅ Automatically build your Flutter app when you push to a specific branch.
✅ Run tests to ensure your app remains rock solid.
✅ Deploy APKs to Google Play Store or TestFlight for iOS with minimal manual intervention.
Why Automate Deployment?
Manual deployment is prone to errors, repetitive, and time-consuming. Automation ensures:
- Consistency: Every build follows the same steps, leaving no room for missed configurations.
- Speed: Focus on coding while GitHub Actions handles deployment.
- Confidence: Continuous testing ensures every release is bug-free.
Setting Up GitHub Actions for Flutter
Here’s a step-by-step guide to setting up GitHub Actions for your Flutter app:
1. Create a Workflow File
Navigate to your project repository and create the directory .github/workflows/. Inside this directory, create a file named deploy.yml. This file will define the steps for automating your app deployment.
2. Define Workflow Triggers
Specify when the workflow should run, for example, on a push to the main branch:
on:
push:
branches:
- main
This ensures the workflow runs whenever new changes are pushed to the main
branch.
3. Setup Flutter Environment
Install and configure Flutter in your workflow using the subosito/flutter-action
:
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: 'stable'
4. Install Dependencies
Ensure all required packages are fetched:
- name: Install Dependencies
run: flutter pub get
5. Run Tests
Add a step to execute tests and validate the app:
- name: Run Tests
run: flutter test
6. Build the App
Build the APK (For Android):
- name: Build APK
run: flutter build apk
But in most cases we need Signed APK.
For Signed APK:
- name: Decode Keystore File
run: echo "${{ secrets.ANDROID_KEYSTORE }}" | base64 --decode > android/app/keystore.jks
- name: Decode Keystore Credentials
run: |
echo "${{ secrets.KEYSTORE_ALIAS }}" | base64 --decode > keystore_alias.txt
echo "${{ secrets.KEYSTORE_PASSWORD }}" | base64 --decode > keystore_password.txt
echo "${{ secrets.KEY_PASSWORD }}" | base64 --decode > key_password.txt
- name: Build Signed APK
run: |
flutter build apk --release \
--dart-define=KEYSTORE_PATH=android/app/keystore.jks \
--dart-define=KEYSTORE_ALIAS=$(cat keystore_alias.txt) \
--dart-define=KEYSTORE_PASSWORD=$(cat keystore_password.txt) \
--dart-define=KEY_PASSWORD=$(cat key_password.txt)
For iOS apps:
- name: Build iOS
run: flutter build ios --no-codesign
7. Deploy Automatically
Use deployment tools or scripts to upload your build to the respective platforms. Here’s an example for deploying to Google Play:
- name: Deploy to Google Play
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJson: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT }}
packageName: com.example.yourapp
releaseFiles: build/app/outputs/flutter-apk/app-release.apk
For iOS, you can use fastlane
or similar tools to deploy to TestFlight. I'll write another post about iOS deployments in depth.
Full Sample Workflow
Here’s a complete workflow example for Flutter deployment with a signed APK and Base64-encoded secrets:
name: Flutter Deployment
on:
push:
branches:
- main
jobs:
build-and-deploy:
runs-on: ubuntu-latest
steps:
- name: Checkout Repository
uses: actions/checkout@v3
- name: Setup Flutter
uses: subosito/flutter-action@v2
with:
flutter-version: 'stable'
- name: Install Dependencies
run: flutter pub get
- name: Run Tests
run: flutter test
- name: Decode Keystore File
run: echo "${{ secrets.ANDROID_KEYSTORE }}" | base64 --decode > android/app/keystore.jks
- name: Decode Keystore Credentials
run: |
echo "${{ secrets.KEYSTORE_ALIAS }}" | base64 --decode > keystore_alias.txt
echo "${{ secrets.KEYSTORE_PASSWORD }}" | base64 --decode > keystore_password.txt
echo "${{ secrets.KEY_PASSWORD }}" | base64 --decode > key_password.txt
- name: Build Signed APK
run: |
flutter build apk --release \
--dart-define=KEYSTORE_PATH=android/app/keystore.jks \
--dart-define=KEYSTORE_ALIAS=$(cat keystore_alias.txt) \
--dart-define=KEYSTORE_PASSWORD=$(cat keystore_password.txt) \
--dart-define=KEY_PASSWORD=$(cat key_password.txt)
- name: Deploy to Google Play
uses: r0adkll/upload-google-play@v1
with:
serviceAccountJson: ${{ secrets.GOOGLE_PLAY_SERVICE_ACCOUNT }}
packageName: com.example.yourapp
releaseFiles: build/app/outputs/flutter-apk/app-release.apk
Wrapping Up
By automating Flutter app deployment with GitHub Actions, ensuring signed APKs, and securely storing secrets in Base64, you save valuable time and minimize errors. A solid CI/CD pipeline ensures every release is reliable and reaches your users faster. 🌟
What challenges have you faced while setting up GitHub Actions? Let us know in the comments below! 💬
Top comments (0)