【问题标题】:Xcode 4: Update CFBundleVersion on each build using Git repo commit versionXcode 4:使用 Git 存储库提交版本更新每个构建的 CFBundleVersion
【发布时间】:2011-09-13 02:47:11
【问题描述】:

我将 Xcode 4 与 Git 结合使用,并希望在每次构建时增加 Info.plist 中的 CFBundleVersion。 CFBundleVersion 键的值应该更新为我对 Git 存储库的最后一次提交的编号。

我发现that python 脚本运行良好,但不幸的是没有更新我的 Xcode 项目中的 Info.plist - 它只是更新了“BUILT_PRODUCTS_DIR”中的 Info.plist。

有谁知道如何让 Xcode 4 获取最新提交的版本并将该信息放入项目的 Info.plist 中?

谢谢!

【问题讨论】:

    标签: xcode git


    【解决方案1】:

    版本字符串必须采用 [xx].[yy].[zz] 格式,其中 x、y、z 是数字。

    我通过使用git tag 来处理这个问题,为 x 和 y 赋予特定的提交有意义的标签号(例如 0.4),然后通过脚本构建阶段,z 获取自最后一个标签以来的提交数,如返回git describe.

    这是我改编自this one 的脚本。它可以作为构建阶段直接添加到目标中(shell/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}'"
    

    【讨论】:

      【解决方案2】:

      @damian 感谢脚本运行良好。

      但之后我遇到了以下问题。每次在我构建项目时提交后,我都会在 git 中进行更改。我有忽略 plist 文件的解决方案,但我不希望这样。

      现在我将您的脚本添加到 git 中的 pre-commit 挂钩中,而不是 xcode 构建阶段。唯一的问题是我的脚本无法获取 PROJECT_DIR 和 INFOPLIST_FILE 所以我不得不用 scipt 将它们硬编码。我找不到如何从 xcode 项目中获取环境变量。

      效果很好:)

      【讨论】:

      • 您可能想要做的是将您的 plist 作为模板放入您的 repo 中,忽略 repo 中的实际 plist,然后在构建时生成它。这样,您的存储库中就没有自动生成的东西。
      【解决方案3】:

      这对我很有效

      #!/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
      

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2013-02-28
        • 1970-01-01
        • 1970-01-01
        • 2014-09-06
        • 1970-01-01
        • 2011-08-03
        • 2012-09-16
        相关资源
        最近更新 更多