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)