Setting up a CI/CD pipeline for Flutter using Codemagic

Simo Nyathi
Oct 9, 2019 · 7 min read
Photo by Sven Kucinic on Unsplash

While most software development teams and companies have predominantly adopted the implementation of the Agile methodology in their approach to software development, there may be a few that may still be stuck in the past with the waterfall approach, the proverbial equivalent of living in a deserted island, unless of course they are trying to walk on water.

Walking on water and developing software from a specification are easy if both are frozen

~ Edward V Berard.

The need, however, for automated processes in the Agile approach could have led to the introduction of the DevOps approach to software development.

One such part of the automated processes that come with DevOps is the CI/CD (Continuous Integration/ Continuous Delivery — Deployment) process. In a nutshell, CI improves on the stability of the product with each development cycle as each time code is pushed, automatic builds are triggered and integration tests are run to ensure that the new units being added do not “break” the previously successfully built application. Builds fail if tests fail, among other reasons, thus ensuring the stability of the app. Continuous Delivery is responsible for the preparation of the app for release while Continuous Deployment is responsible for automatic deployment to production.

The trouble with programmers is that you can never tell what a programmer is doing until it’s too late

~ Seymour Cray.

There already exists a good number of tools for setting up CI/CD pipelines for many programming languages. This article discusses setting up a CI/CD Pipeline for a Flutter application using CodeMagic. An attempt to making sure that everyone always knows what the programmer is always doing.


CodeMagic became the first CI/CD tool created specifically for Flutter apps, and like All the other CI/CD tools, it starts with a Git repository or some decentralized repository at least. When code is pushed to this repository, it triggers a new build process. If the build fails at any point, it will halt any further progress of the CI/CD process and give logs so we know where exactly the issue came from. Successful builds deliver the application artifacts for iOS and Android for installation on the respective devices.

Codemagic allows you to signup using Github, Bitbucket or GitLab. Once Signup is completed, you will land on the Applications overview showing a list of all your apps from the linked repository.

Flutter allows you to apply some filters on the apps displayed. Initially, it will show all the apps linked to the repository used to sign in. You can then filter by the Repository, by the account email, by the languages(initially set to all languages), etc.

Filters for displayed applications.

It is quite odd that Codemagic, through the “All languages” filter option, and still displays non-flutter apps with the option to start a build, which then fails with an error “No Flutter projects found from branch ‘branch_name’

Error on non-flutter project build attempt

Each app list item contains the app name, a settings icon/ button, and an always enabled “Start your first build” or “Start new build” button for initial builds or new builds respectively.

Build settings

The settings button/ icon is where all the magic is setup. So when you click the Icon the first time, it feels like you can’t do anything else but start the first build; which ordinarily you would as the blue call to action button is quite unmissable.

The first time you go into the Build Settings.

After running your initial build and navigating back via the settings icon, the screen takes a whole different look as it honestly feels like it has come alive with multiple build settings being offered.

“New” Beefed up Build Settings screen.

The “new” layout is what we are most looking for. The app name is displayed at the top, the “Start new build” button appears to be disabled, there is a drop-down list to select a workflow from with “Default Workflow” selected and initially disabled as that is the only option. There is a “Configure app settings and add custom steps.” section with options to configure Build Triggers, Environment variables, Dependency caching, Tests, Build, and Publishing settings. The right panel contains the workflow settings

Selected Workflow.

Let’s start from the Top, the Selected Workflow. Codemagic allows multiple workflows to allow multiple build settings. That way you can have builds being built but not deployed to production for a development workflow when code is merged to the dev branch, while code merges to the release branch trigger publishing to the app stores for instance.

The default workflow has build trigger settings tracking every branch but no trigger set. Should you want to keep the default, then selecting the “Duplicate workflow” option on the Workflow settings on the right panel does exactly that. Instantly the workflow dropdown is enabled and the selection set to “Default Workflow(Copy)”.

Configuration of the selected workflow

Clicking the Workflow name under Workflow settings allows you to edit the name. Set this name to the new Workflow that you are tracking for example “Develop Workflow” or “Release Workflow” to track any code merges on my develop or your release branch. The changes are automatically saved when you accept the change.

Just like that, you have created an extra workflow besides the default. The same renaming process could be applied to the default workflow if you preferred not to have a default flow. Selecting the workflows is as easy as selecting the particular one on the drop-down list.

Build Triggers

Now that the particular workflow we want is set, we can now set the build triggers for the selected workflow. The first thing you do is type in the branch to track. This is done by specifying the branch name from your project. Once you have the correct name set, click the “Add pattern” button. An example would be “develop” for the “Develop Workflow”.

Build Trigger Configuration section

If you only want the builds to be created manually, click the “Save” button and you are done with the build triggers. Else select at least one of the automatic build trigger options. The simplest option would be “Trigger on every push” as builds will be triggered each time code is pushed to the watched branch. Save your changes and head to Tests.

Please note that this article doesn’t cover Environment variables and Dependency caching.


The test settings are quite straightforward. You basically set how the tests affect the build. You can enable Flutter analyzer, enable Flutter test which runs the unit tests in your application. You can deactivate the automatic build failures resulting from failed tests here, a highly unrecommended option for builds going out to production at the very least. Remember to always save the settings for each individual section as there is no universal save button to save all set settings.

Flutter test configuration.


This is where Continuous Delivery settings are configured. This section contains the settings that specify the kind of artifacts the build process produces. These settings include specifying the Flutter version, the platform to which to build, the mode to build, Xcode version, and build arguments.

For the Flutter version, leave it as “channel Stable”. For the platforms to build for, select the intended platform targets. For the Mode, set to “Release” as you are building production-ready artifacts. Leave Xcode version set to “Latest”. Leave build arguments as is.

After successfully building the app, you get a badge for your result

CodeMagic Badge for a successful build.


This is where the Continuous Deployment configuration happens. Should the Ops decide to always release builds after the Dev is done, this is where we can link our pipeline to all the various channels of Deployment. It might not necessarily be deployed to production as it allows the emailing of artifacts to the various stakeholders within the team. Simply follow the steps to set up all the channels you need and save all the settings.

Emailed artifacts after successful builds

And just like that, your Workflow is set and all the triggers are in place. When you merge code into the develop branch, it will trigger the magic and before you know it, your app will be delivered and deployed to all interested parties through the preset channels.

Try it out on The user experience is quite unparalleled. It would be weird if it wasn’t. After all, it was made just for Flutter.

DVT Software Engineering

Simo Nyathi

Written by

DVT Software Engineering

Making an impact in Software Engineering

Welcome to a place where words matter. On Medium, smart voices and original ideas take center stage - with no ads in sight. Watch
Follow all the topics you care about, and we’ll deliver the best stories for you to your homepage and inbox. Explore
Get unlimited access to the best stories on Medium — and support writers while you’re at it. Just $5/month. Upgrade