39

iOS持续集成构建

 5 years ago
source link: http://www.cocoachina.com/ios/20190412/26797.html?amp%3Butm_medium=referral
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.

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

Jenkins集成方案

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

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

下载Jenkins

NbmMJff.png!web

安装Jenkins

bQ7Vnea.png!web

安装Jenkins.png

设置管理员账号密码

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

bUfai2y.png!web

获取初始密码Jenkins.png

Jenkins插件安装

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

AR3Mr22.png!web

Jenkins安装插件.png

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

IRzqEfE.png!web

Jenkins工作流程.png

步骤1 拉取代码

au2mMri.png!web

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_TYPE
export ETT_BUILD_VERSION=$ETT_GIT_REV.$BUILD_NUMBER
export ETT_BUILD_ID=$ETT_VERSION_NUMBER-$ETT_JENKINS_TIME-$ETT_GIT_REV-$BUILD_NUMBER-G$ETT_GIT_COMMIT

export NEXUS_JENKINS_NAME=打包后上传账号
export NEXUS_JENKINS_PASSWD=密码


export ExportOptionsPlistPath=/Users/用户/Downloads/zhengshu/ExportOptions.plist
export XCODE=/usr/bin
export ETT_DIST_ROOT_PATH=工作区路径
export ETT_DIST_PATH=$ETT_DIST_ROOT_PATH/$BUILD_NUMBER
export ETT_ARCHIVE_PATH=$ETT_DIST_PATH/$ETT_APP_NAME.xcarchive
export ETT_WORK_SPACE=$WORKSPACE/$ETT_WORKSPACE_NAME.xcworkspace

export ETT_FILE_NAME=$ETT_APP_NAME-$ETT_BUILD_ID
export ETT_IPA_NAME=$ETT_FILE_NAME.ipa
export ETT_EXPORT_PATH=$ETT_DIST_PATH/$ETT_IPA_NAME
export ETT_PACKAGE_NAME=$ETT_FILE_NAME.tar.gz
export ETT_PACKAGE_PATH=$ETT_DIST_PATH/$ETT_PACKAGE_NAME
export ETT_NEXUS_FILE_NAME=$ETT_APP_NAME-$ETT_JENKINS_TIME-$BUILD_NUMBER-$ETT_GIT_COMMIT.tar.gz

export ETT_UPLOAD_DSYM_SRC=$ETT_WORKSPACE_NAME.app.dSYM
export ETT_UPLOAD_DSYM_FILE=$ETT_FILE_NAME-dSYM.zip
export ETT_UPLOAD_DSYM_PATH=$ETT_DIST_PATH/$ETT_UPLOAD_DSYM_FILE

if [ ! -d "$ETT_DIST_ROOT_PATH" ]; then
  mkdir $ETT_DIST_ROOT_PATH
fi
if [ ! -d "$ETT_DIST_PATH" ]; then
  mkdir $ETT_DIST_PATH
fi

#/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_PATH
zip -r $ETT_UPLOAD_DSYM_PATH $ETT_UPLOAD_DSYM_SRC
tar -C $ETT_DIST_PATH -zcvf  $ETT_PACKAGE_PATH $ETT_IPA_NAME $ETT_UPLOAD_DSYM_FILE
curl -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

eQnaMjA.png!web

打开Xcode Server.png

配置Xcode Server管理员账号

aErQVfr.png!web

配置Xcode Server管理员账号.png

创建Bot(值守机器人)

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

3i2YfuV.png!web

创建值守机器人.png

配置仓库分支

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

fMbeM3i.png!web

配置仓库分支.png

编译打包参数配置

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

ZVjmiuz.png!web

编译打包参数配置.png

构建触发器

2yYVnu3.png!web

构建触发器.png

eu2aQjN.png!web

构建触发器.png

添加签名文件

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

IZzUfe7.png!web

添加签名文件.png

添加环境变量

ZZzm6ji.png!web

添加环境变量.png

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

添加打包后的脚本命令

uAriAb7.png!web

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

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

集成打包

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

n2uINvv.png!web

集成打包.png

总结

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

最后打个广告:

模仿推特客户端(纯Swift开发,develop分支):

https://github.com/waitwalker/MyTwitter

针对这个客户端简单用Python写了几个接口:

https://github.com/waitwalker/MyTwitterAPI

文章地址:https://www.jianshu.com/p/42ed698c57ad,因为一直在写code,文章比较糙,还没来及整理,抱歉!

作者:偶尔登南山

链接:https://www.jianshu.com/p/f72f10a921b9


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK