写点什么

使用 gitlab ci 构建 IOS 包并发送通知消息到企业微信

用户头像
Zoe
关注
发布于: 2020 年 05 月 20 日
使用gitlab ci构建IOS包并发送通知消息到企业微信

在之前的文章中,我们介绍了使用 gitlab ci 构建 Android 包的方法。今天我们介绍使用 gitlab ci 如何构建 IOS 包,并且在打包成功或者失败时,如何将消息通知到企业微信。

如果对 gitlab ci 还不熟悉的,可以参考之前的文章使用gitlab ci构建Android包,这篇文章我们主要涉及三个知识点:

  • IOS 开发者证书。

  • IOS 打包命令。

  • 如何往企业微信发消息。

IOS 开发者证书

IOS 打包离不开开发者证书,因此首先我们需要先搞清楚 IOS 的证书是怎么回事,它是怎么工作的。

为什么需要证书

我们知道,如果手机不越狱的情况下,iphone 手机安装 app 只能通过官方的 App Store。这种限制是怎么做到的呢?其实很简单,主要用到了非对称加密

首先苹果官方生成一堆公私钥,在所有的 iphone 手机里内置了一个公钥,在苹果公司的后台保存着私钥。当 app 开发者上传 app 到 App Store 时,会用保存在后台的私钥对 App 进行签名,在 iphone 手机上下载这个 app 后,用手机上的公钥来验证这个签名,如果签名验证通过,则表示这个 app 是由苹果后台认证的,并且没有被篡改过。

基于这种签名机制,保证了在 iphone 手机上安装的每一个 app 都是经过苹果认证允许的。

但是,一个新的问题来了,如果我们的 app 还处于开发中,还没有上传到 appStore,该怎么安装到 iphone 手机上呢?这就需要用到开发者证书在中间做一个过渡作用。

证书类型

常用的开发者证书分为两种,一种是个人开发者证书,一种是企业开发者证书。其中,我们常见的有两种模式:

  • In-House:企业内部分发,可以直接的安装 ipa 包(一般是将包上传到服务端,生成链接,点击链接可以下载)。不过最新的 ios 系统,需要在【通用—关于本机—证书信任设置】中对企业证书进行信任。

  • Ad-Hoc:相当于是企业分发的限制版,限制 100 个设备安装,需要提前在苹果后台配置 iphone 设备的设备号(可通过第三方工具或者访问蒲公英查询)。

需要注意的是由企业证书签名的包,是不能上传到 App Store 的,因此需要根据自己公司的情况申请不同的开发者证书。

原理介绍

上面其实已经提到,证书的工作原理是通过非对称加密,从网上找了一幅图,很好的介绍了这个过程:


上图对应的步骤如下:

  • 在 mac 电脑上申请一对公私钥,图中是公钥 M 和私钥 M。

  • 对于苹果的证书来说,跟 App Store 工作原理一样,在苹果后台服务器放置了私钥 A,在苹果设备上存放了对应的公钥 A。

  • 将公钥 M 上传到苹果后台,用私钥 A 进行签名,得到包含公钥 M 及其签名。同时还有一个 Provision profile(大家常说的 pp 文件)文件(其中包含了 AppID、设备列表、App 可使用的权限),将证书文件下载到本地 mac。

  • 在开发 app 时,使用本地的私钥 M 对 app 进行签名,连同上面的 pp 文件一起被打包到 app 中。

  • 在安装 app 时,ios 系统获取证书,通过内置的公钥 A,去验证 app 内的证书是正确的。如果能验证通过,则可以将 App 内的证书数据取出来,使用公钥 M 验证 App 的签名是否正确,验证安装 app 的设备 ID 是否存在设备列表中等。

上面的步骤,大致描述了苹果开发者证书的工作原理,如果你没太理解也没关系。可以结合着上图多看几遍。

