Skip to main content

CI/CD with GitHub Actions for Flutter projects - Part 1

First of all, to successfully follow this guide you should be familiar with the YAML serialisation language. (YAML files can be created with yaml and yml file extensions, both are the same in interpretation and syntax and I will use one or the other interchangeably).

If you have a project hosted on GitHub, there are plenty of automation tools you can rely on. If a few days ago we talked about using Dependabot on GitHub for Flutter and Dart, today I'm going to talk about using GitHub Actions as a Continuous Integration tool.

Flutter logo, Dash mascot and GitHub Actions logo

You may think that setting up GitHub Actions for Flutter is as simple as clicking on Actions inside the repository in the suggested actions...

Flutter DragPDF project header on GitHub on Actions tab.

But I anticipate that this will not be enough as what will be set up is an Actions for Dart and it will fail when it discovers that you have Flutter.

Window execution failing with the build created by the Dart and Flutter wizard on GitHub Actions within the platform.

As you may be thinking... It's a workflow for Dart (not Flutter). So let's get down to work.

GitHub Actions and Workflows

First of all, we will go to the documentation so that we can clarify what a Workflow in GitHub Actions is.

A workflow is a configurable automated process that will run one or more jobs. Workflows are defined by a YAML file checked in to your repository and will run when triggered by an event in your repository, or they can be triggered manually, or at a defined schedule.

Workflows are defined in the .github/workflows directory in a repository, and a repository can have multiple workflows, each of which can perform a different set of tasks. For example, you can have one workflow to build and test pull requests, another workflow to deploy your application every time a release is created, and still another workflow that adds a label every time someone opens a new issue.

So we already know that we should have a hidden folder inside the repository as follows.

Android Studio opened with the .github folder containing another workflows folder which contains the flutter_workflow.yml file that triggers flutter's continuous integration into GitHub.

Note that .github is the same hidden directory we used in the Dependabot tutorial a few weeks ago.

As you can imagine. We will create as many workflow files as we want groups of jobs to be executed. 

In the case of the image I only have one workflow inside a file called flutter_workflow.yml

You can create it with any name you want.


Following the documentation again, a workflow should contain the following basic components:

  1. One or more events that will trigger the workflow.
  2. One or more jobs, each of which will run on an execution machine and execute a series of one or more steps.
  3. Each step can execute a script that you define or execute an action, which is a reusable extension that can simplify your workflow.
Diagram of jobs and Runners within GitHub Actions.

Creating a workflow

Triggers of the flutter_workflow.yml file that will trigger the continuous delivery GitHub Actions in a Flutter project.

In the first line of the file we will give it a name (Flutter CI in my case). That name is used when you lists your workflows on the GitHub Action website.

In the second line, we indicate the event or events that will trigger the workflow to start running.

In my case, as you can see below, it is triggered when a push is made to the develop and master (line 3 - 6 both inclusives).

It also triggers the workflow with pull requests to the same two branches (line 7 - 10 both inclusives).

A complete list of the events that can be defined can be found at the following link. Now we can focus on writing the jobs we want to be executed. With the input jobs: (line 12) we define that it is the entry point to each of the jobs that the workflow will perform. In this example we only have one defined, but we can define as many as we want as long as we respect the yml identation.

Jobs of the flutter_workflow.yml file that will trigger the continuous delivery GitHub Actions in a Flutter project.
We define the name we want to give to the job, in my case it is called flutter_ci.

We can give it a name by which it will be referred to on the GitHub Actions website (line 14).

In line 15 we can choose the type of container we want our job to run in. We can see a list of available machinesFinally, we will indicate the steps that must be executed to complete the task. We do this starting on line 16. 

The list of steps will change depending on the needs, in our case we will try to analyse the project looking for errors or warnings as well as launching the tests that are available.

Full lists of jobs of the flutter_workflow.yml file that will trigger the continuous delivery GitHub Actions in a Flutter project.
The first thing to do is to indicate that our job uses or requires the checkout action (line 17). This action checks your repository under $GITHUB_WORKSPACE, so that your workflow can access it. In short, this allows your scripts to execute authenticated git commands.

As it will be run on android on an ubuntu machine, it will also require the use of the Java SDK by using the action on line 18.

Finally, we will indicate that it uses the flutter action to provide the SDK with Dart and Flutter.

Using the run: tag, we can execute as many commands as we want. In my case I have chosen to run:

Run tags of a Runner of continuous integration on Flutter project in GitHub Actions.

If we save the file and push it to the repository with this change, the action will automatically be triggered as shown below:

GitHub with a project selected with the Actions tab open.

The full yml file appears below or you can view it in this repository.

Full content a file named fluttter_workflow.yaml to make a continuous integration in a Flutter project on GitHub.


As you can see, this opens the way even to continuous distribution, as we can even create tasks that build and even publish the versions. But for that we will have to find a way to get the keystore information and the file to GitHub Actions as these should never be uploaded to the repository! 

So in order not to make this guide even longer I have decided to split it into 2 parts where we will discuss how to protect API keys from being available in our Flutter repositories.

Note: If you want to know how to protect your sensitive data by removing it from the repository, take a look at our guide.

See you in the next post, greetings! 


© 2020 Mobile Dev Hub