I\'m using Xcode 4 in combination with Git and would like to increment the CFBundleVersion in Info.plist on each build. The value for the key CFBundleVersion should be updat
@damian Thank you for the script it works well.
But after then I had following problem. Every time after a commit when I build the project then I have changes in git. I had the solution to ignore the plist file but I don't want that.
Now I add your script into pre-commit hook in git instead of xcode build phase. The only problem with that is my script can not get PROJECT_DIR and INFOPLIST_FILE so I had to write them hard coded in scipt. I could not find how to get the env variables from a xcode project.
It works well :)
The version string needs to be of the format [xx].[yy].[zz] where x, y, z are numbers.
I deal with this by using git tag
to give specific commits meaningful tag numbers for x and y (eg 0.4), and then via a script build phase, z gets the number of commits since the last tag, as returned by git describe
.
Here's the script, which I adapted from this one. It can be added straight to the target as a build phase (shell
is /usr/bin/env ruby
):
# add git tag + version number to Info.plist
version = `/usr/bin/env git describe`.chomp
puts "raw version "+version
version_fancy_re = /(\d*\.\d*)-?(\d*)-?/
version =~ version_fancy_re
commit_num = $2
if ( $2.empty? )
commit_num = "0"
end
fancy_version = ""+$1+"."+commit_num
puts "compatible: "+fancy_version
# backup
source_plist_path = File.join(ENV['PROJECT_DIR'], ENV['INFOPLIST_FILE'])
orig_plist = File.open( source_plist_path, "r").read;
File.open( source_plist_path+".bak", "w") { |file| file.write(orig_plist) }
# put in CFBundleVersion key
version_re = /([\t ]+<key>CFBundleVersion<\/key>\n[\t ]+<string>).*?(<\/string>)/
orig_plist =~ version_re
bundle_version_string = $1 + fancy_version + $2
orig_plist.gsub!(version_re, bundle_version_string)
# put in CFBundleShortVersionString key
version_re = /([\t ]+<key>CFBundleShortVersionString<\/key>\n[\t ]+<string>).*?(<\/string>)/
orig_plist =~ version_re
bundle_version_string = $1 + fancy_version + $2
orig_plist.gsub!(version_re, bundle_version_string)
# write
File.open(source_plist_path, "w") { |file| file.write(orig_plist) }
puts "Set version string to '#{fancy_version}'"
This works perfectly for me
#!/usr/bin/ruby
require 'rubygems'
begin
require 'Plist'
rescue LoadError => e
puts "You need to install the 'Plist' gem: [sudo] gem install plist"
exit 1
end
raise "Must be run from Xcode" unless ENV['XCODE_VERSION_ACTUAL']
GIT = "/usr/bin/env git"
PRODUCT_PLIST = File.join(ENV['BUILT_PRODUCTS_DIR'], ENV['INFOPLIST_PATH'])
HASH = `#{GIT} log -1 --pretty=format:%h`
BUNDLE_VERSION = "CFBundleVersion"
if File.file?(PRODUCT_PLIST) and HASH
# update product plist
`/usr/bin/plutil -convert xml1 \"#{PRODUCT_PLIST}\"`
info = Plist::parse_xml(PRODUCT_PLIST)
if info
info[BUNDLE_VERSION] = HASH
info["GCGitCommitHash"] = HASH
info.save_plist(PRODUCT_PLIST)
end
`/usr/bin/plutil -convert binary1 \"#{PRODUCT_PLIST}\"`
# log
puts "updated #{BUNDLE_VERSION} to #{HASH}"
puts "HEAD: #{HASH}"
end