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
.
CFBundleVersion
?If you check in your info.plist
, you'll see CFBundleVersion
, and CFBundleShortVersionString
. What's the difference?
CFBundleShortVersionString
is the user-visible version number. This has to line up with the versions that you've created on App Store Connect. Some people go with the standard <major>.<minor>
, others use something like <year>.<relase number>
. Since it'll change pretty infrequently, I'm happy managing this manually.CFBundleVersion
is an internal identifier for the build. As long as it's in the correct format (see docs), you can put pretty much anything you like here. The important thing is that you can have multiple builds with the same CFBundleShortVersionString
by using separate CFBundleVersion
s.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:
Deploy
.CFBuildVersion
.CFBundleVersion
, commit, and move Deploy
to point at this new commit.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.
#!/bin/zsh
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 CFBundleVersion
s also makes it super easy to find the state at a specific version.