[Part 2] How to setup a Flutter application with Bitrise ?
The first part of this article explains what are our requirements and how we setup multiple environments in a Flutter application. You can find the source code in this repository.
To sum up, we created 3 environments :
👉 Dev : used when a developer works on local environment
👉 Staging: used for building the application when the ‘develop’ branch evolves (each new commit) and to validate checks for the pull requests.
👉 Prod: used for building production application when the ‘master’ branch evolves
Initialize Bitrise CI
The application is now ready to be imported in Bitrise. Bitrise has an out-of-the-box Flutter support, so I used it to initialize the CI/CD workflows.
You can add your Flutter app to our scanner and it will provide your project with two Flutter specific workflows which will allow you to test, build and deploy your app
- Add a new application
- Bitrise scanner detects the git repository which contains a Flutter application and ask you some questions to configure the default Bitrise setup
- When the setup is done, Bitrise automatically triggers a build with the default workflow called primary
Default Workflows
By default, Bitrise create 2 workflows primary and deploy. The principal difference between this 2 worklfows is the build and signing steps in the deploy workflow.
- To see the configuration, go to the workflow tab
- Go to the trigger tab to see when each workflow will be triggered by default
- The bitrise.yml tab allows you to retrieve all the configuration of your application on Bitrise. We usually store this file in the git repository to have a backup.
Our need !
The default setup does not meet our needs, so we have to configure it manually. So what is ours needs ?
We want to set up 4 workflows :
👉 pull-request : used for checking the code quality (tests, code coverage, …) and if the application can be built without bugs. Depending on your needs, you could also make the application available for a functional validation of the new feature.
👉 staging : used for building the application for the staging environment and make it available to POs, testers, stakeholders who need it.
👉 prod : used for building the application for the production environment and make it available to POs, testers, stakeholders who need it.
👉 unauthorize : used for preventing unauthorized actions in our continuous integration kinematics. This workflow throws an error.
Actually, we do not configure a continuous deployment, we make it manually. But if you want to do it, you can add a new workflow that will be triggered on git tag events !!
Bitrise configuration to meet our needs
The easiest way to share our configuration, is to give you our bitrise.yml file.
- You can copy and paste it into the Workflows/bitrise.yml tab. Don’t forget to press save 😜 !!
This bitrise.yml creates the 4 workflows and the triggers configurations. For example, you can see the steps defined in the pull-request workflow on the left.
We added the File Downloader, Certificate and profile installer, Codecov, Xcode Archive & Export for iOS and Github status steps.
File Downloader : used for downloading the Android certificat.
Certificate and profile installer : use to get the mobile provision and certificat for iOS signing.
Xcode Archive & Export for iOS : use to build and sign the iOS app
Github status : use to send Github status checks on each PR. You can configure your repository on Github so that status checks are mandatory to merge a PR.
If you look at the configuration of the Xcode Archive & Export for iOS, you can see an additional configuration in the Debug section (you need to click to show the additional Custom export option plist content configuration). Without this configuration, we encountered the error described in this PR. After long discussions with the Bitrise team, we found this hack to solve this issue. We only encountered this issue on Bitrise, no problems on our local machines. Thanks to the Bitrise team for the support 👍.
- Here is how triggers are configured
Android signing configuration
If you start a build on the develop branch with the actual configuration, you will have the following issue :
As described in the first post, the signing config for Android is defined like this in the build.gradle file :
You must generate the Android keystore if you don’t have one
keytool -genkey -v -keystore prod.jks -alias YOUR_ALIAS -storepass YOUR_STORE_PASS -keypass YOUR_KEYPASS-keyalg RSA -v
Once you have the keystore, you need to upload it on Bitrise. Go to the Workflows Tab and then in the Code Signing Tab :
Re-run the previous job, the Android build should not have any error, but the iOS build will fail !!
iOS signing configuration
Now you have to fix the iOS build failure, you must provide the iOS certificates and mobile provision file
For this step, you must have an Apple Developper account to create the mobile provisionning and the certificate. Once you have yours, you can upload them in Bitrise, go to the Workflows Tab and then in the Code Signing Tab :
Re-run the previous job, the Android and the iOS build should not have any error 🍾 🚀
Conclusion
The default Bitrise setup for an application must be configured to suit your processes, and this is normal. Each team/project has its own reality.
Bitrise offers a large number of steps that cover all the of a mobile application industrialization. Some steps like creating the iOS archive can be a little tricky to configure on Bitrise while locally we had no build errors. It is possible to connect remotely to the VM Vagrant to debug during a build and this is a real advantage. Nevertheless, we had to use Bitrise support to understand the difference between our local environment and that of Bitrise. The workaround implemented should not be necessary and raises a reproducible build concern. This is the only real negative point we have encountered in industrializing a Flutter application. So we gonna use it for our next Flutter project 👍