Xcode 4: Update CFBundleVersion on each build using Git repo commit version

前端 未结 3 1550
悲哀的现实
悲哀的现实 2020-12-28 10:40

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

相关标签:
3条回答
  • 2020-12-28 11:13

    @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 :)

    0 讨论(0)
  • 2020-12-28 11:23

    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}'"
    
    0 讨论(0)
  • 2020-12-28 11:37

    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
    
    0 讨论(0)
提交回复
热议问题