另外,这里还有个知识点,在 mac 电脑申请的公钥和私钥 M 只能在申请的电脑使用,怎么让其他伙伴也能正常使用呢?可以将私钥 M 导出成.p12 文件,其他 Mac 电脑导入私钥 M,就可以正常使用了。

IOS 打包

首先打包之前,需要清理工程(workspace 和 scheme 参数的值需要拿到 ios 代码才能查看):

$ xcodebuild clean -workspace xxxx.xcworkspace -scheme xxxx
复制代码

其次,如果你想要 ios 包的构建号是自动递增的,可以使用 agvtool 这个工具:

$ agvtool next-version -all 
复制代码

接着,就可以开始 archive 包(对 Target 进行编译、归档,生成.xcarchive)。

$ xcodebuild -workspace xxxx.xcworkspace -scheme xxxx -configuration Debug archive -archivePath xxxxPath/xxxxx.xcarchive
复制代码

最后,就是将归档文件导出,生成不同渠道的 ipa 包:

$ xcodebuild -exportArchive -archivePath build/$SCHEME_NAME.xcarchive -exportPath build -exportOptionsPlist $EXPORT_OPTIONS_PLIST
复制代码

这里需要指定一个 exportOptionsPlist,是对导出 ipa 的配置,我这里写的比较简单,格式如下:

<?xml version="1.0" encoding="UTF-8"?><!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd"><plist version="1.0"><dict> <key>compileBitcode</key> <true/> <key>destination</key> <string>export</string> <key>method</key> <string>development</string> <key>signingStyle</key> <string>automatic</string> <key>stripSwiftSymbols</key> <true/> <key>teamID</key> <string>xxxxxxxx</string> <key>thinning</key> <string>&lt;none&gt;</string></dict></plist>
复制代码

如果你觉得使用命令行的方式相对麻烦的话,可以考虑使用打包工具 fastlane(后面我再专门写文章介绍)。

发送消息通知

企业微信中可以创建一个群机器人,然后通过 webhook 来进行消息通知。企业微信提供了详细的配置方式,可以参考:企业机器人配置。其本质上就是发送了一个请求:

curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=693axxx6-7aoc-4bc4-97a0-0ec2sifa5aaa' \   -H 'Content-Type: application/json' \   -d '   {        "msgtype": "text",        "text": {            "content": "hello world"        }   }'
复制代码

我们只需要将 key 替换成我们创建机器人的 key 即可。

整合之后的.gitlab-ci.yml 配置文件

最后贴一个我在项目中使用的配置文件,如下所示:

