I don't think anyone actually enjoys editing a plists, whether its in Xcode plist editor or the down and dirty XML. So has a result it was the perfect opportunity to get familiar with xcode's build process, and how to tie external scripts into it.
I use 3 segment version numbers (1.1.1), where the first digit is the major version, second digit is the minor version, and the 3rd digit is the build. For the benefit of the team, i wanted to have the latest commit hash in the build number so that people could quickly reference it and know whats going on.
With some direction from this post by Duane Sibilly i was able to hack together the below.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
# XCode 4 auto-versioning script for Git | |
# Inspired by the work of Axel Andersson, Marcus S. Zarra and Matt Long | |
# http://valthonis.net/u/19 | |
""" | |
NOTE: Due to its use of build environment variables, this | |
script will only work from inside XCode's build process! | |
""" | |
import os | |
import csv | |
from subprocess import Popen, PIPE | |
from Foundation import NSMutableDictionary | |
# get the short commit hash from git | |
cmd = "/usr/bin/git rev-parse --short HEAD" | |
commit_hash = Popen(cmd, shell=True, stdout=PIPE).stdout.read() | |
#remove a trailing line feed | |
commit_hash = commit_hash.rstrip() | |
#load the plist | |
info_plist = os.environ['PRODUCT_SETTINGS_PATH'] | |
# Open the plist and write the short commit hash as the bundle version | |
plist = NSMutableDictionary.dictionaryWithContentsOfFile_(info_plist) | |
full_version = plist['CFBundleVersion'] | |
#Break the version into parts | |
parts = full_version.split('.') | |
#Clean up the last part | |
# %d ([A-9]*) | |
currentDotRevision = parts[2].split(' ')[0]; | |
dotRevision = int(currentDotRevision) + 1 | |
if os.environ['CONFIGURATION'] == 'Debug': | |
full_version = '%d.%d.%d (%s)' % ( int(parts[0]), int(parts[1]), dotRevision, commit_hash ) | |
else: #For releases drop the version hash | |
full_version = '%d.%d.%d' % ( int(parts[0]), int(parts[1]), dotRevision ) | |
print 'Built => ' + full_version | |
#Actual version | |
plist['CFBundleVersion'] = full_version | |
#git revision | |
plist['CFBundleShortVersionString'] = full_version | |
#Write the file to disk | |
plist.writeToFile_atomically_(info_plist, 1) |