【问题标题】:Better way of incrementing build number?增加内部版本号的更好方法?
【发布时间】:2012-03-04 17:26:02
【问题描述】:

我一直在使用 shell 脚本作为我的 Xcode 构建过程的一部分来增加 plist 文件中的构建号,但是它使 Xcode 4.2.1 经常崩溃(关于目标的错误不属于一个项目;我猜 plist 文件的更改在某种程度上使 Xcode 感到困惑)。

Shell 脚本这样做是为了使内部版本号仅在文件比 plist 文件更新时增加agvtool(因此只是构建并没有增加值):

if [ -n \"`find ProjDir -newer ProjDir/Project-Info.plist`\" ]; then agvtool -noscm next-version -all; else echo \"Version not incremented\"; fi

有没有办法增加不会破坏 Xcode 的内部版本号(在 plist 文件中或其他任何地方)?

最终编辑:我现在使用我刚刚在github 上公开的python 脚本来做这种事情。它没有很好的记录,但应该不难解决。作为奖励,这个 repo 还包含一个有用的脚本,可以自动将 3rd 方库捆绑到应用程序包中。

【问题讨论】:

  • 如果有人感兴趣:我稍微修改了脚本以使用十六进制数字而不是十进制数字 - gist.github.com/sascha/5398750
  • 您可以直接将此脚本添加为预构建操作,无需调用外部脚本。不要在构建阶段运行此脚本; Xcode 只会每隔一次构建复制更新的 plist。
  • 开箱即用我收到“权限被拒绝”错误,所以我想把这个问答指向遇到同样情况的其他人:stackoverflow.com/q/9850936/519030
  • 此脚本失败,退出代码为 1。谁能帮我解决这个问题?
  • @Tander 看起来您没有将 plist 文件作为参数提供给脚本。

标签: xcode shell version xcrun agvtool


【解决方案1】:

如果我正确理解你的问题,你想修改Project-Info.plist 文件,它是Xcode 标准项目模板的一部分?

我问这个的原因是Project-Info.plist 通常是在版本控制之下,修改它意味着它会被标记为,嗯,修改。

如果这对你来说没问题,那么下面的 sn-p 将更新内部版本号并将文件标记为在此过程中已修改,其中get_build_number 是一些脚本(即本例中的占位符)来获取(可能增加)您要使用的内部版本号:

#!/bin/sh

# get_build_number is a placeholder for your script to get the latest build number
build_number = `get_build_number`

/usr/libexec/PlistBuddy -c "Set :CFBundleVersion ${build_number}" ProjDir/Project-Info.plist

PlistBuddy 允许您在 plist 文件中设置任何键,而不仅仅是版本号。您可以创建所需的所有 plist 文件,并在需要时将它们包含在资源中。然后可以从包中读取它们。

至于你需要在about面板等地方显示版本,你也可以看看设置CFBundleGetInfoString和CFBundleShortVersionString。

【讨论】:

  • 我不需要 plist 文件中的 git commit(或标签),所以一个简单的递增系统就可以了(由agvtool 提供),但是该行为在构建期间修改 plist 会经常破坏 Xcode(因为删除脚本后它没有崩溃一次,当它每 3 个构建左右就崩溃时)。是否可以将版本信息放在另一个 plist 文件中,并将其包含在捆绑包中并可从应用程序访问?
  • 很棒的脚本 - 我更愿意将此与 Hugues BR 的建议结合起来,即仅在归档构建时使用它。保持较低的数字并忽略在发布之间执行的许多开发构建。
  • 什么是get_build_number?这只是一些占位符吗?
  • 是的,get_build_number 只是一个占位符 - 更新了答案以澄清。
【解决方案2】:

我尝试了修改后的程序,但没有成功,因为:-

  1. Xcode 4.2.1 更改了 .xcodeproj 中的 xcuserdata 子目录

  2. git 注意到 Project-Info.plist 中的先前更改

以下修改会导致这些被忽略,并且只标记真正的更改:-

if [ -n "$(find $dir \! -path "*xcuserdata*" \! -path "*.git" -newer $plist)" ]; then

【讨论】:

    【解决方案3】:

    感谢脚本。效果很好。

    我的 Info.plist 位于一个名称包含空格的子目录中,因此我必须修改运行脚本,并在 plist 路径周围加上引号:

    ${PROJECT_DIR}/tools/bump_build_number.sh "${PROJECT_DIR}/${INFOPLIST_FILE}"
    

    和 shell 脚本以同样的方式在所有路径周围加上引号:

    #!/bin/sh
    
    if [ $# -ne 1 ]; then
        echo usage: $0 plist-file
        exit 1
    fi
    
    plist=$1
    dir=$(dirname "$plist")
    
    # Only increment the build number if source files have changed
    if [ -n "$(find "$dir" \! -path "*xcuserdata*" \! -path "*.git" -newer "$plist")" ]; then
        buildnum=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "$plist")
        if [ -z "$buildnum" ]; then
            echo "No build number in $plist"
            exit 2
        fi
        buildnum=$(expr $buildnum + 1)
        /usr/libexec/Plistbuddy -c "Set CFBundleVersion $buildnum" "$plist"
        echo "Incremented build number to $buildnum"
    else
        echo "Not incrementing build number as source files have not changed"
    fi
    

    【讨论】:

    • 是的,这是有道理的。很高兴你发现它有用;从那以后我一直在使用 Xcode 4.{2,3,4,5} 时完全没有问题。
    • 如果我看到这个答案,我会为自己节省几个小时!另外,请注意,hte 内部版本号不能有小数,否则 BASH 会崩溃。
    【解决方案4】:

    您可能只想在归档(例如上传到 TF)时执行此操作。 否则你的版本号可能会很快上升..

    在方案(Product / Edit Scheme / Archive / Pre-Actions)中,您可以添加一个仅在您存档时才会执行的脚本。

    此外,您可能希望在每次增加应用版本时重置内部版本号。

    最后一件事,如果你改用存档,你可以安全地禁用:

    # if [ -n "$(find "$dir" \! -path "*xcuserdata*" \! -path "*.git" -newer "$plist")" ]; then
    ...
    # else
        # echo "Not incrementing build number as source files have not changed"
    # fi
    

    因为只有在您归档...

    时,内部版本号才会增加

    编辑:更正我所说的,存档中的预操作发生在构建之后(但在存档之前),因此构建号将在下一个存档中增加...但是您可以创建一个新方案并在构建中添加此操作这个新计划的(预行动)部分。并在您想创建新版本时使用此方案

    【讨论】:

    • 是的,它正在快速上升(目前 5500+),但这对我来说不是问题;这只是一个数字。有趣的是,有多少次 Cmd-B/Cmd-R 在任何工作之前被击中...
    【解决方案5】:

    整个条目非常有帮助。我使用了这个技巧,但将我的脚本设置为 GIT 中的提交后挂钩,因此每次成功提交后 CFBundleVersion 都会递增。挂钩脚本位于 .git/hooks 中。在项目目录中留下了一个日志。

    这符合我最基本的标准。我希望能够从 GIT 中提取一个版本并重建我之前的确切版本。在构建过程中完成的任何增量都不会这样做。

    这是我的脚本:

    #!/bin/sh
    #
    # post-commit
    #
    # This script increments the CFBundleVersion for each successful commit
    #
    
    plist="./XYZZY/XYZZY-Info.plist"
    buildnum=$(/usr/libexec/Plistbuddy -c "Print CFBundleVersion" "$plist")
    if [ -z "$buildnum" ]; then
        exit 1
    fi
    buildnumplus=$(expr $buildnum + 1)
    /usr/libexec/Plistbuddy -c "Set CFBundleVersion $buildnumplus" "$plist"
    
    echo $(date) "- Incremented CFBundleVersion to" $buildnumplus >> hookLog.txt
    

    【讨论】:

    • 我有同样的要求,这就是为什么如果源文件已被修改,内部版本号仅递增。我发现它工作得很好,并且自创建以来不必对 bump_build_number.sh 脚本进行更改。
    【解决方案6】:

    我用过这个清单。它按预期工作。 https://gist.github.com/sekati/3172554 (所有功劳归原作者所有)

    我随时间修改的脚本。

    xcode-versionString-generator.sh,

    xcode-build-number-generator.sh

    由于这些要点正在帮助开发社区,因此我制作了 GitHub 项目。所以让我们好好开发它。 这是 GitHub 项目: https://github.com/alokc83/Xcode-build-and-version-generator

    我已经更新了这两个脚本的代码一点点增强。 而不是使用下面从 GitHub 获取最新的内容

    对于版本:

    # xcode-version-bump.sh
    # @desc Auto-increment the version number (only) when a project is archived for export. 
    # @usage
    # 1. Select: your Target in Xcode
    # 2. Select: Build Phases Tab
    # 3. Select: Add Build Phase -> Add Run Script
    # 4. Paste code below in to new "Run Script" section
    # 5. Check the checkbox "Run script only when installing"
    # 6. Drag the "Run Script" below "Link Binaries With Libraries"
    # 7. Insure your starting version number is in SemVer format (e.g. 1.0.0)
    
    # This splits a two-decimal version string, such as "0.45.123", allowing us to increment the third position.
    VERSIONNUM=$(/usr/libexec/PlistBuddy -c "Print CFBundleShortVersionString" "${PROJECT_DIR}/${INFOPLIST_FILE}")
    NEWSUBVERSION=`echo $VERSIONNUM | awk -F "." '{print $3}'`
    NEWSUBVERSION=$(($NEWSUBVERSION + 1))
    NEWVERSIONSTRING=`echo $VERSIONNUM | awk -F "." '{print $1 "." $2 ".'$NEWSUBVERSION'" }'`
    /usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString $NEWVERSIONSTRING" "${PROJECT_DIR}/${INFOPLIST_FILE}"
    

    对于构建:

    # xcode-build-bump.sh
    # @desc Auto-increment the build number every time the project is run. 
    # @usage
    # 1. Select: your Target in Xcode
    # 2. Select: Build Phases Tab
    # 3. Select: Add Build Phase -> Add Run Script
    # 4. Paste code below into new "Run Script" section
    # 5. Drag the "Run Script" below "Link Binaries With Libraries"
    # 6. Ensure that your starting build number is set to a whole integer and not a float (e.g. 1, not 1.0)
    
    buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")
    buildNumber=$(($buildNumber + 1))
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
    

    【讨论】:

    • 这将总是增加内部版本号,我希望它只在源文件更改时增加。这只是我目前使用的脚本,安全检查较少,对变化的辨别能力也较差。
    • XCode 5:编辑器(菜单栏)→添加构建阶段→添加复制文件构建阶段:
    • @trojanfoe :您可以将此脚本作为提交后挂钩运行。这种情况下,它只会在您将代码提交到 repo 时增加内部版本号。下面来自 LostInTheTrees 的回答是您可能想做的更多事情。
    • @Alix 链接的 shell 脚本现在与此处发布的完全不同。要仅在进行存档构建时增加内部版本号,您可以使用我制作的要点,非常基于上面 Alix 的脚本,在这里:gist.github.com/mattpotts/abcffea6d08ad45739ef
    【解决方案7】:

    其中一些解决方案的一个问题是Launch Services only recognizes four five major digits in the bundle version。我有一个内部版本号为数千的项目,所以我想使用一些不太重要的数字。

    这个 Perl 脚本会增加项目中的所有 Info.plist,而不仅仅是当前目标的那个,所以构建号都保持同步。它还使用一个补丁数字和两个次要数字,因此 build 1234 的版本为 1.23.4。我将它用作预构建行为,因此它适用于我构建的所有项目。

    该脚本非常暴力,但它确实对我有用。

    #!/usr/bin/perl
    
    use strict;
    use warnings;
    use v5.12.0;
    
    use Dir::Iterate;
    
    for my $plist_file(grepdir { /-Info.plist$/ } '.') {
        my $build = `/usr/libexec/PlistBuddy -c "Print CFBundleVersion" '$plist_file'`;
        chomp $build;
    
        next unless $build;
    
        # Strip dots
        $build =~ s/\.//g;
        $build =~ s/^0//g;
    
        # Increment
        $build++;
    
        # Re-insert dots
        $build =~ s/^(\d{0,4}?) (\d{0,2}?) (\d{0,1}?)$/$1.$2.$3/x;
    
        # Insert zeroes
        $build =~ s{(^|\.)\.}{${1}0.}g;
    
        system qq(/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $build" '$plist_file');
    }
    

    【讨论】:

    • 您引用的帖子指出'实际上,LS 需要以下格式:nnnnn[.nn[.nn]][X] 其中 n 是 0-9 的数字,正方形括号表示可选组件,X 是任何不以数字开头的字符串。 X 在存在时被忽略。' - 所以这是 99999 构建。对于大多数项目来说应该足够了..?
    • @Jay 我显然将其误读为四位数。哎呀。 (不过,如果您的开发风格涉及大量调整和重建,那么经过多年的项目开发,您可以达到 100,000 次构建并不是不可想象的。)
    • @BrentRoyal-Gordon True - 我已经调整了我的构建脚本以增加仅用于发布配置的构建.. 即使我可能从未达到接近 10k 的构建,即使我使用了 10 多年的遗留产品为新的 Cocoa 项目提供大量的头部空间确实感觉很好;-)
    【解决方案8】:

    我建议使用autorevision。

    Xcode 允许头文件(可以在构建时自动生成,而不是在 vcs 中自动生成)提供将在构建时在 info.plist 中扩展的值。您可以在 autorevision website 上找到有关设置的演练。

    Autorevision 有一个针对这些类型的头文件的输出类型,可以在这些情况下提供帮助。

    【讨论】:

    【解决方案9】:

    FWIW - 这是我目前用来增加内部版本号的方法仅适用于发布版本(包括存档)。在 Xcode 5.1 下运行良好。

    直接在 Xcode 中将 sn-p 复制/粘贴到 Run script 构建阶段:

    buildnum=$(/usr/libexec/PlistBuddy -c "Print :CFBundleVersion" "$PRODUCT_SETTINGS_PATH")
    
    if [ "$CONFIGURATION" = "Release" ]; then
    buildnum=$((buildnum + 1))
    echo "Build number updated to $buildnum"
    /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildnum" "$PRODUCT_SETTINGS_PATH"
    fi;
    

    【讨论】:

    • 如何增加 CFBundleVersion?在 Xcode 5.1 中,它是一个格式为“1.0”的字符串?
    • 终于有人做对了 :) 为什么我要关心我在开发设备上运行的每个构建?发布(以及向测试人员发布)计数,而不是“嗯,向左移动 2px”构建。
    【解决方案10】:

    您可能想查看我一直在开发的一个名为 Xcodebump 的新工具。它可以处理更新 CFBundleShortVersionString 和 CFBundleVersion。作为最后一步,它还将签入到 git 并标记提交以匹配那些 CFBundle 值。

    Xcodebump project 位于此处:

    https://github.com/markeissler/Xcodebump

    【讨论】:

      【解决方案11】:

      我已经搞砸了很多关于这个问题的答案,但没有一个让我很满意。不过,我终于想出了一个我非常喜欢的混合物!

      我们只需将构建产品的版本号设置为 Git 提交的数量。这不会影响您的源代码管理,因为脚本只会改变构建的产品。

      将此“运行脚本”构建阶段添加到构建阶段的末尾:

      if [ "${CONFIGURATION}" = "Release" ]; then
          buildNumber=$(git rev-list --count head)
          /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${TARGET_BUILD_DIR}/${INFOPLIST_PATH}"
      fi
      

      将您项目中的 Info.plist 版本设置为您想要的任何版本,在构建发布版本时它永远不会被使用。我将我的设置为AUTOMATED 或DEVELOPMENT,所以当我运行开发版本时很清楚。

      就是这样!构建的应用程序将具有不断增加的内部版本号。 (只要你总是在同一个分支上构建。)

      为什么我喜欢这种方法:

      • 简单
      • 不会污染 Git 版本历史
      • CFBundleVersion 是全自动的
      • 漂亮的版本号可以随时修改

      其他说明:

      • 如果您的项目中有应用程序扩展,只需在这些目标上设置相同的构建脚本即可。这将使所有版本号保持自动化和同步。 App Store 要求扩展版本与您的主应用相匹配。

      【讨论】:

      • 将版本号保留在版本控制的 plist 文件之外是最好的方法,特别是如果您每个版本都有一个分支并且有时需要合并或挑选。谢谢!
      • 你可以用git rev-list --count HEAD代替git rev-list HEAD | wc -l | tr -d ' '。
      • 嗯。我发现如果您使用fastlane 以这种方式上传自动构建,您会得到: ERROR ITMS-90058: "This bundle is invalid. The value for key CFBundleVersion [DEVELOPMENT] in the Info.plist file must be a period-separated最多三个非负整数的列表。”
      • 我不确定它应该去哪里,我把第一个脚本作为第一个构建阶段,最后一个脚本作为最后一个构建阶段,它对我有用。
      • 你绝对可以使用这个解决方案提交 Info.plist——这就是重点。 Info.plist 始终设置并签入,版本号设置为“DEVELOPMENT”,在构建过程中临时更改,然后再次设置为“DEVELOPMENT”,因此 Info.plist 是稳定的。
      【解决方案12】:

      这是我的解决方案。 如果你和我一样:终端友好,比如 ruby​​,比如语义版本控制,试试这个。

      创建一个名为 Rakefile 的文件,其中包含以下内容:

      require "xcodeproj"
      require "versionomy"
      
      XCODEPROJECT = "MyProject.xcodeproj"
      INFOPLISTFILE = "MyProject/MyProject-Info.plist"
      
      $UPDATES = [:major,:minor,:tiny]
      $UPDATES.each { |part|
        desc "increment #{part} part of version"
        task "increment:#{part}" do |task|
          version=`/usr/libexec/Plistbuddy -c "Print CFBundleVersion" #{INFOPLISTFILE}`.chomp
          version=Versionomy.parse(version)
          version=version.bump(part)
      
          # I use the same string for CFBundleVersion and CFBundleShortVersionString for now
          `/usr/libexec/PlistBuddy -c "Set :CFBundleVersion #{version}" #{INFOPLISTFILE}`
          `/usr/libexec/PlistBuddy -c "Set :CFBundleShortVersionString #{version}" #{INFOPLISTFILE}`
          print "version upgraded to #{version}\n"
        end
      }
      

      准备:gem install xcodeproj versionomy

      随时运行:rake increment:major 或 rake increment:minor 或 rake increment:tiny。

      【讨论】:

        【解决方案13】:

        我使用最新的 SVN 版本作为内部版本号。如果你更改了构建目录中的 Info.plist,你不会影响到源 Info.plist:

        # use the last SVN revision as the build number:
        Info_plist="$BUILT_PRODUCTS_DIR/$CONTENTS_FOLDER_PATH/Info.plist"
        defaults write "${Info_plist}" CFBundleVersion `svn stat -u | awk '/'"Status against revision:"'/ {print $4}'`
        

        【讨论】:

          【解决方案14】:

          在Wil Gieseler's solution 的基础上,我只想做出一项改变。他的解决方案将 git 提交的计数放入内部版本号中。有用,但仍然很难找到创建该构建的实际提交。我不太在意内部版本号是否单调增加,因此我放弃了该要求,以便我可以更轻松地访问生成给定二进制文件的提交。

          为此,我将他的第一个脚本修改为:

          # Set the build number to the decimal conversion of the short version of the current git SHA
          
          # Get the short version of the current git SHA in hexadecimal
          SHA=$(git rev-parse --short @)
          # Uppercase any alphabetic chars in SHA (bc doesn't like lowercase hex numbers)
          UPPERCASE_SHA=$(tr '[:lower:]' '[:upper:]' <<< "$SHA")
          # Use bc to convert the uppercase SHA from hex to decimal
          BUILD_NUM=$(bc <<< "ibase=16;obase=A;$UPPERCASE_SHA")
          # Set our build number to that
          /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $BUILD_NUM" "${PROJECT_DIR}/${INFOPLIST_FILE}"
          
          # To convert a build number back to a usable git SHA, run the following, substituting the build number for <build number>
          # bc <<< "ibase=10;obase=16;<build number>"
          

          这会将当前 git SHA 的短版本转换为十进制。十六进制字符不能很好地满足 Apple 的内部版本号要求,这就是我必须这样做的原因。要将其转换回来,您只需运行以下代码:

          SHA=$(bc <<< "ibase=10;obase=16;<build number>")
          

          在 bash 中,&lt;build number&gt; 是您从二进制文件中获得的内部版本号。然后,只需运行git checkout $SHA,就可以了。

          因为这是对Wil Gieseler's solution 的改编,如上所述,您还需要以下构建后脚本:

          # Set the build number to "DEVELOPMENT"
          /usr/libexec/PlistBuddy -c "Set :CFBundleVersion DEVELOPMENT" "${PROJECT_DIR}/${INFOPLIST_FILE}"
          

          让你的 git 历史保持干净。

          【讨论】:

          • 那么,如果您将 git 信息写入 Info.plist,它本身是由 git 跟踪的,那么它是如何工作的?
          • @trojanfoe 正如我在答案顶部提到的,这个答案是对 Wil Gieseler 解决方案的改编。因此,它需要在那里使用相同的构建后脚本。我已明确将其添加到答案中。
          【解决方案15】:

          我目前使用的脚本非常基于上面的Alix's。我在下面的改编中添加了一项检查,以仅在发布/存档构建上执行自动增量。

          如果不进行该更改,则会出现版本控制冲突,因为每个开发人员都将以自己的速度增加内部版本号。而且随着内部版本号的不断变化,git 历史记录会受到不必要的污染。

          # xcode-build-bump.sh
          # @desc Auto-increment Xcode target build number every time the project is archived
          # @src stackoverflow.com/a/15483906
          # @usage
          # 1. Select: your Target in Xcode
          # 2. Select: Build Phases Tab
          # 3. Select: Add Build Phase -> Add Run Script
          # 4. Paste code below in to new "Run Script" section
          # 5. Drag the "Run Script" below "Link Binaries With Libraries"
          # 6. Insure that your starting build number is set to a whole integer and not a float (e.g. 1, not 1.0)
          
          if [ "Release" != "${CONFIGURATION}" ]
          then
              exit 0
          fi
          
          buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")
          buildNumber=$(($buildNumber + 1))
          /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
          

          它也可以作为GitHub gist 提供(以更容易复制和粘贴的格式)。

          【讨论】:

            【解决方案16】:

            您可以使用Apple's generic versioning。基本上,您所要做的就是从托管 .xcproj 文件的目录中调用 agvtool next-version -all。欲了解更多详情,请查看上面的网址。

            【讨论】:

            • 这个解决方案的问题是从项目的脚本中调用 agvtool 会取消你的构建。除非您能找到解决方法,否则这不是一个好的解决方案。
            【解决方案17】:

            我不知道哪种方式最好,但我会发布 Apple 的答案以防万一有人在搜索它...

            据此Apple's Q&A post:

            使用 agvtool 自动化版本和内部版本号

            版本和内部版本号键分别指定应用程序的营销和内部版本。 agvtool 是一个命令行工具,可让您自动将这些数字递增到下一个最高数字或特定数字。

            内部版本号标识您的应用程序的未发布或已发布版本。它以CFBundleVersion(捆绑版本)的形式存储在应用程序的 Info.plist 中。

            您必须在您的 Xcode 项目中完成以下步骤:

            1. 启用 agvtool

            导航到目标的“构建设置”窗格,然后为所有构建配置更新它,如下所示:

            • 将当前项目版本设置为您选择的值。

            您的 Xcode 项目数据文件 project.pbxproj 包含一个 CURRENT_PROJECT_VERSION(当前项目版本)构建设置,它指定项目的当前版本。 agvtool 在 project.pbxproj 中搜索CURRENT_PROJECT_VERSION。如果CURRENT_PROJECT_VERSION 存在则继续运行,否则停止运行。它的值用于更新内部版本号。

            • 将版本控制系统设置为 Apple Generic。

            默认情况下,Xcode 不使用任何版本控制系统。将版本控制系统设置为 Apple Generic 可确保 Xcode 将所有 agvtool 生成的版本信息包含在您的项目中。

            1. 设置您的版本和内部版本号

            agvtool 在您的应用程序的 Info.plist 中搜索您的版本和内部版本号。如果它们存在,它会更新它们,否则什么都不做。确保您的 Info.plist 中存在 CFBundleVersion(捆绑版本)和 CFBundleShortVersionString(捆绑版本字符串,短)键,如下图所示:

            退出 Xcode,然后在终端应用程序中导航到包含 .xcodeproj 项目文件的目录,然后再运行以下任何命令。 .xcodeproj 项目文件包含被agvtool 使用的project.pbxproj。 (这是您可以在脚本而不是命令行中运行的部分。)

            更新版本号

            要将版本号更新为特定版本,请运行

            xcrun agvtool new-marketing-version <your_specific_version>
            

            例如:将版本号更新为 2.0

            xcrun agvtool new-marketing-version 2.0
            

            更新内部版本号

            要自动增加内部版本号,请运行

            xcrun agvtool next-version -all
            

            要将应用程序的内部版本号设置为特定版本,请运行

            xcrun agvtool new-version -all <your_specific_version>
            

            例如:将内部版本号设置为 2.6.9

            xcrun agvtool new-version -all 2.6.9
            

            奖励:

            要查看当前版本号,运行

            xcrun agvtool what-marketing-version
            

            要查看当前的内部版本号,请运行

            xcrun agvtool what-version
            

            【讨论】:

            • 这个问题是 agvtool 将中止 xcode 构建,因此它无法在构建阶段集成为脚本。
            • 你不能把bump via agvtool 放在方案的构建预操作中吗?
            • 我将其添加为用于在方案中构建的操作后脚本。这样,它会在构建成功后递增,并且不会取消构建。
            【解决方案18】:

            我通过以下方法更新build number。

            $INFO_FILE是plist文件的路径。 而$build_number 是该建筑物的新版本号。

            /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $build_number" "${INFO_FILE}"
            

            一般来说,我的$build_number由major和minor部分组成。 minor 来自项目信息。所以我描述了如何生成major 部分。

            ## Composed by `major` and `minor`. 
            ## `minor` is parsed from project information. It's another story.
            ## Examples: `21.1`, or `21.1.3`
            build_number="${major_number}.${minor_number}"
            

            我有两种策略来决定$build_number。

            第一策略

            此策略使用git tag 计数来决定build number 的major。如果项目有53标签,会按照shell脚本返回53。

            一般来说,它在增加。并且会强制开发者在发布前打上git标签。

            major_number=$(git tag -l | wc -l | grep -oE "\d+")
            

            第二个策略

            让Jenkins CI 系统决定major 部分。它有一个环境变量BUILD_NUMBER。在 CI 系统上构建时,它会自动增加。此信息对于跟踪 CI 系统上的项目历史非常有用。

            major_number=${BUILD_NUMBER}
            

            【讨论】:

              【解决方案19】:

              这是一个更新的版本。这适用于 Xcode 9.3.1、iOS 11。

              单击应用程序目标中的“构建阶段”,单击 + 图标以添加新的运行脚本,然后在框中粘贴此代码。

              buildNumber=$(/usr/libexec/PlistBuddy -c "Print CFBundleVersion" "${PROJECT_DIR}/${INFOPLIST_FILE}")
              buildNumber=$(($buildNumber + 1))
              /usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
              

              进入 Info.plist 文件并将 'Bundle version' 设置为 1,并将 'Bundle versions string, short' 设置为 1,您应该进行设置。

              在视图中使用 Info.plist 构建项目,您应该会看到 Bundle 版本(内部版本号)发生了变化。

              • 请注意,从 Xcode 9.3.1 开始,您将无法从常规选项卡中看到这些更改,但会在您归档构建时以及在 Info.plist 中看到这些更改

              【讨论】:

                【解决方案20】:

                我觉得我找到了我的部落。部落,我希望你对 VersionX 感到开心。

                十年前,当我在一个包含超过 25 个 Xcode 项目的工作区工作时,我借此机会将版本自动化并构建字符串更新到一个可能看起来很荒谬的程度,如果你只维护一个或两个项目不定期更新。

                X 版:

                • 知道构建类型(发布/调试)
                • 在构建时从存储库收集信息(包括 git 支持,但可以针对 hg、svn 或您使用的任何内容进行自定义)
                • 提供易于定制的精美营销版本字符串(在 App Store 实施约定之前有更多变化),因此您可以使用 git 标签约定自动增加包含“beta”符号的字符串。李>
                • 包括一个类,该类填充了包含版本和提交信息的实例变量。这对于填充您的 about 面板和使用预先填充的信息构建日志字符串、崩溃报告或用户电子邮件错误报告非常有用。

                制作很有趣。我学到了很多关于 Xcode 构建系统的知识。

                这是 VersionX 可以自动生成的精美版本和构建字符串类型的示例。

                VersionX 1.0.1 β7(c5959a3“干净”)

                营销版本: VersionX 1.0.1 β7 “1.0.1 派生自提交的标签,而 “Beta 7”由提交计数或构建计数自动生成(例如)。

                构建版本:(c5959a3 “干净”) 显示简短的提交哈希,并通知您构建目录有零个未提交的更改。

                VersionX (source at GitHub) - a baroque system for automatically incrementing version and build strings in Xcode projects.

                The VersionX Documentation.

                【讨论】:

                  【解决方案21】:

                  我觉得使用Automating Version and Build Numbers Using agvtool 最方便。

                  试试这个:

                  1. 按照上面链接的 Apple 文档中的说明进行配置。
                  2. 添加 脚本 作为项目的预操作 -> 编辑方案... -> 存档(或其他,如果您愿意)
                  3. 设置:提供来自&lt;your_app_target&gt; 的构建设置

                  脚本(第一行是可选的):

                  exec > ${PROJECT_DIR}/prebuild.log 2>&1
                  cd ${PROJECT_DIR}
                  xcrun agvtool next-version -all
                  cd -
                  

                  【讨论】:

                    【解决方案22】:

                    让我们以 Apple 自己的方式来做这件事。 每次成功构建后都会增加构建号

                    我将引导您浏览 5 张图片,您只需浏览一下即可。

                    1. 当您选择位于 Stop_build_button 右侧的项目名称时,从下拉列表中选择“编辑方案...”。 Check First Step

                    2. 从左侧菜单展开“构建”选项并选择“后操作” Check Second Step

                    3. 您可以在此处添加您想要在成功构建程序后执行的所需代码(脚本)。这是我们必须添加少量代码以使我们的自动化完美运行的地方。 >> 1. 从左侧角落选择“添加 (+)”按钮以添加新脚本文件 >> 2. 现在从下拉列表中选择“新运行脚本操作” Check Third Step

                    4. 它有 3 个字段 >> 1. 已经为您分配了 shell >> 2. 现在为“提供您的构建设置”选择您的项目名称。 >> 3. 添加脚本有一个很大的字段,只需复制并粘贴此代码即可:Check Fourth Step

                      PLIST="${PROJECT_DIR}/${INFOPLIST_FILE}" PLB=/usr/libexec/PlistBuddy LAST_NUMBER=$($PLB -c "打印 CFBundleVersion" "$PLIST") NEW_VERSION=$(($LAST_NUMBER + 1)) $PLB -c "设置:CFBundleVersion $NEW_VERSION" "$PLIST"

                    5. 完成第 4 步后,只需选择“关闭”关闭窗口,我们必须执行最后一步,转到项目文件菜单中的“plist.info”文件并确保“捆绑版本”键位于'Key' 部分大部分包含数值 Check Fifth Step

                    【讨论】:

                      猜你喜欢
                      • 1970-01-01
                      • 2020-05-13
                      • 1970-01-01
                      • 1970-01-01
                      • 2016-07-23
                      • 2011-08-21
                      • 2011-03-06
                      • 1970-01-01
                      • 2017-09-13
                      相关资源
                      最近更新 更多