场景:
- 从多个仓库拉取代码,打ipa包,支持选择是否上传到蒲公英;完成之后发送钉钉通知消息
- 现在的App大部分都用到了混合开发;有的需要H5资源包,或者是RN的混合应用需要打包bundle和assets;我们需要将这些资源整合到App中,可以去处理,人为的话会存在没有用最新的资源包或者忘了替换资源包的情况;所以最好是能通过CI管理这些操作
1. 多个仓库拉取代码
多个仓库拉取代码,一般可以使用Pipline或者Multiple SCMs plugin
Jenkins推荐使用Pipline,需要了解Pipline的使用语法,Pipline同时也提供自动生成一些操作的代码;本教程使用Pipline
1. 设置参数化构建,支持不同的仓库可以拉取不同的分支的代码
-
App的包环境选择,或者可以理解为App的不同的configuration
图片.png -
多仓库的分支设置,支持打各个仓库的任意分支
图片.png -
是否上传到蒲公英选项,比如内测版本就钩上
图片.png
2. 多仓库设置
- SCMS管理
我们可以指定不同的仓库的代码拉取到本地的不同的目录,checkout的分支就是参数化构建设置的分支
图片.png
- pipline管理
pipline我们可以直接使用工具生成我们想要的步骤的代码,点击下图的
图片.png流水线语法
在编辑器中选择需要的步骤,配置好参数,生成脚本
图片.png
2. 打包ipa
打包ipa可以使用xcodebuild fastlane等工具处理
-
编写脚本
比如是Native和RN的混合项目,一般需要:- 一个打包RN的脚本并将资源拷贝到Native的项目目录
图片.png
package_rn.sh - xcode编译时的脚本,将RN的bundle和assets拷贝到App包目录
图片.png
cp-rn-resources.sh - 打包导出ipa的脚本
图片.png
export_ipa.sh
- 一个打包RN的脚本并将资源拷贝到Native的项目目录
️ 导出ipa包时需要exportOptionPlist,这个文件可以参照官方的规范编写plist,也可以直接用xcode打包导出ipa,在ipa包的文件夹中有ExportOptions.plist
,建议使用后者的方式;一般需要两个一个development的一个production的
3. 消息通知
消息通知可以按需要选择邮件、钉钉、微信等方式,官方也有对应的插件,如果通知的内容定制较高,最好使用API发消息API文档
- 比如钉钉消息,支持markdown格式,我们可以通过curl的方式发送消息到钉钉
DINGDING_ROBOT_URL="https://oapi.dingtalk.com/robot/send?access_token=xxxx"
MSG="{\"msgtype\": \"markdown\",
\"markdown\": {
\"title\": \"${title}\",
\"text\": \"${markdown}\"
}
}"
curl -H 'Content-Type:application/json' -X POST --data '${MSG}' ${DINGDING_ROBOT_URL}
-
钉钉机器人,需要管理员权限才能创建
图片.png
4. 上传ipa到蒲公英
在测试阶段,需要打包上传到蒲公英,方便测试和公司的人体验安装,或者发内测版本上传到蒲公英
- 准备工作
使用api或者插件上传都要用到API信息
- 使用api上传ipa到蒲公英
API2.0
curl -F "file=@./IPAFullPath" \
-F "_api_key=️这里填你的蒲公英的APP Key" \
-F "buildInstallType=1" \
http://www.pgyer.com/apiv2/app/upload \
-o ./pgy.json'
- 这个地方将上传返回的结果写到本地文件
pgy.json
中,是为了获取安装的地址,或者二维码等其他信息,可以按需要获取;一般用到的有buildQRCodeURL
、buildShortcutUrl
- shell获取json中的信息,建议使用jq,比如在pipline中获取
buildShortcutUrl
// 获取蒲公英的下载地址
def createPGYDownloadURL() {
def buildShortcutUrl = sh(returnStdout: true, script: 'cat pgy.json | jq -r ".data.buildShortcutUrl"')
echo buildShortcutUrl
def downloadUrl = "http://www.pgyer.com/${buildShortcutUrl}"
echo downloadUrl
return downloadUrl
}
// 获取蒲公英安装包的二维码
def createPGYQRURL() {
def buildQRCodeURL = sh(returnStdout: true, script: 'cat pgy.json | jq -r ".data.buildQRCodeURL"')
echo buildQRCodeURL
return buildQRCodeURL
}
拿到这个url,就可以发消息的时候带上这个url了。
jq是从json文件中读取某个字段的工具,没有安装的需要安装一下 brew install jq
5. pipline的Jenkinsfile事例
这个事例包含:
- 多仓库代码异步拉取
- stages的使用
- 自定义ipa包名--需要获取到app的版本用到
/usr/libexec/PlistBuddy
- 上传到蒲公英并获取下载地址
- 发送markdown格式的钉钉消息
Jenkinsfile
使用的时候可以直接将Jenkinsfile的内容拷贝粘贴到流水线脚本中
或者使用Jenkinsfile
图片.png
pipline需要指定agent,这里的label就是打包机器的标签,Jenkins默认是master,如果改了名字就用对应的,可以在系统设置中查看
如下所示:图片.png
6. Jenkins构建效果图
-
构建操作面板
图片.png -
pipline工作过程面板
图片.png
6. QA
- xcode archive正常,但是用Jenkins打包的时候报错如下:
error: Task failed with exit 1 signal 0 {
/usr/bin/codesign '--force' '--sign' '9A0FCDA0F401B37A181F5F3A7675F57A190E8B9C' '--verbose' '/Users/xxx/Library/Developer/Xcode/DerivedData/xxx-etuxniaybliunxazmzjuqgiiqbqv/Build/Intermediates.noindex/ArchiveIntermediates/xxx/InstallationBuildProductsLocation/Applications/xxx.app/Frameworks/libswiftAVFoundation.dylib'
}
** ARCHIVE FAILED **
The following build commands failed:
CopySwiftLibs xxx
(1 failure)
解决方法:
将钥匙串中的打包证书,从“登录”移到“系统”
https://forums.developer.apple.com/thread/64101
2.xcode导出正常,使用命令行去打包也正常,使用jenkins的时候提示
/ArchiveIntermediates/xxx/InstallationBuildProductsLocation/Applications/xxx.app: errSecInternalComponent
Command /usr/bin/codesign failed with exit code 1
尝试了以下方法:
- 重启大法没能解决
- security unlock-keychain login.keychain
- 删除~/Library/MobileDevice/Provisioning Profiles里的描述文件,重新导入描述文件,重启电脑
最终还是用问题1的方法将证书从登录移到了系统解决了
Xcode Command /usr/bin/codesign failed with exit code 1 : errSecInternalComponent
网友评论