Have you ever experienced waiting long hours to deploy a build of your app, only to know in the end, it failed because of that one little mistake that you did?
You forgot to run the tests, code sign the project, or clean the project before creating a build. Even worse, you’re in a hurry that you failed to submit the build. 🤦
These issues are some of the things that you have to deal with repeatedly, whenever you manually deploy your Flutter apps (Android and iOS) to Google Play or Apple App Store, respectively.
Get help
Start automating your workflow.
Here’s some of the benefits you get when you automate your workflow:
- Quality - without sacrificing developer productivity, your team is enabled to ship a product that gets tested several times against multiple edge cases and environments
- Timeliness - automated workflow makes it easy for your team to plan release schedules ahead of time or ship bug fixes quickly to production
- Reproducible builds - you can easily track and fix issues found on a specific build
CI/CD in a nutshell
“CI” in CI/CD stands for Continuous Integration, it always has been. While the “CD” may either refer to Continuous Delivery or Continuous Deployment.
Typical CI/CD setup of a project
CI/CD contains a set of jobs for automating your development and deployment workflow.
CI jobs are used for running the pre-checks whether a new code can be merged into a repository. These jobs include but are not limited to running lint checks, tests, and building your app.
Continuous delivery and continuous deployment are almost identical. They both extend the CI jobs and prepare your app for release, except when deploying it.
Continuous deployment automatically deploys the changes of your app to production, while continuous delivery doesn’t. This means that with continuous delivery, your team gets to decide when to “manually” release the build.
Continuous Delivery vs Continuous Deployment
Which one is preferred? It depends.
They both have varying pros and cons depending on the project requirement or organization structure.
From my experience as a release manager at Freelancer.com, the mobile team uses a continuous delivery workflow. It makes sense because some internal processes require manual intervention before a build can be considered as “ready for production”.
In this article series, your goal is to implement a continuous delivery workflow.
Several CI/CD tools are available to help you automate your workflow, but using Github Actions and Fastlane is a good starting point to learn CI/CD.
Github Actions
Github Actions is a service that allows you to run your CI/CD workflow in the cloud.
Using this service, you rely on actions that are created by the community. You can also create your custom action by following this guide.
Pricing
Public Repositories
- Free
Private Projects
- Free: 2,000 Action minutes/month
- Team: 3,000 Action minutes/month
- Enterprise: 50,000 Action minutes/month
Demo
Here’s a simple demo the using CI workflow in Github Actions:
This is the workflow file used for the demo shown above:
# ci.yml
name: CI
on:
push:
branches:
- master
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v1
- uses: actions/setup-java@v1
with:
java-version: 12.x
- uses: subosito/flutter-action@v1
with:
flutter-version: 1.17.5
- run: flutter pub get
- run: flutter format --set-exit-if-changed .
- run: flutter analyze .
- run: flutter test
- run: flutter build apk
- uses: actions/upload-artifact@v1
with:
name: release-apk
path: build/app/outputs/apk/release/app-release.apk
Core Concepts 💡
Workflow
A workflow is triggered (to run) by a specific event. In the example above, the on
parameter indicates that this workflow is triggered, whenever you push
new commits to the master
branch.
Job
By default, a job runs in parallel with the other tasks you specified in the jobs
. This is helpful for a Flutter project because you can run simultaneous jobs when building your Android and iOS apps.
You can also run a set of jobs sequentially by using the needs
parameter, which accepts the name of the jobs it depends on.
# example_sequential_jobs.yml
jobs:
build_android:
steps: ...
deploy_android:
needs: [build_android]
steps: ...
In the example, if build_android
job fails, deploy_android
will not run.
Step
steps
contains a combination of multiple commands and actions to fulfill a job.
Action
These are the individual tasks combined to create a step. In a task, you specify the Github Action package
you need, the executable commands to run, or the configuration of the task such as setting the environment variables.
# example_environment_variables.yml
- uses: subosito/flutter-action@v1
with:
flutter-version: 1.17.5
env:
SOME_SECRET: "${{ secrets.SOME_SECRET }}"
Github provides a secure way to store these encrypted secrets
so you can use them inside a workflow file without having to hardcode them in your code.
Fastlane
At the time of writing, there’s no easy way of uploading the builds of your Flutter apps to Google Play Console (Android) or TestFlight (iOS) by using Github Actions alone.
Fastlane to the rescue.
Fastlane is an open-source tool that simplifies the deployment of both Android and iOS apps.
It comes with Fastlane match which makes it easy for teams to generate certificates and provisioning profiles when building iOS apps. More on this on the follow-up article for the iOS setup.
Fastlane determines the configuration of your automated workflow using a Fastfile
. This contains the Fastlane actions used to upload both Android and iOS builds to Google Play and TestFlight respectively.
Here’s a snippet of a Fastfile
for an iOS app:
default_platform :ios
platform :ios do
desc "This lane builds and upload the iOS app to the AppStore"
lane :build_and_upload do
custom_ruby_function
build_ios_app
upload_to_app_store
end
def custom_ruby_function():
...
end
end
Core Concepts 💡
Lane
build_and_upload
is an example of a lane. This consists of the Fastlane actions or custom Ruby functions required to complete a job.
Fastlane Actions
build_ios_app
and upload_to_app_store
are both examples of Fastlane actions. These are the functions that are included in Fastlane by default. More on the available Fastlane actions here.
Workflow setup goal
Continuous Delivery using Fastlane and Github Actions
Github Actions will be used to run the entire CI/CD workflow, invoke Flutter commands such as running tests and creating artifacts, and execute the lanes described in the Fastfile
s.
Implement the workflow
Continue reading the follow-up articles in this series:
Conclusion
The benefit you get from your CI/CD workflow is often directly proportional to your investment in it.
Starting small is still a good thing than not having anything set up at all.
Having an automated workflow saves a lot of time spent on waiting, helps avoid frustration on silly mistakes, lets your team focus on what matters, and be productive. 🚀