iOS持续集成构建

目前市面上持续集成的方案很多:例如,Jenkins, Fastlane,Xcode server等,这些持续集成的方案大同小异,他们之间的性能差异笔者没有做大量的横向分析,只是大体比较了一下打包时间.总结来说,持续集成主要是三个步骤:1.拉取代码;2.编译打包;3.分发数据(打包结果),下面将通过两种方案(Jenkins和Xcode server)来分析一下这三个过程.

Jenkins集成方案

Jenkins作为免费集成方案,其社区拥有大量插件,非常友好,所以用户也众多.

首先来安装Jenkins,Jenkins官网提供了多个系统环境的软件包,我选择的是macOs系统,选择下载安装,步骤如下图:

下载Jenkins

image.png

安装Jenkins

image.png

安装Jenkins.png

设置管理员账号密码

安装完成后,一般mac环境集成了Apache服务器会自动配置启动8080端口,Jenkins的初始化页面也会在安装完成后自动弹出.此时只要找到图中红色标记路径cat或者vi看一下里面的秘钥,进入Jenkins初始化设置工作.这个过程会设置管理员账号密码等.

image.png

获取初始密码Jenkins.png

Jenkins插件安装

初始化完成后,就可以利用管理员账号登录.登录后通常可以安装一些常用插件,一般有默认插件和自定义插件,选择默认插件即可.

image.png

Jenkins安装插件.png

基本的环境搭建完成后,就可以实施上面的三个过程了.其实Jenkins的主要工作流程,可以通过下图来直观看出来.

image.png

Jenkins工作流程.png

步骤1 拉取代码

image.png

git仓库分支配置.png

拉取代码过程比较简单,主要是从指定仓库中克隆代码到Jenkins的工作目录.

步骤2 编译打包

编译打包命令主要有xcodebuild,xcrun,xctool(facebook)等,前两个是官方的,后一个是Facebook出品,xctool里面集成了个性化定制,需要的可以细研究一下,文中只是对xcodebuild做出使用分析.

xcodebuild编译过程也主要分三个过程:

- clean    xcodebuild -workspace MyWorkspace.xcworkspace -scheme SchemeName    - archive     xcodebuild archive -workspace MyWorkspace.xcworkspace -scheme SchemeName     - export ipa     xcodebuild -exportArchive -archivePath MyMobileApp.xcarchive -exportPath ExportDestination.ipa -exportOptionsPlist 'exportPlist.plist'

这里多说两句:由于IDE变化,导致编辑脚本稍微有一些出入,主要是在编译的第三步(- export ipa),这步Xcode 8.0需要指定描述文件,Xcode 9.0需要指定exportOptionsPlist(这个是主要包含一些证书, ipa模式等键值表).下面贴出打包执行脚本的全部命令(Xcode 9.0):

export ETT_APP_NAME=app名称export ETT_WORKSPACE_NAME=工作区名称export ETT_SCHEME=scheme名称export ETT_PROVISIONING_PROFILE=描述文件(Xcode9.0用不到)export ETT_BUILD_TYPE=编译类型(用于区分发布还是AdHoc模式,可以忽略)export ETT_CONFIGURATION=编译配置(主要根据自己的多环境进行配置,比如Release,Debug等)###############################################################################################################export ETT_JENKINS_TIME=$(date +%m%d) export ETT_GIT_COMMIT=${GIT_COMMIT:0:7}export ETT_GIT_REV=`git rev-list HEAD | wc -l | awk '{print $1}'`export ETT_VERSION_PRO=`/usr/bin/agvtool mvers -terse1`export ETT_VERSION_NUMBER=$ETT_VERSION_PRO$ETT_BUILD_TYPEexport ETT_BUILD_VERSION=$ETT_GIT_REV.$BUILD_NUMBERexport ETT_BUILD_ID=$ETT_VERSION_NUMBER-$ETT_JENKINS_TIME-$ETT_GIT_REV-$BUILD_NUMBER-G$ETT_GIT_COMMITexport NEXUS_JENKINS_NAME=打包后上传账号export NEXUS_JENKINS_PASSWD=密码export ExportOptionsPlistPath=/Users/用户/Downloads/zhengshu/ExportOptions.plistexport XCODE=/usr/binexport ETT_DIST_ROOT_PATH=工作区路径export ETT_DIST_PATH=$ETT_DIST_ROOT_PATH/$BUILD_NUMBERexport ETT_ARCHIVE_PATH=$ETT_DIST_PATH/$ETT_APP_NAME.xcarchiveexport ETT_WORK_SPACE=$WORKSPACE/$ETT_WORKSPACE_NAME.xcworkspaceexport ETT_FILE_NAME=$ETT_APP_NAME-$ETT_BUILD_IDexport ETT_IPA_NAME=$ETT_FILE_NAME.ipaexport ETT_EXPORT_PATH=$ETT_DIST_PATH/$ETT_IPA_NAMEexport ETT_PACKAGE_NAME=$ETT_FILE_NAME.tar.gzexport ETT_PACKAGE_PATH=$ETT_DIST_PATH/$ETT_PACKAGE_NAMEexport ETT_NEXUS_FILE_NAME=$ETT_APP_NAME-$ETT_JENKINS_TIME-$BUILD_NUMBER-$ETT_GIT_COMMIT.tar.gzexport ETT_UPLOAD_DSYM_SRC=$ETT_WORKSPACE_NAME.app.dSYMexport ETT_UPLOAD_DSYM_FILE=$ETT_FILE_NAME-dSYM.zipexport ETT_UPLOAD_DSYM_PATH=$ETT_DIST_PATH/$ETT_UPLOAD_DSYM_FILEif [ ! -d "$ETT_DIST_ROOT_PATH" ]; then  mkdir $ETT_DIST_ROOT_PATHfiif [ ! -d "$ETT_DIST_PATH" ]; then  mkdir $ETT_DIST_PATHfi#/usr/bin/agvtool vers -terse#/usr/bin/agvtool mvers -terse1/usr/bin/agvtool new-marketing-version $ETT_VERSION_PRO/usr/bin/agvtool new-version -all $ETT_VERSION_PRO.$ETT_BUILD_VERSION#/usr/bin/agvtool vers -terse#/usr/bin/agvtool mvers -terse1$XCODE/xcodebuild clean build BITCODE_GENERATION_MODE=bitcode OTHER_CFLAGS="-fembed-bitcode" archive -archivePath "$ETT_ARCHIVE_PATH" -workspace $ETT_WORK_SPACE -destination generic/platform=iOS -scheme $ETT_SCHEME -configuration "$ETT_CONFIGURATION" BUILD_NUMBER="$ETT_BUILD_ID" CONFIGURATION_BUILD_DIR=$ETT_DIST_PATH UPLOAD_dSYM_FILE=$ETT_UPLOAD_DSYM_FILE$XCODE/xcodebuild -exportArchive -archivePath $ETT_ARCHIVE_PATH -exportPath $ETT_EXPORT_PATH -exportOptionsPlist $ExportOptionsPlistPath -allowProvisioningUpdates

