Apple provides a tool called agvtool which stands for Apple Generic Versioning Tool. But, you generally don't want to use it while you have an Xcode project open, so incorporating it into a run script build phase is not advised.
I've found a few examples on the internet of scripts that incorporate the Subversion build number, but they didn't quite fit my needs. The ones I found were written in Perl and Python, and I'm not particularly comfortable in either of those languages, so I decided to write my own in Ruby, with which I have a much higher comfort level, rather than tweak those existing ones to meet my needs.
This script does not utilize the versioning system built-into Xcode, but rather directly sets the Bundle Version based on the Subversion version number. It also does a commit if there have been any changes since the last build before grabbing the version number from Subversion.
To use this script, right-click on your Target where you want to use this and select Add->New Build Phase->New Run Script Build Phase.
When the window opens up, set the Shell to
/usr/bin/rubyand then paste the following script into the window if you want to commit and increment on every build:
data = ''
f = File.open(filename, "r")
f.each_line do |line|
data += line
end
return data
end
# commit if any changes
%x[svn -m 'automated build commit' commit]
svn_version = %x[svnversion -n]
parts = svn_version.split(":")
new_version = parts[1]
# Figure out where the Info.plist file is
project_dir =
infoplist_file =
plist_filename = " /"
infoplist = get_file_as_string("/Users/jeff/dev/FlyPaper/Resources/Info.plist")
start_of_key = infoplist.index("CFBundleVersion")
start_of_value = infoplist.index("<string>", start_of_key)
end_of_value = infoplist.index("</string>", start_of_value) + "</string>".length
old_value = infoplist[start_of_value, end_of_value - start_of_value]
new_key = "<string> </string>"
new_info_plist = "\n"
File.open(plist_filename, 'w') {|f| f.write(new_info_plist) }
or use this script if you only want to commit and increment the build number on builds using the Release configuration:
data = ''
f = File.open(filename, "r")
f.each_line do |line|
data += line
end
return data
end
if == "Release"
# commit if any changes
%x[svn -m 'automated build commit' commit]
end
svn_version = %x[svnversion -n]
parts = svn_version.split(":")
new_version = parts[1]
# Figure out where the Info.plist file is
project_dir =
infoplist_file =
plist_filename = " /"
infoplist = get_file_as_string("/Users/jeff/dev/FlyPaper/Resources/Info.plist")
start_of_key = infoplist.index("CFBundleVersion")
start_of_value = infoplist.index("<string>", start_of_key)
end_of_value = infoplist.index("</string>", start_of_value) + "</string>".length
old_value = infoplist[start_of_value, end_of_value - start_of_value]
new_key = "<string> </string>"
new_info_plist = "\n"
File.open(plist_filename, 'w') {|f| f.write(new_info_plist) }
After you paste it in, close the window. You might want to rename the run script build phase to something more meaningful. You can do that by right-clicking on it and selecting Rename from the menu that pops up. Also, you need to drag the new build phase up so that it fires before the Copy Bundle Resources phase so that the commit happens before it builds the application. Otherwise, the application will always reflect the previous version number in the Get Info window.
That's all you have to do. Now, whenever you build or do a Release build, Xcode will commit your files to the Subversion repository if there have been changes, then set the bundle version to the value currently in Subversion. Now, this script has not been extensively tested. If you have problems, let me know about them, and I will try to fix any issues that arise.
No comments:
Post a Comment