Skip to content

Instantly share code, notes, and snippets.

What would you like to do?
Automatic Git revision stamping for Xcode projects
# Xcode auto-versioning script for Git by Steve Madsen.
# Adapted from Subversion script by Axel Andersson.
# This is a Ruby script. Use /usr/bin/ruby as the shell.
build_counter_file = 'build-counter'
raise "#{$0}: Must be run from Xcode" unless ENV['BUILT_PRODUCTS_DIR']
def development?
ENV['CONFIGURATION'] !~ /Ad Hoc|App Store/
def local_modifications?
`git ls-files -m` != ""
build_counter = rescue 0
unless development?
raise "#{$0}: local modifications present for a production build!" if local_modifications?
build_counter += 1, 'w') { |f| f.printf "%d", build_counter }
unless system "git commit -m 'increment build counter' #{build_counter_file}"
raise "#{$0}: Git commit of #{build_counter_file} failed: #{$?.exitstatus}"
info = "#{ENV['BUILT_PRODUCTS_DIR']}/#{ENV['WRAPPER_NAME']}/Info.plist"
info_xml = `plutil -convert xml1 '#{info}' -o -`
raise "#{$0}: reading Info.plist failed: #{$?.exitstatus}" unless $?.success?
info_xml.gsub! %r{([\t ]+<key>CFBundleVersion</key>\n[\t ]+<string>\d+\.\d+).*?(</string>)}, "\\1.#{build_counter}\\2"
IO.popen("plutil -convert binary1 - -o '#{info}'", 'w') { |plutil| plutil << info_xml }
raise "#{$0}: writing Info.plist failed: #{$?.exitstatus}" unless $?.success?

This comment has been minimized.

Copy link
Owner Author

commented Jul 18, 2012

This script should be used in an Xcode custom build phase to automatically increment a build counter for Mac and iOS production builds. I first discussed this script in a blog post at

Detection of Ad Hoc and App Store builds is done using new configurations. I clone the Release configuration and make the necessary changes (for Ad Hoc: optional entitlements; for both: signing with distribution keys).

This script will force a build failure if it detects local modifications to tracked files for Ad Hoc or App Store builds.

The build counter is stored in a file called build-counter and is automatically committed. It is used as the third component of CFBundleVersion in your Info.plist file. (You can change where it is placed by modifying the regular expression on line 31.)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
You can’t perform that action at this time.