我使用 ANT 创建版本,利用 xcodebuild 命令行实用程序。蚂蚁目标看起来像这样:
<target name="build-adhoc">
<echo>Running XCODE compiler</echo>
<exec executable="xcodebuild" failonerror="true" vmlauncher="false" dir="${connect_src}">
<arg value="build"/>
<arg value="-target" />
<arg value="myappname" />
<arg value="-configuration"/>
<arg value="AdHoc"/>
<arg value="SYMROOT=${export_app}-${version.number}/AdHoc" />
<env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/somesource/**\ /tmp/build/trunk/Libraries/somemoresource/**"/>
</exec>
<echo>xcode build complete</echo>
</target>
为您的临时版本创建配置,并确保它使用临时准备好的配置文件。或者,您可以创建一个使用您的开发人员配置文件的普通、非临时配置。如果您使用前者,您可以将产品连同您的配置文件一起通过电子邮件发送给测试人员。如果您执行后者,您可以使用 iPhone 配置实用程序在配置文件中的任何设备上进行安装。
此外,我们的 ANT 目标设置依赖于从源代码管理进行新的检查并从那里进行构建。最后,我们使用真正的 App Store 就绪配置进行构建,这样我们就可以测试第一个构建并将第二个构建交付给 Apple,并在一定程度上确定代码行为将是相同的。
以下是按处理顺序对我们的 ANT 目标进行的摘要:
- 设置构建所需的环境变量
- 清除结帐和构建目录
- 从源代码管理中签出 HEAD
- 修改 plist 以删除调试和元素仅供内部使用(使用 PLISTBUDDY)
- 增量构建版本(使用 agvtool)
- 运行单元测试(这需要将 sdk 设置设置为 iphonesimulator4.x 和一个特殊目标 - 请参阅 iPhone 开发人员指南了解单元测试)
- 进行内部构建(使用开发配置文件或临时配置文件)
- 进行分发构建(使用 App Store 分发证书)
- 签入具有新构建版本的 plist 文件
- 在源代码管理中添加一个标记来指示构建
- 报告构建统计信息(构建版本、位置等)
注意:确保您在 xcodebuild 命令语法中设置了 SYMROOT 环境变量,以便您的构建最终位于正确的目录中。事后我们在复制 App Store 版本时遇到了问题。
这是用于创建多个构建的完整 ANT 脚本,一个用于测试,一个用于分发。例如:“ant distribution”将使用 dev 配置文件创建一个构建,并使用 App Store 分发配置文件创建一个。
这个脚本是“清理过的”,所以它只是作为一个开始的模型:
<?xml version="1.0" ?>
<project basedir="." default="xcode-build" name="Temp">
<property file="build.properties" />
<property name = "CONFIGURATION_INTERNAL" value = "InternalRelease" />
<property name = "CONFIGURATION_DISTRIBUTION" value = "Distribution" />
<property name = "CONFIGURATION_ADHOC" value = "InternalAdHoc" />
<property name="cvsroot" value=":pserver:${username}:${password}@${cvsurl}"/>
<tstamp>
<format property="TODAY"
pattern="MM-dd-yyyy"
locale="en,US"/>
</tstamp>
<target name="init">
<echo message="deleting old directories" />
<delete dir="${check_out_location}"/>
<mkdir dir="${check_out_location}"/>
</target>
<target name="set-source-trees" depends="init">
<echo message="exporting source tree variables" />
<echo message="${somesourcedir}" />
<exec executable="/bin/bash" os=" Mac OS X">
<arg value="-c" />
<arg value="${export_src_trees}"/>
<arg value="${anothersourcedir}"/>
</exec>
<exec executable="/bin/bash" os=" Mac OS X">
<arg value="-c" />
<arg value="${export_src_trees}"/>
<arg value="${yetanothersourcedir}"/>
</exec>
</target>
<target name="cvs-login" depends="init" description="CVS Login">
<echo>Login CVS</echo>
<cvs cvsroot=":pserver:${username}:${password}@${cvsurl}" command="login" />
</target>
<target name="checkout" depends="cvs-login" description="Check out source from CVS">
<echo message="check out from CVS ...." />
<echo message="${check_out_location}" />
<cvs cvsroot="${cvsroot}" command=" -Q checkout -P -d${project_trunk} ${project_repository_root}/${project_trunk} " dest="${check_out_location}" compression="true" />
<echo message="...check out from CVS done" />
</target>
<target name="strip-settings" depends="checkout" description="Remove elements from the Settings.bundle that we don't want in the distribution">
<echo message="Removing Settings not valid for distribution"/>
<exec executable="/usr/libexec/PlistBuddy" failonerror="TRUE" dir="${app_src}/Resources">
<arg value="-c"/>
<arg value="Delete :PreferenceSpecifiers:3"/>
<arg value="Settings.bundle/Root.plist"/>
</exec>
<exec executable="/usr/libexec/PlistBuddy" failonerror="TRUE" dir="${app_src}/Resources">
<arg value="-c"/>
<arg value="Delete :PreferenceSpecifiers:3"/>
<arg value="Settings.bundle/Root.plist"/>
</exec>
</target>
<target name="build-version" depends="checkout">
<property name = "LOGLEVEL" value = "DEBUG" />
<!-- GET THE NEXT VERSION NUMBER (major and minor) -->
<exec executable="/tmp/build/trunk/Build/version.sh" failonerror="TRUE" outputproperty="version.number" dir="${app_src}"></exec>
<echo message="Increment Build Number"/>
<exec executable="agvtool" failonerror="TRUE" dir="${app_src}">
<arg value="new-version"/>
<arg value="-all"/>
<arg value="${version.number}"/>
</exec>
<!-- GET THE MINOR portion of the version number for later use -->
<exec executable="/tmp/build/trunk/Build/minor.sh" failonerror="TRUE" outputproperty="version.minor" dir="${app_src}"></exec>
<!-- SET the version number as reference in the Settings.bundle -->
<exec executable="/usr/libexec/PlistBuddy" failonerror="TRUE" dir="${app_src}">
<arg value="-c"/>
<arg value="Set :PreferenceSpecifiers:1:DefaultValue ${version.number}"/>
<arg value="./Resources/Settings.bundle/Root.plist"/>
</exec>
<echo message="New build number=${version.number}"/>
<!-- SET the log level - NOTE, ANT vars are immutable, if LOGLEVEL was previously set, it cannot be overridden -->
<exec executable="/usr/libexec/PlistBuddy" failonerror="TRUE" dir="${app_src}">
<arg value="-c"/>
<arg value="Set LogLevel.Default ${LOGLEVEL}"/>
<arg value="./Resources/SharedConfig.plist"/>
</exec>
<echo message="Log level set to ${LOGLEVEL}"/>
</target>
<target name="encrypt" depends="build-version">
<!-- SOME ENCRYPTION OF SENSITIVE DATA -->
</target>
<target name="build-internal" depends="test-lib1, test-lib2, test-app, encrypt">
<echo>Running XCODE compiler</echo>
<exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${app_src}">
<arg value="clean"/>
<arg value="install"/>
<arg value="-target" />
<arg value="MyApp" />
<arg value="-configuration"/>
<arg value="${CONFIGURATION_INTERNAL}"/>
<arg value="SYMROOT=${build_release}" />
<env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/somesource/**\ /tmp/build/trunk/Libraries/someothersource/**"/>
</exec>
<echo>xcode build complete</echo>
</target>
<target name="test-lib1" depends="checkout">
<echo>Running XCODE compiler</echo>
<exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${somelib_dir}">
<arg value="clean"/>
<arg value="build"/>
<arg value="-target" />
<arg value="Lib1UnitTests"/>
<arg value="-sdk"/>
<arg value="iphonesimulator4.1"/>
<arg value="SYMROOT=${build_release}" />
</exec>
<echo>xcode build complete</echo>
</target>
<target name="test-lib2" depends="checkout">
<echo>Running XCODE compiler</echo>
<exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${somelib2_src_dir}">
<arg value="clean"/>
<arg value="build"/>
<arg value="-target" />
<arg value="Lib2UnitTests"/>
<arg value="-sdk"/>
<arg value="iphonesimulator4.1"/>
<arg value="SYMROOT=${build_release}" />
<env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/Lib1source/**"/>
</exec>
<echo>xcode build complete</echo>
</target>
<target name="test-app" depends="checkout">
<echo>Running XCODE compiler</echo>
<exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${app_src}">
<arg value="clean"/>
<arg value="build"/>
<arg value="-target" />
<arg value="AppUnitTests"/>
<arg value="-sdk"/>
<arg value="iphonesimulator4.1"/>
<arg value="SYMROOT=${build_release}" />
<env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/Lib1/**\ /tmp/build/trunk/Libraries/Lib2/**"/>
</exec>
<echo>xcode build complete</echo>
</target>
<target name="build-distribution" depends="internal-release, test-lib1, test-lib2, test-app">
<echo>Running XCODE compiler</echo>
<exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${app_src}">
<arg value="build"/>
<arg value="-target" />
<arg value="MyApp" />
<arg value="-configuration"/>
<arg value="${CONFIGURATION_DISTRIBUTION}"/>
<arg value="SYMROOT=${export_app}-${version.number}/Distribution" />
<env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/Lib1/**\ /tmp/build/trunk/Libraries/Lib2/**"/>
</exec>
<echo>xcode build complete</echo>
</target>
<target name="build-adhoc" depends="internal-release, test-lib1, test-lib2, test-app">
<echo>Running XCODE compiler</echo>
<exec executable="${xcode_builder}" failonerror="true" vmlauncher="false" dir="${app_src}">
<arg value="build"/>
<arg value="-target" />
<arg value="MyApp" />
<arg value="-configuration"/>
<arg value="${CONFIGURATION_ADHOC}"/>
<arg value="SYMROOT=${export_app}-${version.number}/AdHoc" />
<env key="USER_HEADER_SEARCH_PATHS" value="/tmp/build/trunk/Libraries/Lib1/**\ /tmp/build/trunk/Libraries/Lib2/**"/>
</exec>
<echo>xcode build complete</echo>
</target>
<target name="checkin" depends="build-internal" description="Commit source to CVS" >
<echo message="Committing to CVS ...." />
<echo message="${check_out_location}" />
<cvs cvsroot="${cvsroot}" command="commit -m 'Commit of internal release build ${version.number}' MyApp-Info.plist" dest="${check_out_location}/trunk/Applications/MyApp" />
<echo message="...commit done" />
</target>
<target name="tag-release" depends="checkin" description="Tag source in CVS" >
<echo message="Tagging source ... Release-${version.minor}" />
<echo message="${check_out_location}" />
<cvs cvsroot="${cvsroot}" command="tag Release-${version.minor}" dest="${check_out_location}"/>
<echo message="...tag done" />
</target>
<target name="internal-release" depends="tag-release" description="Tag source in CVS" >
<echo message="Creating Internal release ..." />
<echo message="Deploying files to . . .${export_app}" />
<copy todir="${export_app}-${version.number}">
<fileset dir="${prod_dir_internal}"/>
</copy>
<echo message="Internal release ${version.number} complete." />
</target>
<target name="override-default-env" description="Setup Env for Distribution" >
<property name = "LOGLEVEL" value = "WARN" />
</target>
<target name="distribution" depends="override-default-env, strip-settings, build-distribution" description="Create Distribution" >
<echo message="Creating Distribution ..." />
<echo message="Deploying files to . . .${export_app}-${version.number}/Distribution" />
<echo message="Distribution ${version.number} complete." />
</target>
<target name="adhoc" depends="override-default-env, strip-settings, build-adhoc" description="Create Ad Hoc Distribution" >
<echo message="Creating ad hoc distribution ..." />
<echo message="Deploying files to . . .${export_app}-${version.number}/AdHoc" />
<echo message="Ad hoc distribution ${version.number} complete." />
</target>
</project>
Hope this helps.