Jack Morris
Automating away CFBundleVersion
29 Apr 2020

I've been working on a small app to burn through the quarantine blues recently (more details maybe coming soon), and I wanted to setup a nice auto-versioning system to manage CFBundleVersion.


If you check in your info.plist, you'll see CFBundleVersion, and CFBundleShortVersionString. What's the difference?


Updating CFBundleVersion automatically is seemingly a common desire, and I found a few different approaches. Most stem from incrementing the number on each build, or by deriving CFBundleVersion from the current time, however I wasn't a fan of those since I didn't want the numbers to vary wildly between builds that I actually end up uploading to App Store connect.

I may build 100 times whilst playing around with something, or it may take me 2 weeks to produce something substantial enough to warrant a new upload. I didn't want either to pollute my CFBundleVersion.

I went with the following in the end:

That's it! I can then push, and I have a workflow on Bitrise that'll build and upload to App Store Connect when there's a change on the Deploy branch.

Here's the script itself. You'll need to seed it with an initial tag (e.g. "0") so that it has something to base the next tag off of.


PLIST_PATH=<path to your Info.plist>

git checkout master

lastBuildNumber=$(git tag | sort --human-numeric-sort | tail -n 1)
newBuildNumber=$(expr $lastBuildNumber + 1)

/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $newBuildNumber" "${PLIST_PATH}"
git add ${PLIST_PATH}
git commit -m "Deploy: #${newBuildNumber}"

git branch -f deploy master
git tag -a ${newBuildNumber} -m "Build ${newBuildNumber}"

(Use at your own risk, of course).

So, whilst not fully automated, this gives me an easy way to indicate that this commit should constitute a "version". Having the tags equal to the CFBundleVersions also makes it super easy to find the state at a specific version.