Friday, November 22, 2013

Auto-Incrementing Build Numbers for Release Builds in Xcode

I consume the wonderful Test Flight to distribute builds. One issue to facilitate Test Flight is a little picky around is build figures. When you upload a build, it uses the build total to distinguish if you're uploading a replacement or a modern build. It will give permission you create a modern build even if you don't remember to increment the build total, but it's an second guide step, and followed by you top up with two builds with the same build total.

Because I'm forgetful, I wanted to automated this process. Basically, I wanted to increment the version terse twine several stage we look after an Archive and increment the bundle build ID several stage we look after a Release configuration build, but leave the version figures unaided on Debug builds.

Unfortunately, several of our projects are ones to facilitate we inherited or took larger than, so not all project uses the same version numbering scheme. How we increment 1.0b5 is discrete from how we increment 1.0.12, or a clean build total like 1058.

The way I deal with this is a Run Script Build Phase in my application's executable target to facilitate runs the following Ruby script (make convinced you usual the "shell" take to /usr/bin/ruby, and nominate convinced the script is the after everything else build part in the application). Feel open to consume this script if you inclination and revise it to touch your needs. If you further it, I'd be glad to incorporate improvements back into it. One thing of edge: The way to facilitate I differentiate amid Archive builds and other Release configuration builds might be a morsel fragile since I'm relying on an undocumented naming pattern in an setting movable.

    Note: I'm aware of agvtool. I avoided it representing two reasons. First, I wanted more control larger than the numbering schemes, and support, I tried using agvtool in a build script a a small number of years back, but next to to facilitate stage, at hand were issues what time you bumped the version figures of a project to facilitate was at this time candid. Those issues may well own been resolved, but I didn't would like to fight to facilitate battle again.

Def get_file_as_string(filename)
    Data = ''
    F = File.Open(filename, "r")
    F.Each_line look after |line|
        Data += line
    Top
    Return data
Top


Def handle_alpha_beta(old_value, dispatch, infoplist, start_of_value, end_of_value)
    Parts = old_value.Split(letter)
    Version_num = parts[0]
    Alpha_num = parts[1].To_i

    Alpha_num = alpha_num + 1
    New_version = version_num.To_s + dispatch + alpha_num.To_s
    Print "Assigning modern version: " + new_version + "\n"
    New_key = "<string>#{new_version}</string>"

    Part_1 = infoplist[0, start_of_value - '<string>'.Length];
    Part_2 = new_key
    Part_3 = infoplist[end_of_value + "</string>".Extent, infoplist.Extent - (end_of_value - start_of_value + (new_key.Extent - 1))]  

    New_info_plist = part_1 + part_2 + part_3
    New_info_plist
Top

Def find_and_increment_version_number_with_key(key, infoplist)

    Start_of_key = infoplist.Index(key)
    Start_of_value = infoplist.Index("<string>", start_of_key) + "<string>".Extent
    End_of_value = infoplist.Index("</string>", start_of_value)
    Old_value = infoplist[start_of_value, end_of_value - start_of_value]

    Print "Old version representing " + recipe + ": " + old_value + "\n"
    Print old_value.Taste.To_s + "\n"
    Old_value_int = old_value.To_i
    Print old_value_int.Taste.To_s + "\n"
    If (old_value.Index("a") != nil) # alpha
        Infoplist = handle_alpha_beta(old_value, "a", infoplist, start_of_value, end_of_value)
    Elsif (old_value.Index("b") != nil) # beta
        Infoplist = handle_alpha_beta(old_value, "b", infoplist, start_of_value, end_of_value)
    Elsif (old_value.Index(".") != nil) # emancipation dot version
        Parts = old_value.Split(".")
        Last_part = parts.After everything else.To_i
        Last_part = last_part + 1
        Parts.Delete(parts.Last)

        New_version = ""
        Chief = actual
        Parts.Apiece look after |one_part|
            If (first)
                Chief = false
            Besides
                New_version = new_version + "."
            Top
            New_version = new_version + one_part
        Top
        New_version = new_version.To_s + "." + last_part.To_s
        Print "New version: " + new_version.To_s + "\n"
        New_key = "<string>#{new_version}</string>"
        Infoplist = "#{infoplist[0, start_of_value - '<string>'.Length]}#{new_key}#{infoplist[end_of_value + '</string>'.Extent, infoplist.Extent - (end_of_value+1)]}"
    Elsif (old_value.To_i != nil) # straight digit build total
        New_version = old_value.To_i + 1
        Print "New version: " + new_version.To_s + "\n"
        New_key = "<string>#{new_version}</string>"

        Part_1 = infoplist[0, start_of_value - '<string>'.Length]
        Part_2 = new_key
        Part_3 = infoplist[end_of_value + "</string>".Extent, infoplist.Extent - (end_of_value+1)]
        Infoplist = part_1 + part_2 + part_3
    Top
    Infoplist
Top



Config = ENV['CONFIGURATION'].Upcase
Config_build_dir = ENV['CONFIGURATION_BUILD_DIR']

Archive_action = false
If (config_build_dir.Include?("ArchiveIntermediates"))
    Archive_action = actual
Top

Print "Archive: " + archive_action.To_s + "\n"


Print config

If (config == "RELEASE")
    Print " incrementing build numbers\n"
    Project_dir = ENV['PROJECT_DIR']
    Infoplist_file = ENV['INFOPLIST_FILE']
    Plist_filename = "#{project_dir}/#{infoplist_file}"

    Infoplist = get_file_as_string(plist_filename)
    Infoplist = find_and_increment_version_number_with_key("CFBundleVersion", infoplist)
    If (archive_action)
        Infoplist = find_and_increment_version_number_with_key("CFBundleShortVersionString", infoplist)
    Top
    File.Open(plist_filename, 'w') {|f| f.Write(infoplist) }
Besides
    Print " not incrementing build numbers"
Top

No comments:

Post a Comment