When developing a mobile app, you’ll build your app multiple time. To differentiate each iteration from the other, we use a unique identifier called the build number. This is not to be confused with the version number.
Let’s say you’re working on your first app release. It’ll be the 1.0.0 version. 1.0.0 is your version number. Now when working on this version, you’ll find some bugs and will want to fix them. So you’ll build multiple iterations of the same 1.0.0 version. Each iteration will have a separate build number. This can be useful when debugging: if a tester is reporting a bug on your app 1.0.0, you need to know which build is containing the bug hence the build number.
On each of my projects, the build number for my iOS and Android app was always initialized to 1. Then, we had to increment it manually for each release. This means one could forget to update it and before building a new app release. We’d end up unable to upload the app with the same error: “An app with the same build number already exists”. How to manage this build number you say?
Apple and Google have one critical rule: the build number always has to increase and has a max value.
My first idea was to have a script that:
We have two problems with this solution.
First, we read the current build number from a file. Changing the build number location means updating our script.
Second, the build number does not bring any information. Imagine that you have an exception in Sentry related to build number 5. Well, that’s not the most helpful information. It’s just an arbitrary number.
So that’s off the picture. Let’s try to give our build number a meaning.
My second idea was to take the version number and compute the build number from it.
1.2.0 → 001002000
Now our build number has meaning, unfortunately, it is the same as the version number. And we still have to read the version number from a file. Furthermore, we can only build one app per app version. In this case, one app version = one build number.
So what can we do next?
We could try to add three digits at the end. Those digits would represent the number of times we built this app version. We’d end up storing the number of builds again.
What is always going forward? Not taking into account Back to the future, **time is a valid answer. So, why not use a timestamp as a build number?
But does it work with the max value constraint? Let’s do the math!
For Apple, 10^18s puts us 31 billion years in the future. I’m not much of a gambler but we should be safe.
For Google though, 2100000000 puts us in 2036. A bit too early in my opinion.
So how can we correct that? Let’s divide our timestamp by 10. It means that we won’t be able to upload apps to Google after 2635. I think it’s safe to say, the rules will have changed by then.
It also means that two versions of the same app, built in a 10 seconds interval, will have the same build number. A small comment and an explanation should take care of that.
At BAM, we use fastlane to help us deploy our app. I created a lane to increment the build number of your app. First, you should install the ++code>fastlane-plugin-android_versioning ++/code>
++pre>++code>bundle exec fastlane add_plugin fastlane-plugin-android_versioning ++/code>++/pre>
Then you can create the lane.
Finally, you can add it to your build workflow.
Now if you run the following command:
++pre>++code>bundle exec fastlane android ++/code>++/pre>
Before building the app, fastlane will update the build number.
My recommendation is to use a timestamp divided by 10 as a build number. This way: