If having CI/CD is great, having CI/CD with the minimal amount of setup is even better right?

This article aims to show how to build and deploy Flutter projects with AppCenter

Building Flutter projects on AppCenter

If having CI/CD is great, having CI/CD with the minimal amount of setup is even better right?

As part of our working week at Rock Solid Knowledge, we are given 10% of our time to work on 'fun' projects that help us learn new technologies. One such project is BrewDay, our craft brew recipe sharing application.

After much discussion and prototyping, we decided to use the Flutter framework to build iOS and Android applications. Flutter is beautifully simple to get started with, and the documentation is very thorough.

Installing Flutter

To install on your desired platform, Windows, macOS or Linux, follow the instructions here:

https://flutter.io/docs/get-started/install

Once installed and flutter doctor executes error free you are ready to go.

AppCenter

Having used AppCenter for a Xamarin project for the Bridgnorth Arts Trail mobile application, I was impressed at its ease of configuration and the number of features available for free. It was immediately obvious that I should investigate if it could be used to build Flutter projects.

If you're not familiar with Microsoft's AppCenter and you create mobile applications, you are missing a hidden treasure. AppCenter will replace HockeyApp after Microsoft's acquisition and adds many new features.

  • Continuous integration from GitHub, Bitbucket (RSK's preference) and Visual Studio Team Services.
  • UI Testing that tests that the latest build of your app reaches the startup page. Scripted UI tests can be added at additional cost.
  • Continuous delivery serving the built apps to distribution groups that are part of the AppCenter organisation, or deployed to both Apple and Google app stores.
  • Crash and error reporting from the apps. Detailed crash and error logs and metrics in a friendly UI.
  • Analytics showing app usage and user sessions and events can be triggered in the apps to acquire anonymous usage information. All captured data can be exported to Application Insights for further analysis and longer retention.
  • Push notifications can be sent to your apps straight from AppCenter and limited to a defined audience.

There are many other features, such as webhooks, bug tracking, and email notifications and is well worth investigating if you are creating mobile applications.

Obviously, there are limits on what you get for free. Data is retained for 90 days and you are allowed 1 consecutive build and 4 build hours per month. For many small projects, this is more than enough.

Building Flutter on AppCenter

After a quick Google, I found build scripts for both iOS and Android provided by Microsoft for this very purpose. AppCenter allows you to run Bash (.sh) scripts for iOS and Android apps.

There are 3 stages during the build where a script can be executed. The correctly named script in either project/android/app/ for Android or project/ios/ for iOS will be executed at the correct point in the build process

Stage Bash script filename
Post Clone appcenter-post-clone.sh
Pre Build appcenter-pre-build.sh
Post Build appcenter-post-build.sh

You can find the scripts here:

https://github.com/Microsoft/appcenter-build-scripts-examples/tree/master/flutter

Create Flutter Project

Create a new flutter app using

flutter create appcenter_example

AppCenter Packages

Using your favorite editor, edit your pubspec.yaml file and add appcenter:, appcenter_analytics: and appcenter_crashes: to the dependencies section.

Save the file and run the following in the project directory.

flutter packages get

As shown on the AppCenter dart package site (https://pub.dartlang.org/packages/appcenter), there is a small amount of configuration necessary. For our purposes, we need to import the new packages in our source file, like so.

import 'package:appcenter/appcenter.dart';
import 'package:appcenter_analytics/appcenter_analytics.dart';
import 'package:appcenter_crashes/appcenter_crashes.dart';

In our main.dart file we need to start the AppCenter services and this can be completed like so. The guid for each app platform can be found when the AppCenter app configuration is created. Change the placeholders for the correct guids to ensure the crash reporting and analytics is correctly reported.

final ios = defaultTargetPlatform == TargetPlatform.iOS;

var app_secret = ios ? "iOSGuid" : "AndroidGuid";
await AppCenter.start(app_secret, [AppCenterAnalytics.id, AppCenterCrashes.id]);

Add AppCenter Build Scripts

Copy the build scripts found at https://github.com/Microsoft/appcenter-build-scripts-examples/tree/master/flutter to the iOS and Android directories. On macOS, I use wget in the project directory to save the files to the correct directories.

I have included the contents of both files to show exactly what the scripts execute. Clone Flutter, install with flutter doctor and then build for the respective platform. The Android script also copies the output APK to a directory so that AppCenter can find the output.

iOS

wget https://raw.githubusercontent.com/Microsoft/appcenter-build-scripts-examples/master/flutter/ios-build/appcenter-post-clone.sh -P ios/
#!/usr/bin/env bash
#Place this script in project/ios/

# fail if any command fails
set -e

# debug log
set -x
cd ..

git clone -b dev https://github.com/flutter/flutter.git

export PATH=`pwd`/flutter/bin:$PATH

flutter doctor

echo "Installed flutter to `pwd`/flutter"

flutter build ios --release --no-codesign

Android

wget https://raw.githubusercontent.com/Microsoft/appcenter-build-scripts-examples/master/flutter/android-build/appcenter-post-clone.sh -P android/app/
#!/usr/bin/env bash
#Place this script in project/android/app/

cd ..

# fail if any command fails
set -e

# debug log
set -x

cd ..

git clone -b dev https://github.com/flutter/flutter.git

export PATH=`pwd`/flutter/bin:$PATH

flutter doctor

echo "Installed flutter to `pwd`/flutter"

flutter build apk --release

#copy the APK where AppCenter will find it
mkdir -p android/app/build/outputs/apk/; mv build/app/outputs/apk/release/app-release.apk $_

For the Android project to be detected by AppCenter, remove (or comment out) gradle-wrapper.jar, gradlew and gradlew.bat from the .gitignore file created by flutter with the new project.

gitignore

Configure AppCenter

Now let's go to AppCenter (https://appcenter.ms/apps) and add a new organization

add-organization

Give the organization a name

add-organization-dialog

Add an app to the organization for iOS. Set OS to iOS and Platform to Objective-C/Swift to allow the build script added earlier to execute correctly.

add-ios-app

Next, add an app for Android. Set OS to Android and Platform to Java/Kotlin as the build configuration.

add-android-app

In the overview section of our app there is a set of instructions for configuring the different AppCenter services. The only important information we require from this page is the Guid to add to the flutter project. Copy the Guid for iOS and Android and replace the placeholders in the AppCenter dart package configuration.

overview

Next, from either your iOS or Android app, connect AppCenter to your favorite repository. The repo will be shared between all apps in an organization.

build-connect-to-repo

Now in each app, you should see a list of branches in your repository. The little cog on the right of the branch allows us to add a build configuration.

branches

For iOS, configure the build as shown, uploading your app provisioning profile and signing certificate to allow the iOS app to be tested on a real device in AppCenter and distribute via AppCenter, TestFlight or the AppStore.

ios-configuration

For Android, configure the build as shown, uploading your keystore file and entering your keystore password, key alias, and key password. The keystore can also be configured in Gradle. If this is the case for your application tick the My Gradle settings are entirely set to handle signing automatically checkbox. Distribution for the Android app is available through AppCenter, direct download or Google Play.

android-configuration

When you hit Save & Build AppCenter will start to build from the last commit on the configured branch. You can configure many builds from different branches, with only one concurrent build per app. Configuring different distribution groups for different branches allow you to simply configure both beta and release branches to distribute to testers or end users.

If all goes well, once the build completes you will be able to view the basic UI test you are provided for free. AppCenter will ensure the app at least starts up, giving confidence that the build worked correctly and there are no glaring errors in the code.

test-results

Any crashes found in apps built in AppCenter will be captured in the Diagnostics area, and analytic information recorded using the appcenter_analytics flutter package will appear in the Analytics section. As mentioned previously, the retention period is only 90 days, although the data can be exported to Azure blob storage or Application Insights for longer retention and analysis.

Profit!

Now you have your CI/CD complete in just a few easy steps, the only thing left to do is count your new found cash income when your app launches into the app stores, or not as the case may be. Best of luck!

About the author

Related links