Apps with flavors
If your app has flavors (Android product flavors, or Xcode schemes on iOS and
macOS), each flavor gets its own Shorebird app, with its own releases and
patches. You pass --flavor to every shorebird release and shorebird patch,
plus --target when the flavor has its own entry point.
Flavors work on Android, iOS and macOS. On Windows and Linux,
shorebird release and shorebird patch don’t take --flavor: passing it
stops with Flavors are not supported on this platform., and without it they
use app_id.
This page uses two flavors, development and production. To test a patch
before your users get it, you don’t need a separate flavor: publish it to a
staging track and promote it once it
works. If you use a flavor per customer brand, see
White Labeling.
Set up the flavors
Section titled “Set up the flavors”Android
Section titled “Android”Add the flavors to android/app/build.gradle.kts (or build.gradle):
applicationIdSuffix gives each flavor its own package name, so both can be
installed side by side. Leave it out if a service you use, such as Firebase,
expects one package name. To show each flavor’s label, set
android:label="${applicationLabel}" on the <application> element in
android/app/src/main/AndroidManifest.xml. Flutter’s
Android flavors guide covers the
rest.
iOS and macOS
Section titled “iOS and macOS”Create an Xcode scheme for each flavor, with build configurations for it, as Flutter’s iOS and macOS flavors guide describes. Each flavor needs an Xcode scheme of the same name. Shorebird 1.6.135 and newer check this before building, and stop with an error like this one if a scheme is missing:
Use the same flavor names on every platform. Shorebird keeps one list of flavors
for the project, so a flavor named production on Android and iOS is one
Shorebird app with an Android and an iOS release, while prod on Android and
production on iOS would be two apps.
Add Shorebird to the flavors
Section titled “Add Shorebird to the flavors”Run shorebird init in your project:
It detects your flavors, creates a Shorebird app for each one, and lists them
under flavors: in shorebird.yaml. What app_id holds depends on the
project:
- In a new project where Android and iOS both have flavors,
app_idis the first flavor’s app. - In a new project where Android or iOS has no flavors,
app_idis a separate app for builds without a flavor. - In a project that already has a
shorebird.yaml,shorebird initadds an app for each flavor that isn’t listed yet and keeps your existingapp_id.
For an existing project, shorebird.yaml then looks something like:
A build with --flavor checks for patches with that flavor’s app ID. A build
without --flavor uses app_id, and shorebird release and shorebird patch
warn about it:
To add a flavor later, set it up as above and run shorebird init again. It
prints New flavors detected: with the new flavor’s name and adds it to
shorebird.yaml.
Release each flavor
Section titled “Release each flavor”Release each flavor you ship, with its --flavor. If the flavor has its own
entry point, pass it with --target; without it, Flutter builds
lib/main.dart.
Upload each flavor’s build to that flavor’s store listing. On Android, the app
bundle is at
build/app/outputs/bundle/productionRelease/app-production-release.aab; on iOS,
the IPA is in build/ios/ipa.
To try a release on a device, pass the flavor to shorebird preview:
Patch a flavor
Section titled “Patch a flavor”Build the patch with the same --flavor, --target, --dart-define and
--dart-define-from-file values as the release it patches:
--flavor picks which Shorebird app gets the patch. --target and the Dart
defines are compiled into your Dart code, so a patch built without them runs a
different entry point or configuration from the release.
Each flavor is its own app, so a fix that every flavor needs is a patch for each flavor, built from the same code. To check a patch before users get it, publish it to a staging track and promote it; see Staging patches.
Flavors in CI
Section titled “Flavors in CI”In CI, run the release or patch once per flavor. A shell loop works on any CI
system that has SHOREBIRD_TOKEN set (see the
CI guides):
--release-version=latest patches each flavor’s most recently updated release.
If a newer release might still be in store review, pass the version your users
have instead; see Patching.
In GitHub Actions, a matrix runs a job per flavor, and the action’s args input
passes the flavor and target:
See GitHub Integration for the action’s inputs.
Examples
Section titled “Examples”- The flavors sample is an app with two flavors on Android, iOS and macOS.
- The multi_dimensional_flavors sample uses more than one flavor dimension.