Versioning is a critical component of your app upgrade & maintenance strategy.
If you’re a developer with a certain level experience you know that it’s not a good idea to keep constants like API endpoints, Secret keys hard coded around the codebase.
To address this what we normally do is to keep an .env file with configurations as key value pairs & access them universally at any point in the codebase.
What if we can do the same thing for versioning a react native application?
In this article we’re going to take a look at how we can configure versioning in react native applications to make the development flow smoother.
As a bonus at the end of the article we’ll see how we need to alter an app automation platform such as visual studio app center with these changes.
Let’s get started 🏁
We’ll start with a fresh react native project. I prefer to use react native community-built typescript template.
npx react-native init RNVersioner --template react-native-template-typescript
In order to access custom constants in react native we need to install react-native-config.
yarn add react-native-config
(Setup guidelines can be different depending on the react native version you’re using. Adjust them accordingly.)
This library exposes config variables to your JS/TS code in React Native, supporting iOS, Android and Windows. It advocates for twelve-factor configuration which summed up, is:
Apps sometimes store config as constants in the code. This is a violation of twelve-factor, which requires strict separation of config from code. Config varies substantially across deploys, code does not.
Next, we’ll create a .env.dist file and include versioning values there. Most of the applications use semantic versioning (semver). Also, there can be release flavors (alpha, beta, etc.). Considering that,
Next, we’ll change platform specific codes that needs to be changed in order to make this work. We’ll be focusing on Android & iOS in this article for the sake of simplicity.
Changing Android version name and version number
Android has two settings available to define version information.
- VersionCode : This is a positive integer used as an internal version number. This number is used only to determine whether one version is more recent than another, with higher numbers indicating more recent versions. This is not the version number shown to users. The Android system use versionCode value to protect against downgrades by preventing users from installing an APK with a lower versionCode than the version currently installed on their device.
(⚠️ Warning: The greatest value Google Play allows for versionCode is 2100000000.)
- VersionName : This is the string used as the version number shown to users.
For more information on android versioning, read android developer guide on publishing versions.
We can define these two values either on Android Manifest file or in app/build.gradle. But we need to follow a versioning schema to generate versionCode & versionName. So, we’ll include this in the gradle configurations.
Above is a gradle recipe I discovered after referring many articles. You can customize according to your own choice.
iOS Version Number & Build Number
Unlike in android, for iOS version and the build numbers work together to uniquely identify a particular App Store submission for an app. These two values reside in Info.plist file as follows.
- Version number is saved with the key CFBundleShortVersionString
- Build number is associated with the key CFBundleVersion
For additional information & guide on version numbers & build numbers refer this archived technote.
To expose environment variables to info.plist there are some extra steps that needs to be followed. You can refer them over here at react-native-config setup guide.
Once that’s done you can modify info.plist similar to below.
That’s pretty much it.
Now in order to run the application in debug mode or to generate a release .apk or .ipa a copy of .env.dist needs to be made with required adjustments.
cp .env.dist .env
Make sure to include .env in your .gitignore to avoid unnecessary changes.
Displaying version name in application
This is straightforward. However, as a good case practice I keep an environment variable accessor with a caching mechanism.
You can invoke this getAppVersionName utility function in any of your components in order to display the version name.
Bonus : Connecting to an automation platform
Let’s take a look at how we can work with App Center to change our application builds.
I’m assuming that you have a prior experience on connecting app center to a repository and setting up the build pipeline for a react native project.
So we’ll be skipping a few steps ahead from setting up an app center project & running your first build ⏭️
App center provides build scripts to customize your builds. In order to make our application work now we need to make a copy of .env.dist and update the environment variables. We can use Post-clone or Pre-build scripts for this.
Now all we need is to update app center build configurations.
Now you are in charge of managing versions of your builds via App center.