Xcode 4: updating CFBundleVersion for each build using the Git version of repo commit

I use Xcode 4 in conjunction with Git and would like to increase the CFBundleVersion value in Info.plist for each assembly. The value for the CFBundleVersion key should be updated to the number of the last commit I made in the Git repository.

I found that a python script that works well, but unfortunately does not update Info.plist in my Xcode project - it just updates Info.plist in "BUILT_PRODUCTS_DIR".

Does anyone have an idea how to get Xcode 4 to fetch the latest commit version and put this information in the Info.plist project?

Thanks!

+6
source share
3 answers

The version string must be in the format [xx]. [yy]. [zz] where x, y, z are numbers.

I deal with this using git tag to give specific commits of meaningful tag numbers for x and y (e.g. 0.4), and then through the build phase of script z gets the number of commits since the last tag since git describe returned.

Here is the script that I adapted from this one . It can be added directly 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}'" 
+7
source

This works great 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 
+1
source

@damian Thanks for the script, it works well.

But after that I had the following problem. Every time after commit when creating a project, I have a change in git. I had a decision to ignore the plist file, but I do not want this.

Now I am adding your script to the pre-commit hook in git instead of the xcode build phase. The only problem with this is that my script cannot get PROJECT_DIR and INFOPLIST_FILE, so I had to write them hardcoded in scipt. I could not find how to get env variables from an xcode project.

It works well :)

0
source

Source: https://habr.com/ru/post/890295/