步骤3 分发数据(发布打包)

这个过程可以直接发布,也可以上传到自己指定的服务器,第三方托管服务器等.我们直接在执行打包脚本的最后面,将打包处理的ipa文件以及符号化文件打包后直接上传到指定服务器:

cd $ETT_DIST_PATHzip -r $ETT_UPLOAD_DSYM_PATH $ETT_UPLOAD_DSYM_SRCtar -C $ETT_DIST_PATH -zcvf  $ETT_PACKAGE_PATH $ETT_IPA_NAME $ETT_UPLOAD_DSYM_FILEcurl -v -u $NEXUS_JENKINS_NAME:$NEXUS_JENKINS_PASSWD --upload-file $ETT_PACKAGE_PATH  服务器路径$ETT_APP_NAME/ios/$ETT_VERSION_PRO$ETT_BUILD_TYPE/$ETT_NEXUS_FILE_NAME

到这里,Jenkins的简单集成过程算完成了,里面涉及到一些环境变量和参数的设置,笔者因为还涉及到Swift和OC混合打包,问题稍多一点.因为业务需求不一样,需要自己去单独设置,有疑问的地方可以一起沟通一下.

Xcode Server集成方案

这个方案,将会把上面三个过程穿插进去,不在单列出来.网上有其他方案是macOS Server + Xcode Server集成方案,本文只是简单介绍一下通过Xcode Server集成

打开Xcode Server

image.png

打开Xcode Server.png

配置Xcode Server管理员账号

image.png

配置Xcode Server管理员账号.png

创建Bot(值守机器人)

配置完成后,然后通过Xcode->Product->Create Bot

image.png

创建值守机器人.png

配置仓库分支

配置代码仓库,Xcode集成了Git所以针对你的项目仓库直接添加分支即可.

image.png

配置仓库分支.png

编译打包参数配置

分支添加完成后,就可配置编译的一些选项:scheme,ExportOptionsPlist,Configuration等.

image.png

编译打包参数配置.png

构建触发器

image.png

构建触发器.png

image.png

构建触发器.png

添加签名文件

下一步添加证书,描述文件等,作者这里选择的是自动签名模式,如果需要可自己指定签名证书,描述文件等,这里不再细说.

image.png

添加签名文件.png

添加环境变量

image.png

添加环境变量.png

下一步就是添加编译之前和编译打包之后的动作

添加打包后的脚本命令

image.png

添加打包后的脚本命令.png

这里你可以把打包结果上传到指定位置,脚本可自行查找.

集成打包

机器人创建完成后会自动运行编译打包一次,下次打包可以直接通过点击Integrate触发打包.

image.png

集成打包.png

总结

两种方案,整个过程走下来并不是很复杂.这里提醒一下,由于Jenkins打包通过脚本命令执行编译打包,这个又依赖于一些环境变量和参数,如果一些插件和参数变了,IDE更新了,系统更新了等等原因,这些很容易造成打包失败,笔者经历多次了,一般就是先把命令拿到终端里面编译打包试一下,排除编译命令问题,然后在调试Jenkins环境.总结下来就是遇到问题时不要着急,慢慢分析,一点一点调试,总会解决的.

交流群昵称:ios-Swift/Object C开发上架
交流群号: 869685378   找ios马甲包开发者合作,有兴趣请添加Q 51259559

作者:偶尔登南山

猜你喜欢

转载自blog.csdn.net/ios8988/article/details/89286593