Automating Flutter App Versioning Using Fastlane Plugin
Tags: flutter, mobile, devops, fastlane
Published: 2020-10-01 09:10:23

If you’ve ever developed mobile applications and published them to their stores, then you are aware of the specific rules of versioning an app. Those rules revolve around two properties: App versioning and incrementing build number. **Versioning is a critical component of an app upgrade and maintenance strategy.**
## Getting our Facts Right
### App Versioning
On iOS, the app version is presented by the `CFBundleShortVersionString` key that must correspond to semantic versioning (https://semver.org/). This key is a machine-readable string composed of one to three period-separated integers, such as 10.14.1. The string can only contain numeric characters (0-9) and periods.
Each integer provides information about the build version in the format **[Major].[Minor].[Patch]:**
**Major:** A major revision number.
**Minor:** A minor revision number.
**Patch:** A maintenance release number.

Source:
https://developer.apple.com/documentation/bundleresources/information_property_list/cfbundleversion

On Android, the app version is presented by the `versionName` inside of the `build.gradle file`. Android doesn’t enforce any rules when it comes to specifying the name.

### Build number
Build number (`CFBundleVersion` on iOS, `versionCode versionCode` on Android) is an identificator that is used only to determine whether one version of an app is more recent than the other, with the higher number indicating a more recent version. Both Google Play Store and Apple AppStore use the build number to protect against downgrades by preventing users from installing an app with a lower build number than the version currently installed on their device. On Android, that number is an integer, but on iOS, that number can be presented both as an integer or as a semantic version.

## Flutter’s Way of Handling Stuff
The Flutter team has decided to handle this very neatly; they have a property in `pubspec.yaml` called `version` that follows this pattern: `{major}.{minor}.{patch}+{version} `Therefore, in order to publish our app with the app version of 1.2.4 and build number of 5, our `pubspec.yaml` would have a `version` property that looks like this: `version: 1.2.4+5 `The next time the application goes through the build process, those values are applied. However, the question is, how we can automate this whole process of versioning?

## flutter_version_manager plugin for Fastlane — The Fun Part!
Fastlane is the easiest way to build and release mobile apps. It has been used widely by the mobile application developers community. It’s written in Ruby, is open source and it has great support for developing your own custom plugins. That being said, I present to you the `flutter_version_manager plugin` for Fastlane: https://github.com/rubiconba/fastlane-plugin-flutter-version-manager

(Please note that this is approach is very subjective as this is the method I use to handle versioning of an app)

This plugin heavily resides on having a git repository and at least one commit as build number is applied through timestamp of HEAD commit. By leveraging the power of git, we no longer have to worry about incrementing `versionCode/CFBundleVersion`. As for the app version, `version.yml` file that we had to create manually should be used as a single source of truth. Now, there are a couple of ways of handling an app version using this plugin:
1. Increment a version manually and call `-apply` on the fastlane plugin. `-apply` command will automatically apply all the changes to `pubspec.yaml`
2. Use `-major`, `-minor`, or `-patch` to bump semantic version. It automatically calls `-apply` and updates the `pubspec.yaml`.

That being said, a DevOps engineer has power over versioning. For example, he may create a `patch` pipe that runs on `patch` branch that will call `deploy_as_patch` lane which automatically bumps patch version and deploys the latest version. You can find an example of Fastfile [here](https://github.com/rubiconba/fastlane-plugin-flutter-version-manager/blob/master/fastlane/Fastfile). Full documentation is available in a [git repository](https://github.com/rubiconba/fastlane-plugin-flutter-version-manager).
This plugin is open-source and any contributions to it are more than welcome. Happy DevOpsing! ^^

-------
_Originally published at https://www.rubicon-world.com._