增加内部版本号的更好方法?

tro*_*foe 133 shell xcode version agvtool xcrun

我一直在使用shell脚本作为我的Xcode构建过程的一部分来增加plist文件中的内部版本号,但是它使得Xcode 4.2.1经常崩溃(关于不属于项目的目标的错误;我猜更改plist文件会以某种方式混淆Xcode).

shell脚本执行此操作,以便只有agvtool当文件比plist文件更新时才会增加构建号(因此只是构建时没有增加值):

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

有没有办法增加不破坏Xcode 的构建号(在plist文件中,或其他任何地方)?

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

Wil*_*ler 69

我在这个问题上弄了很多答案,但没有一个人对我很满意.但是,我终于想出了一个我非常喜欢的混合物!

有两个步骤,一个在构建阶段,一个在构建阶段.

一开始:

# Set the build number to the count of Git commits
buildNumber=$(git rev-list HEAD | wc -l | tr -d ' ')
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "${PROJECT_DIR}/${INFOPLIST_FILE}"
Run Code Online (Sandbox Code Playgroud)

在末尾:

# Set the build number to "DEVELOPMENT"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion DEVELOPMENT" "${PROJECT_DIR}/${INFOPLIST_FILE}"
Run Code Online (Sandbox Code Playgroud)

查看Xcode中的Info.plist,您会看到版本号是"开发",但构建的应用程序将具有不断增加的内部版本号.(只要你总是在同一个分支上进行构建.)

将版本号设置回最后的常量字符串可防止通过构建应用程序来更改Info.plist文件.

为什么我喜欢这种方法:

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

  • 您可以使用`git rev-list --count HEAD`而不是`git rev-list HEAD | wc -l | tr -d''`. (13认同)

Ali*_*lix 38

我已经使用了这个神奇的怪物并且按预期工作. https://gist.github.com/sekati/3172554 (所有功劳归原作者所有)

我修改过的Sctipts随着时间的推移.

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}"
Run Code Online (Sandbox Code Playgroud)

用于构建:

# 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}"
Run Code Online (Sandbox Code Playgroud)


Mon*_*olo 29

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

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

如果你没问题,那么下面的代码片段将更新内部版本号,并在过程中将文件标记为已修改,其中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
Run Code Online (Sandbox Code Playgroud)

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

至于您需要在about窗格和其他位置显示版本,您还可以查看设置CFBundleGetInfoStringCFBundleShortVersionString.

  • 什么是get_build_number?这只是一些占位符吗? (5认同)

Los*_*ees 14

整个条目非常有用.我使用了这个技巧但是将我的脚本设置为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
Run Code Online (Sandbox Code Playgroud)


For*_*nja 14

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

根据Apple的问答帖子:

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

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

内部版本号标识应用程序的未发布或已发布版本.它作为CFBundleVersion(Bundle版本)存储在应用程序的Info.plist中.

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

  1. 启用agvtool

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

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

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

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

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

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

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

agvtool在您的应用程序的Info.plist中搜索您的版本和内部版本号.如果它们存在则更新它们,否则不执行任何操作.确保Info.plist中存在CFBundleVersion(Bundle版本)和CFBundleShortVersionString(Bundle版本字符串,简短)键,如下图所示:

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

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

更新版本号

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

xcrun agvtool new-marketing-version <your_specific_version>
Run Code Online (Sandbox Code Playgroud)

例如:将版本号更新为2.0

xcrun agvtool new-marketing-version 2.0
Run Code Online (Sandbox Code Playgroud)

更新内部版本号

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

xcrun agvtool next-version -all
Run Code Online (Sandbox Code Playgroud)

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

xcrun agvtool new-version -all <your_specific_version>
Run Code Online (Sandbox Code Playgroud)

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

xcrun agvtool new-version -all 2.6.9
Run Code Online (Sandbox Code Playgroud)

奖金:

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

xcrun agvtool what-marketing-version
Run Code Online (Sandbox Code Playgroud)

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

xcrun agvtool what-version
Run Code Online (Sandbox Code Playgroud)

  • 这个问题是agvtool将中止xcode构建,因此它不能在构建阶段作为脚本集成. (7认同)

Jay*_*Jay 11

FWIW -这就是我目前使用增加了版本号只对发布版本(包括归档).在Xcode 5.1下正常工作.

只需将代码段直接复制/粘贴到Xcode中的Run脚本构建阶段:

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;
Run Code Online (Sandbox Code Playgroud)


mas*_*bio 7

谢谢你的剧本.它很棒.

我的Info.plist位于一个子目录中,其名称包含空格,因此我必须使用plist路径周围的引号修改Run Script:

${PROJECT_DIR}/tools/bump_build_number.sh "${PROJECT_DIR}/${INFOPLIST_FILE}"
Run Code Online (Sandbox Code Playgroud)

和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
Run Code Online (Sandbox Code Playgroud)


Mat*_*hew 6

我目前使用的脚本非常基于上面的Alix.下面的我的改编添加了一个检查,仅对发布/归档版本进行自动增量.

如果没有这种更改,就会出现版本控制冲突,因为每个开发人员都会按照自己的速率增加内部版本号.事实上,随着内部版本号的不断变化,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}"
Run Code Online (Sandbox Code Playgroud)

它也可以作为GitHub的要点(以更容易复制和粘贴的格式).


dak*_*180 5

我建议使用autorevision.

Xcode允许头文件(可以在构建时自动生成而不是在自己的vcs中生成)来提供将在构建时在info.plist中展开的值.您可以在autorevision网站上找到进行此设置的演练.

Autorevision具有面向这些类型头文件的输出类型,以帮助完全满足这些情况.