Tuesday, December 27, 2011

How to Autogenerate App Version Number from GIT

Application needs a version number, naturally. It's publicly used to identify, which version customer is using (and reporting bugs about).

However there is a very important technical reason to take good care of version number: if you want to update application, the new version number must be bigger than the old one. Sounds easy, yet again...

Let's check the documentation:

CFBundleShortVersionString

CFBundleShortVersionString (String - iOS, Mac OS X) specifies the release version number of the bundle, which identifies a released iteration of the application. The release version number is a string comprised of three period-separated integers. The first integer represents major revisions to the application, such as revisions that implement new features or major changes. The second integer denotes revisions that implement less prominent features. The third integer represents maintenance releases.

The value for this key differs from the value for “CFBundleVersion,” which identifies an iteration (released or unreleased) of the application. This key can be localized by including it in your InfoPlist.strings files.
...and also:
CFBundleVersion

CFBundleVersion (String - iOS, Mac OS X) specifies the build version number of the bundle, which identifies an iteration (released or unreleased) of the bundle. This is a monotonically increased string, comprised of one or more period-separated integers. This key is not localizable.
Some lessons learned about version numbering:
  • 1.01 is same as 1.1
  • 1.10 is bigger than 1.2
  • 2.5 is smaller than 2.27
  • 2.50 is bigger than 2.27
  • It's a series of integer values separated by dots, NOT a single float number
  • I recall there was some max limit to single value, but can't find the reference. Please let me know, if you know about this
If app update has same version number as already installed version, strange things can happen: some of the resources might not be updated - or might be. It's a mystery! Beware!

SVN version control system contains a revision number, which tells how many commits has been submitted. Great candidate for automatic app version numbering, but GIT doesn't support it. GIT identifies source code updates by a unique hash code, which are not incremental in any way.

No worries, there is a work-around to get something similar from GIT version control system: count number of submits by yourself.

Xcode setup (using Xcode 4.2)

Select current target - Build Phases
Bottom right corner "Add Build Phase - Run Script"
Move "Run Script" before Compile Sources (drag and drop)

Copy to Run Script:
#!/bin/csh
git=/usr/local/git/bin/git
touch Info.plist
buildNum=`$git log --oneline | wc -l`
echo "#define BUILD_VERSION $buildNum" > InfoPlist.h
Change "Info.plist" to match your project Info.plist
Verify where the output file is generated, make sure it's "visible" i.e. inside project folder

Edit Info.plist file:

Bundle versions string, short (CFBundleShortVersionString): write manually your app version e.g. "1.0" (check below for GIT tag)

Bundle version (CFBundleVersion): BUILD_VERSION

Project - Build Settings - Packaging:
Info.plist Preprosessor Prefix File: InfoPlist.h
Preprosess Info.plist File: Yes

Yet again make sure you got (possible) path right!

Testing

Add this into AppDelegate.m didFinishLaunchingWithOptions:
    NSString *shortVersion = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleShortVersionString"];
    NSString *version = [[NSBundle mainBundle] objectForInfoDictionaryKey:@"CFBundleVersion"];
    NSLog(@"\nSystem: %@ %@\nModel: %@\nApp version: %@ (%@)",
         [[UIDevice currentDevice] systemName], [[UIDevice currentDevice] systemVersion],
         [[UIDevice currentDevice] model],
         shortVersion,version);
That't it, now your app version number is automatically generated from GIT. Just remember to make some changes before you release an update - or rather to check them in version control!

Credits: inspired  by "Using Git Versioning inside your XCode Project", check it for using "GIT tag" in automated version numbering.

No comments:

Post a Comment