Continuous integration with Flutter and GitHub Actions

Per Classon
3 min readDec 11, 2020

--

To allow for collaboration in a repository, it is useful to have continuous integration to automatically check that code is correctly formatted and that tests pass. One way to have continuous integration on GitHub is to use GitHub Actions, and this article explains how to set it up with Flutter.

Create a workflows file

In your GitHub repository create a yml file inside the .github/workflows directory, you can name it to what you like, in this example it is checks.yml. To set the checks to run on pull requests and on commits to the main branch, add the following to checks.yml:

name: Code checks.
on:
push:
branches:
- main
pull_request:

The job can run on a Linux (Ubuntu), Windows or MacOS machine, in the example below it runs on all three operating systems. To install Flutter, its repository is cloned on the stable channel and the bin directory is added to the path. The repository that is being tested is then checked out under a different directory, to avoid any conflicts with the Flutter repository. Any packages are also installed from the pubspec.yaml.

jobs:
test:
name: Test on ${{ matrix.os }}
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-18.04, windows-2019, macos-10.15]
steps:
# Checkout Flutter and add it to the path.
- name: Checkout Flutter repository with stable channel.
uses: actions/checkout@v2
with:
repository: 'flutter/flutter'
ref: 'stable'
path: 'flutter'
fetch-depth: 0
- name: Add Flutter to the PATH for Unix
if: startsWith(matrix.os, 'macOS') || startsWith(matrix.os, 'ubuntu')
run: echo "$GITHUB_WORKSPACE/flutter/bin" >> $GITHUB_PATH
- name: Add Flutter to the PATH for Windows
if: startsWith(matrix.os, 'windows')
run: echo "${env:GITHUB_WORKSPACE}\flutter\bin" | Out-File -FilePath $env:GITHUB_PATH -Encoding utf8 -Append
- name: Run Flutter doctor.
run: flutter doctor -v
# Checkout your repository under `code`, to avoid conflicts with `flutter`.
- name: Checkout repository.
uses: actions/checkout@v2
with:
path: 'code'
- name: Get packages for the Flutter project.
run: flutter pub get
working-directory: code

With Flutter set up, it is up to you to decide what kind of checks you want to do in your repository.

Verify code formatting is correct

If your repository is following the dartfmt style guide, you can use the flutter format command to check that the code is formatted correctly:

  - name: Check code formatting.
run: flutter format --set-exit-if-changed --dry-run .
working-directory: code

The formatter handles indentation, inline whitespace and line wrapping. If there is an issue with the formatting, it exits with an error and the check fails.

Run static analysis with the Flutter analyzer

Static analysis allows you to find problems before executing a single line of code. It’s a useful tool used to prevent bugs and ensure that code conforms to style guidelines. Add the following code to check that the analyzer has no issues:

  - name: Analyze the Dart code.
run: flutter analyze
working-directory: code

The rules used in the analysis can be configured with an analysis_options.yaml file, or by putting ignore statements directly inside of the code.

Run all unit and widget tests

Hopefully you have had the time to add unit or widget tests for your code. To run them, add the following code:

  - name: Run Flutter tests.
run: flutter test
working-directory: code

Use grinder package for custom checks

If you have any custom commands or checks for your repository, there is the grinder library that helps you write and define project workflows and tasks to run on the command-line. As an example, inside of the Flutter Gallery it was used to check that localizations and code segments have been generated.

Add branch protection on GitHub

If you only want to allow pull requests to your repository if the GitHub Actions checks pass, then you need to enable branch protection for your GitHub repository. This way only pull requests with all checks passed can be merged.

Full example

To see a full fledged example, you can look at this flutter_code example repository. It runs a job for each subdirectory, with all of the above mentioned checks:

Under the Actions tab in GitHub you can see the result of each run, and all of the steps for each job. If your GitHub actions job would fail, this is where you can debug it:

Screenshot of a GitHub Actions job.

I hope this article helped you in setting up Github Actions!

--

--

Per Classon
Per Classon

Written by Per Classon

Software Engineer 👨🏼‍💻

No responses yet