前言
一个对效率有追求的公司,都应该有一套自动构建系统。
目前使用的这套 iOS 构建流程,经历 2 年的使用,基本稳定下来。
这篇文章主要用来记录📝 目前自己使用的 Jenkins 打包📦脚本。
用来打包做类似事情的工具很多,更主要的是为什么使用自动构建:
- 效率上,解放出开发人员的时间。也更方便其他同事使用。
- 保证打包的标准,避免配置或环境问题,带来的失败。把事情做对,比做快更重要。
- 权限安全上,通过构建系统集中管理,对于使用者来说是一个黑盒。
- 项目流程上,便于有需求时做 Daily Build 或者 自动测试。
对于 如何安装 Jenkins
或者 Jenkins 参数配置
之类的基本配置不做涉及。
网上已经有不少详细的文章进行介绍。比如 手把手教你利用Jenkins持续集成iOS项目。
大体的iOS 构建流程
先介绍整体的构建流程,具体的内容会在下面分步骤介绍.
下面使用的相应 ruby 脚本已经上传 github 仓库,注意的是,里面的变量进行了脱敏处理,根据自己需要去稍作修改
构建前
- 设置构建名
- 配置 app 图标水印(build号,分支)
- ruby 脚本根据参数,修改工程 bundleID ,宏等
- 安装第三方依赖,pod update
执行构建
- xcodebuild clean
- xcodebuild archive
- xcodebuild exportArchive
构建完成
- 上传分发平台: 蒲公英/fir/appstore(历史版本记录: git tag )
- 符号表处理:上传 bugly
- 归档产物: 上传 FTP 服务器
- 清理: 删除 IPA 等
- 设置构建描述
- 通知: 企业微信 webhook 机器人推送
构建前
设置构建名
首先设置我们的构建名称,我这里使用到几个参数:
- BUILD_NUMBER ,Jenkins 自带的参数,代表第几次构建
- BetaPlatform ,设置的选项参数,代表分发平台。我这里的值分别是:
fir
,pgyer
,appstore
- Mode,设置的选项参数,代表 Xcode 构建的环境设置,为
Snapshot
和Release
- Branch,Jenkins 自带的参数,代表 Git 分支名称
配置 APP 图标
为了打包后进行测试的 APP ,便于定位问题,可以在 App Logo 上打上水印,加入构建使用的 git 分支名
,jenkins 构建号
,app 版本号
等关键信息。
配置图标水印的流程为:
- 判断此次是否为 appstore 分发平台。如果是 appstore 的话,将旧有的图标目录清理掉,然后将图标复制到使用的目录中。
- 如果不是 appstore ,则为测试平台分发,进行水印处理。
打包前替换资源
Note:
在处理图标做替换时,原来有两种方式,一种是在构建完成后,进入 app 的资源中进行替换(现在行不通了)。另一种是,直接修改工程中的资源。
目前是用的方法,就是直接修改工程目录中的图标源文件
.所以要在构建之前完成加水印替换 Logo.
因为要使用替换资源的方式,所以准备两个目录。
一个目录作为 源目录
,存放未处理的图片。一个目录作为目标目录
,存储 App Logo 使用的图片。
为什么使用两个图片目录存储?假设只用一个,原图为A,当第一次处理,图片为 A1水印图片,当第二次再拿到的图片,已经是被处理过的 A1水印图片了,而不是原图A 。
这里注意 icons_path
为存放原图的地址, icons_dest_path
为要修改使用的目标路径。 命名为 AppIcon-Internal
。
可以参考 iOS APP图标版本化
关于 version 的获取, 因为目前版本有改动,使用 ruby 去获取,脚本会在后面提供链接:
1 | version=$(ruby ./ToolChain/ruby/dy_build_version.rb ${Mode}) |
还有一个临时存放路径,要提前创建好这个文件夹:
1 | tmp_path="/Users/${sys_username}/Desktop/iOS_IPA/IconVersioning |
ImageMagick
添加水印主要使用到了命令行工具 ImageMagick
,所以要先安装:
1 |
|
脚本内容
具体的脚本如下:
1 |
|
Ruby 修改工程参数
这里使用 ruby 实现参数修改(当然也可使用 python 等各种语言,自己方便就 OK )。
根据自己的场景做区分,有的参数时不要的可以不做。这里主要记录笔者自己用到的,修改参数和添加参数标记的方法
目前做的操作:
- 区分是否 beta 版本 – 修改定义
beta
宏 的真假值 - 不同分发平台,使用不同 bundleID – 对 bundleID 进行修改
1 |
|
脚本里依靠 CocoaPods 开源的 Xcodeproj ,对工程的 name.xcodeproj/project.pbxproj 文件进行配置修改。
python 的话,可以使用这个项目 mod-pbxproj
Pod 操作
安装/更新第三方库,这里使用到的是 Cocoapods,其它的包管理器可使用其它方式。
1 | echo "🌲 ------------- Pod 操作 --------------------" |
执行构建
准备工作
在开始之前,我们要做些准备工作,比如设置要使用的变量,常量。
需要提前写好,尽量避免散落。
1 | echo "🌰 ------------- 获取材料 --------------" |
Build 号相关
旧有的方式,是直接通过 info.plist 取:
1 |
|
然而在新的 Xcode 取 版本号
和 bundleID 的方式发生变化,
现在 info.plist
里的值是变量名,取版本号为 $(MARKETING_VERSION)
, bundleID 为 $(PRODUCT_BUNDLE_IDENTIFIER)
.
结局思路是通过脚本到工程配置里去获取,下面使用 ruby 实现了这两个目的。
我们将 App 与 Jenkins 的 build number 设置为同一个,方便需要时,查看构建的参数以及符号表等:
1 |
|
使用 security
解锁钥匙串.
加入 security
解锁操作的原因,是在子节点 ssh 登录上去之后,keychain 没有被解锁.导致打包失败.
解决方案是用 security unlock-keychain 命令将证书解锁。
1 |
|
另外可以通过命令查看描述文件的详细信息 包括UUID等信息
1 | /usr/bin/security cms -D -i 文件路径 |
Xcodebuild
对工程进行构建打包,主要在于使用 Xcodebuild .
分为三个阶段:
- Clean
- Archive
- Export
如果在执行过程中又不喜欢日志输出的,可以在命令行最后加上
1 | -quiet #只有 warn 和 error 才会输出 |
清理工程
每次构建时,对工程进行 clean ,保证没有其它影响的因素。
使用xcodebuild clean [-optionName]...
清除编译过程生成文件,使用如下:
1 | #//下面是集成有Cocopods的用法 |
非 cocoapods 的工程,将 -workspace "${APP_NAME}.xcworkspace"
换成 -project ${APP_NAME}.xcodeproj
即可。
新版本的 Xcode 有了新的构建系统,使用 -UseModernBuildSystem=<value>
来做新旧区分。
命令 | 说明 |
---|---|
-workspace NAME | 指定工作空间文件XXX.xcworkspace |
-scheme NAME | 指定构建工程名称 |
-configuration [Debug/Release] | 选择Debug或者Release构建 |
-sdk NAME | 指定编译时使用的SDK |
构建 archive 包
Xcodebuild archive
1 | echo "🚗🚗🚗 *** 正在 编译工程 For ${development_mode} 🚗🚗🚗" |
导出 IPA 包
1 |
|
更新到Xcode9.0后,之前写的自动打包脚本不可用了。
需要添加 -allowProvisioningUpdates
,获取访问钥匙串权限的关键所在,设置了这个字段就会在打包过程弹框请求获取钥匙串内容权限。
exportOptionsPlist 设置
特别说明的是,exportOptionsPlist 一定要检查,不同的环境和分发平台要选择对。
最简单方式,就是调好需要的环境后,直接手动 archive ,export 出来,使用产物里的 exportOptionsPlist 文件。
检查 ipa
检查对应路径是否有 **.ipa 文件:
1 |
|
构建完成
上传分发平台
这里分为 蒲公英,fir,appstore 三个平台,上传 IPA.
如果为 appstore, 则多出一个 git tag 的相关操作,标记上当前版本的提交,方便需要时直接回退代码进行查看。
下面使用的三个上传命令,最好先提前在机器上实验可以正常用再构建。
1 |
|
符号表处理
上传 bugly
1 | echo " 📦 ------ 开始符号表 相关工作 ------" |
归档产物
进行完所有操作后,对于产物做一次保存,需要时可以用上。
压缩
首先将文件压缩
1 |
|
上传 FTP 服务器
通过 FTP 插件,把 zip 文件上传到归档的路径下
产物清理
删除 IPA 等文件,注意的是,当状态为 success
才清理,避免有时上传出问题,可以进行手动上传。
构建描述
设置构建描述
进行通知
完成后,进行通知。这里设置成可选项,避免频繁打扰其它同事。企业微信 webhook 机器人推送
1 | if [ "${BotPush}" = "YES" ];then |