variables:  CONFIGURATION: "Debug"  WORKSPACE: "xxxx.xcworkspace"  SCHEME_NAME: "xxxx"  EXPORT_MAIN_DIRECTORY: "build"  EXPORT_OPTIONS_PLIST: "ExportOptions-dev.plist"  CODE_SIGN_IDENTITY: "xxxxxx"  PROVISIONING_PROFILE: "xxxxx"  LANG: "en_US.UTF-8"
stages: - makedir - archive - ipa - upload - notify# 创建对应目录dir_job: stage: makedir script: - mkdir $EXPORT_MAIN_DIRECTORY - EXPORT_MAIN_DIRECTORY=$EXPORT_MAIN_DIRECTORY/$(date "+%Y%m%d%H%M%S") - echo $EXPORT_MAIN_DIRECTORY - mkdir $EXPORT_MAIN_DIRECTORY tags: - ios
# 构建archivearchive_job: stage: archive script: - agvtool next-version -all # 更新构建号,版本号之后再更新 - xcodebuild clean -workspace $WORKSPACE -scheme $SCHEME_NAME - xcodebuild -workspace $WORKSPACE -scheme $SCHEME_NAME -configuration Debug archive -archivePath $EXPORT_MAIN_DIRECTORY/$SCHEME_NAME.xcarchive artifacts: expire_in: '2 day' name: "下载xcarchive,保留2天" paths: - $EXPORT_MAIN_DIRECTORY/$SCHEME_NAME.xcarchive tags: - ios# 导出ipaipa_job: stage: ipa script: - echo 'export ipa' - xcodebuild -exportArchive -archivePath $EXPORT_MAIN_DIRECTORY/$SCHEME_NAME.xcarchive -exportPath $EXPORT_MAIN_DIRECTORY -exportOptionsPlist $EXPORT_OPTIONS_PLIST artifacts: expire_in: '5 day' name: "下载ipa,保留5天" paths: - $EXPORT_MAIN_DIRECTORY/$SCHEME_NAME.ipa only: - qa tags: - ios# 上传ipaupload_job: stage: upload script: - curl -H "Authorization:Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJkYXRhIjp7Il9pZCI6IjVlOTE4Yzc5MmMzZGQ0MDAxZTRiOGY1YiIsInVzZXJuYW1lIjoic3VodWNoZW4ddiLCJlbWFdddpbCI6InN1aHVjaGVuQHFxLmNvbSJ9LCJleHAiOjQ3NDAxOTcyODgsImlhdCI6MTU4NjU5NzI4OH0.5UUkM4lJddYrnvXvHaNNJIY_j5OsBQmLw0mBUrXG3d9E4" -F "file=@$EXPORT_MAIN_DIRECTORY/$SCHEME_NAME.ipa" http://上传包地址/api/apps/5e916b9eac2363001dd7554a/upload only: - qa tags: - ios
# 构建失败时的通知消息notifyFailWeChat: stage: notify script: - curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=26b07c1b-03ea-49da-afc7-f68a359f2a52' -H 'Content-Type:application/json' -d "{\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"ios项目构建结果:<font color=\\"warning\\">失败</font>\n>本次构建由:$GITLAB_USER_NAME 触发\n>项目名称:$CI_PROJECT_NAME\n>提交号:$CI_COMMIT_SHA\n>提交日志:$CI_COMMIT_MESSAGE\n>构建分支:$CI_COMMIT_BRANCH\n>流水线地址:[$CI_PIPELINE_URL]($CI_PIPELINE_URL)\"}}" tags: - ios only: - qa when: on_failure
# 构建成功时的通知消息notifySuccessWeChat: stage: notify script: - curl 'https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=26b07c1b-03ea-49da-afc7-f68a359f2a52' -H 'Content-Type:application/json' -d "{\"msgtype\":\"markdown\",\"markdown\":{\"content\":\"ios项目构建结果:<font color=\\"info\\">成功</font>\n>请前往发布平台下载体验:[下载地址](http://app下载地址)\n>本次构建由:$GITLAB_USER_NAME 触发\n>项目名称:$CI_PROJECT_NAME\n>提交号:$CI_COMMIT_SHA\n>提交日志:$CI_COMMIT_MESSAGE\n>构建分支:$CI_COMMIT_BRANCH\n>流水线地址:[$CI_PIPELINE_URL]($CI_PIPELINE_URL)\"}}" tags: - ios only: - qa when: on_success
复制代码

总结

如果你们公司目前还没搞起来 Jenkins,我推荐尝试用 gitlab 实现 ci/cd 流水线,因为可以减少很多配置和插件的安装。相对来说实现成本更低一些,从目前我用 gitlab ci 的情况来看,基本上 Jenkins 能实现的 gitlab ci 都能满足。


发布于: 2020 年 05 月 20 日阅读数: 211
用户头像

Zoe

关注

追求卓越,成功就会在不经意间追上你!! 2017.10.23 加入

欢迎关注我的个人公众号:“软件测试布道师”。 互联网从业者,深耕软件测试领域,在测试开发技术栈、持续集成、自动化等方面都有一定的经验。另外对职场、职业规划也有一定的思考。愿意和大家一起成长,一起进步。

评论

发布
暂无评论
使用gitlab ci构建IOS包并发送通知消息到企业微信