Versioning with Flutter

Please note: This is my first article since I left university. So please be patient.
2nd note: My Java/Kotlin/Swift/Dart is much better than my English ;-)

Does it bother you to increase the version in the Android as well as in the iOS part again and again? You can be helped.

Every time you want to create a new version you have to increase the build number in Android as well as in iOS: You have to modify the app/build.gradle file and the Info.plist file.

Would it be nice to have just one place to do that?

A usual Dart project has a version property in its pubspec.yaml file but a Flutter project doesn’t. Till now.

The following depends on #16857. Currently, it isn’t merged, so you have to wait a little bit. But as we say in Germany: Vorfreude ist die schönste Freude (I hat this sentence. Parents tell this to their child’s before Christmas when the children can’t wait to get the presents).

Okay, we assume it is merged.

If you now create a new Flutter project the pubspec.yaml file has a version property like this:

name: hello
description: A new Flutter project.
version: 1.0.0+1
dependencies:
flutter:
sdk: flutter
...

Flutter uses this value to set the version in both Android and iOS for you. You only need to call flutter run or flutter build or press the play button in IntelliJ / Android Studio / the IDE of your choice.

The Format

Flutter expects an exact format of the version property.

It has two parts separated by a +. The first part is the build name (versionName Android / CFBundleShortVersionString iOS) and the second part is the build number (versionCode Android / CFBundleVersion iOS).

The build name can have up to 3 integers separated by dots. The build number is just one integer.

How to modify them?

You can still edit the pubspec.yaml file by hand but sometimes you need a way to modify them automatically for example when your CI builds a new version.

To change the version automatically, you have two options —-build-name and --build-number. These two options are options of the flutter build command:

flutter build apk --build-name=1.0.3
flutter build apk --build-number=3
flutter build apk --build-name=1.0.3 --build-number=3

I use Fastlane to do my CI builds. My fastfile looks like this:

lane :alphaBuild do
  # Return the number of commits in current git branch
build_number = number_of_commits()
  Dir.chdir ".." do
sh("flutter", "packages", "get")
sh("flutter", "clean")
sh("flutter", "build", "apk", "--build-number=#{build_number}")
end
end

How to update an old Flutter project?

You can also do the above with an old flutter project, but you need to make some changes.

Flutter Part

All you have to do is to add the version property to your pubspec.yaml file. It should look like this:

name: hello
description: A new Flutter project.
version: 1.0.0+1 # add this
dependencies:
flutter:
sdk: flutter
...

Android Part

Every time you call flutter run or flutter build Flutter updates the local.properties file. You only need to use the values in your app/build.gradle file.

To do that modify you app/build.gradle file that it looks like this:

Read the values from the local.properties file (lines 14 till 22) and use them (line 39 and 40).

iOS Part

flutter run and flutter build updates the Generated.xcconfig file too, just use its values.

Change the CFBundleShortVersionString value to $(FLUTTER_BUILD_NAME) (line 18) and the CFBundleVersion value to $(FLUTTER_BUILD_NUMBER) (line 21).

Open the project in Xcode, select the Build Settings tab of the Runner target and search for versioning. Change the value of Current Project Version to $(FLUTTER_BUILD_NUMBER).

Bonus

The following depends on #16934. Currently, it isn’t merged, so you have to wait a little bit. But as we say in Germany…

Now that our Flutter project knows the version it would be nice to access it to show it somewhere, in an about dialog for example.

With #16934 Flutter generates a lib/build_config.g.dart file which looks like this:

// GENERATED CODE - DO NOT MODIFY BY HAND

class BuildConfig {
static const bool kDebug = true;
static const String kModeName = "debug";
static const String kFlavor = null;
static const String kVersionName = "1.0.0";
static const int kVersionNumber = 1;
}

You can now easily use it to show the version or to do other fancy things depending on the build, for example, if it is a debug build or which flavor was build.