我正在启动一个新项目,它将让多个开发人员使用Git在Xcode中工作。我想设置自动递增的内部版本号,我已经找到了一些关于如何做到这一点的好答案,但我关心的是多个开发人员和Git。
我知道在Xcode中有一些文件,比如项目文件,它们非常敏感且难以合并。我看到的用于自动递增构建数的最佳技术将容易受到相同的多个Git合并问题的影响。
这里有关于如何使用自动递增构建技术并仍然将合并问题保持在最低限度的指导吗?也许答案是没有好的答案,但我想知道别人在做什么。
答案 0 :(得分:4)
首先感谢harald的回答和评论,这有助于我更好地思考我真正想要实现的目标。
让我总结一下我的想法,我意识到我想做什么,以及我是如何做到的。
我想要一种以自动方式填充内部版本号(CFBundleVersion)的方法。该值存储在主项目-Info.plist文件中,该文件由源控制。我担心遵循指南通过“构建阶段”脚本自动执行此操作,因为它可能会为多个开发人员修改此文件,并导致需要不断合并的情况。
我想要的原因是我可以轻松找到特定版本的代码。虽然人们当然可以通过标记和正确的文档来手动执行此操作,但我想要一种更加自动化和灵活的方式,因为我认为我将为TestFlight完成大量构建。
我最初的想法是为这个值使用一个简单的增量版本号,但这对合并来说确实很麻烦。 Harald建议在Git repo上使用提交SHA,这为我提供了更好的思路。
所以我的解决方案的第一部分是使用提交SHA中的前9个字符(SHA太长)。我使用前9个字符,因为我正在运行GitLab HQ(顺便说一句,这是一个很棒的开源项目),并且他们在显示正在运行的提交流时使用前9个字符。让我这样的命令如下:
/usr/bin/git rev-parse --short=9 HEAD
为了避免出现Git合并问题,我想到了首先在项目-Info.plist文件中更改构建号(CFBundleVersion)值,允许构建运行,然后在最后一步更改值默认为1,以便在源代码管理中不会显示更改。我尝试使用“运行脚本”在“构建阶段”流程中以各种方式执行此操作,但似乎即使将代码放入最终步骤中还原值,它也会影响正在运行的应用程序。
在进一步挖掘之后,我遇到了模式以及前期行动和后期行动。这似乎是我的路线。
因此,在模式中,对于“构建”计划,我创建了一个预先操作,将CFBundleVersion值设置为我当前的提交ID(9个字符),并且在后期操作中我会将此值还原到默认值(1)。这看起来像我需要的那样起作用。
这是我的行动前代码:
buildPlist="$SRCROOT/$INFOPLIST_FILE"
echo "The build plist file $buildPlist"
CFBundleVersion="$(cd $SRCROOT;/usr/bin/git rev-parse --short=9 HEAD)"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $CFBundleVersion" $buildPlist
这是我的动作后代码:
buildPlist=$"$SRCROOT/$INFOPLIST_FILE"
CFBundleVersion=1
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $CFBundleVersion" $buildPlist
这段代码与我在“构建阶段”脚本中使用的代码不同,需要使用$ SRCROOT来设置目录。最初我的印象是你会得到与“Build Phase”中相同的构建设置,但是你似乎没有。 “运行脚本”窗口中有一个名为“从以下位置提供构建设置”的选项,它允许您选择目标。也许这是正确的,无论给出预先操作,您都必须设置完整的目录路径。我花了一点时间才想出来,所以我想我会提到它。
总之,我很欣赏我收到的信息,这有助于我思考我的目标并最终实现我想要的目标。
答案 1 :(得分:1)
虽然我没有真正意识到线性递增构建数量试图跟踪像git这样的非线性开发模型,但是有办法实现它。这取决于你所追求的是什么。如果你只想要一个“官方”版本的内部版本号,你可以在构建时通过构建脚本简单地生成它。然后让构建脚本标记使用生成的数字构建的提交。像这样:
git checkout build-branch
generate_build_num > buildnum.txt
make
git tag `cat buildnum.txt`
生成唯一的递增构建号的责任在于generate_build_num
脚本,您始终可以使用该标记找回相应的提交。
另一方面,如果你希望git树中的每个提交都对应一个线性内部版本号,那么你需要做更多的工作。
在我看来,与直接使用sha1相比,没有太大的收获。
答案 2 :(得分:-1)
我使用稍微不同的方法来避免与在每次构建时触摸Info.plist相关联的合并冲突。它类似于magnusMTB临时设置(然后重置)内部版本号的策略,但不是使用前后操作,而是在项目的Info.plist中留下占位符值,然后添加“运行脚本”构建阶段仅修改产品的版本号而不触及Xcode项目的副本。
脚本如下所示:
# Grab some environment variables from Xcode
BUILD_NUMBER_FILE="${SOURCE_ROOT}/BuildNumber"
PLIST_FILE="${TARGET_BUILD_DIR}/${CONTENTS_FOLDER_PATH}/Info.plist"
# Create a build string
# Anything goes, but this uses my employer's App_vX_YYMMDD.HHMM format
majorVersion=`/usr/libexec/PlistBuddy -c "PRINT:CFBundleShortVersionString" "$PLIST_FILE"`
dateTime=`date "+%y%m%d.%H%M"`
buildNumber=App\_v$majorVersion\_$dateTime
# Write the build string to a local file under version control
echo $buildNumber > $BUILD_NUMBER_FILE
# Set the build number in the product's plist (Not the Xcode project's plist)
echo Writing generated build number \"$buildNumber\" to \"$PLIST_FILE\"
/usr/libexec/PlistBuddy -c "Set :CFBundleVersion $buildNumber" "$PLIST_FILE"
通过这种方式,版本控制下的Info.plist保持不变,但用于测试或部署的应用程序内部的内部版本号是“正确的”动态生成的值。通过与Info.plist不同的单个清理合并文件,构建号保留在版本控制中。
警告:我不确定构建号是否在Info.plist之外的某个位置被烘焙到二进制文件中。这可能会产生问题。然而,对于它的价值,我正在测试的应用程序从其捆绑中的Info.plist自我报告正确的(脚本生成的)构建号。