Like with pretty much any other framework, keeping up with package upgrades in Flutter can get pretty tedious. I decided to see if I could make things a little less tedious over the weekend and I'd like to share a GitHub Action workflow that I came up with while experimenting.
What about Dependabot?
I'd actually be happy to use Dependabot but there isn't full support yet. Somebody is working on it at the moment though. I'm confident there will be full support one day, it's just a matter of time. For now though Dependabot isn't really a realistic option.
Using GitHub Actions
There was the option of creating an Action and putting it on the Actions Marketplace but I'm not entirely sure what that would involve yet and I'm not that committed to the idea yet either considering that there is work being done on the Dependabot front. So in the end I just decided to create a workflow with existing Marketplace Actions. Here's roughly the set of steps I wanted the workflow to use:
- Check out the repo
- Pull in cache data(so the next step runs a little faster)
- Setup Flutter CLI so it can be used in the next steps
- Run
flutter pub upgrade --major-versions
- Run
flutter pub get
- Run
flutter test
- (Optional) Capture the output of
flutter pub outdated
for later - If there are changes from (4) commit them to a new branch and open a PR
And obviously I'd want this workflow to run every so often so it would need to be scheduled with cron. In the end this is what I came up with:
name: Upgrade packages
on:
workflow_dispatch:
schedule:
- cron: "0 0 * * *"
env:
flutter_version: "2.2.2"
# A workflow run is made up of one or more jobs that can run sequentially or in parallel
jobs:
upgrade_packages:
# The type of runner that the job will run on
runs-on: ubuntu-latest
# Steps represent a sequence of tasks that will be executed as part of the job
steps:
# Checks-out your repository under $GITHUB_WORKSPACE, so your job can access it
- uses: actions/checkout@v2
- name: Cache Flutter dependencies
uses: actions/cache@v2
with:
path: /opt/hostedtoolcache/flutter
key: ${{ runner.OS }}-flutter-install-cache-${{ env.flutter_version }}
# Installs Flutter
- uses: subosito/flutter-action@v1
with:
flutter-version: ${{ env.flutter_version }}
channel: stable
# Upgrade packages(bump major versions)
- name: Run upgrade
run: flutter pub upgrade --major-versions
# Get/install packages
- name: Run get
run: flutter pub get
# Run tests
- name: Run tests
run: flutter test
# Captures the output of `flutter pub outdated`
- name: Check remaining outdated packages
id: check_outdated
run: |
content="$(flutter pub outdated)"
content="${content//'%'/'%25'}"
content="${content//$'\n'/'%0A'}"
content="${content//$'\r'/'%0D'}"
echo "::set-output name=outdated_info::$content"
# Opens a pull request with changes
- name: Create Pull Request
uses: peter-evans/create-pull-request@v3
with:
token: ${{ secrets.PAT }}
commit-message: Upgrade packages
title: Upgrade packages
body: |
Output for outdated check following upgrades:
${{ steps.check_outdated.outputs.outdated_info }}
branch: feature/update-packages
For this to work you need to generate a Personal Access Token
in your GitHub account's settings and then add that as a secret to your repository. You can learn more about this here. This is what the ${{ secrets.PAT }}
value represents in the last step.
You might have also noticed that I have this set to run everyday at 12am UTC. I'm going to tweak this later on but like I said I'm just experimenting with things at the moment and want to see if I run into any issues down the road. If I find some improvements I can make I will update this post. If you wanted to run this on a weekly schedule instead, you could use something like "0 0 * * Sun" instead(12am UTC every Sunday).
Caveats
The above workflow has been working pretty good for me for the last few days on some simple, small projects. That being said it is far from perfect.
First of all the above workflow won't upgrade your Pods on the iOS side of things. If you switch from ubuntu-latest
to macos-latest
you could run pod install --repo-update
in the ios directory of your project, I did try this out personally and it seemed to work okay - but keep in mind that workflows that use MacOS cost something like 10 times more than workflows that use Ubuntu. This would probably matter less if you were only running the workflow once a week or something like that.
Another thing you could tweak is the flutter pub upgrade --major-versions
command. This command will potentially pull in breaking changes because it will upgrade over major versions. You can opt out of this behaviour by just running flutter pub upgrade
instead.
One more shortcoming of the workflow above is that it only runs your tests. Your tests might not cover everything so adding a flutter build ios
or flutter build apk
might add an extra layer of security if the upgrades break your project. I think I'm going to look into all of these points as I keep tweaking the workflow.
Summing up
Like I said the workflow I introduced above definitely isn't perfect but I think that it's a good start and something that can be used to keep sane while we all wait for Dependabot support. If you're interested in more Flutter tips, I wrote another post about adding linting to a project a couple of days ago - you can find it here.
Top comments (0)