Github Actions for Flutter with Caching
--
Github Actions provides an incredible tool for automation. Automation which costs us some up front developer time to setup and then provides a continual decrease in cost for the long run. Unfortunately for iOS, Github Actions come with a hefty penalty for using MacOS: a ten-times multiplier for MacOS instance minutes. The 2,000 minute limit for free accounts suddenly becomes a lot more daunting when we realize that is only 200 minutes for our iOS workflow to execute each month. If the average workflow takes two minutes, that is only 100 runs for month. Thankfully we can alleviate this issue do a degree by using caching.
This template can be used to create a cached Flutter environment for testing, building, analyzing, etc. With its current implementation, when an individual pushes to develop
or master
, this workflow will run the Dart analyzer and all tests in the project. Using caching, it will preserve the Flutter runtime to minimize setup time for each successive execution of the workflow (and reduce the risk of going over Github Action limits to avoid increased costs).
The Flexible Pieces
on:
push:
branches: [develop, master]
The block indicates the prerequisite git action that will result in our workflow executing. In this example we execute any jobs on all pushes to the develop
or master
branches. Another notable option here would be pull_request:
. This will allow us to differ strictness or separate out compiling APKs from more normal workflows such as if we wanted to run tests on every push but only run the Dart analyzer on pull requests.
env:
flutter_version: '1.20.x'
We pull out the Flutter version for two reason:
- Make changing Flutter version easy and centralized
- Embed the version into the cached file name so different versions of Flutter will have their own cache.
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest]
include:
- os: ubuntu-latest
flutter_path: /opt/hostedtoolcache/flutter
While this template only uses Ubuntu, it is written to be mold-able into as many operating systems as needed. Using a matrix allows us to provide a list of options operating systems which will individually run the Dart analyzer and our tests. It could be updated to include multiple operating systems as follows:
runs-on: ${{ matrix.os }}
strategy:
matrix:
os: [ubuntu-latest, windows-latest, macos-latest]
include:
- os: ubuntu-latest
flutter_path: /opt/hostedtoolcache/flutter
- os: windows-latest
flutter_path: [path-for-windows]
- os: macos-latest
flutter_path: [path-for-macos]
Lastly, the caching itself:
- uses: actions/cache@v1
with:
path: ${{ matrix.flutter_path }}
key: ${{ runner.os }}-flutter-install-cache-${{ env.flutter_version }}
Here, we utilize the Cache action. The path
is used for storing the actual path itself and will be different absolutely values depending on the operating system (e.g. C:\path\to\cache
versus /home/user/path/to/cache
). The key is the unique identifier for storing or retrieving the cache itself. If we left the flutter_version
variable off the end, we could end up testing with a different cached version than what we are specifying for flutter-action
.