刚开始打算直接用jenkins去走完整一条持续集成的踩坑之路。
然后发现jenkins上面坑比较多,网上的对于某一个问题解决方案也各式各样,同样遇到的问题有人提问,没人回答,有的回答的然后去试了,感觉越踩越深,可能官方的坑吧。感觉Jenkins配置比较麻烦,学习成本比较高。所以后面采取的是jenkins + fastlane进行持续集成操作。后面又涉及到批量打包,所以就采用了xconfig这种模式。
Jenkins主要用于拉取远程代码,然后提供了一个可视化的界面
fastlane主要用于构建工程,上传的appstore 或者蒲公英等第三方托管平台。
Jenkins在这里的操作就是操作fastlane去打包
一些比较好的文献:建议踩坑之前先看
http://www.jianshu.com/p/5cad74906159 Jenkins For iOS安装
https://whlsxl.github.io/#to_app_store [小团队的自动化发布-Fastlane带来的全自动化发布]
http://www.jianshu.com/p/c69deb29720d 一步一步构建iOS持续集成:Jenkins+GitLab+蒲公英+FTP
Jenkins 一些简单的介绍:
Jenkins是一个开源软件项目,是基于Java开发的一种[持续集成]工具,用于监控持续重复的工作,旨在提供一个开放易用的软件平台,使软件的持续集成变成可能。
Jenkins 安装方式总结下我碰到的有三种:
一种是直接去官网下载Jenkins的pkg安装包进行安装
一种是下载java.war方式,这个和第一种其实一样的
还有一种就是通过Homebrew进行安装,这些网上都有比较详细的教程的。
他们安装的路径时不一样的。
pkg安装我遇到一个问题就是本地处于offline的状态,安装不了插件,我跳过安装插件,直接完成平台的初始化配置,当我登录Jenkins平台,进入 系统管理——管理插件,点击可选插件时出现这样一个错误
网上翻了一圈,什么方法都尝试了一下,感觉是java CA证书受信的问题。耽搁了很长时间,于是我尝试了brew安装的方式,在用brew安装的时候需要注意下,brew安装的和pkg安装的其实是可以共存的,pkg安装默认占用了8080端口,并且开机会自动启动Jenkins服务,你想运行brew安装的版本时可以找到brew 安装的Jenkins的jenkins.war路径,然后给他换个端口启动:(mac如果用brew安装的话应该路径一样)
使用如下命令 9999为端口号,当某个端口被占用时也可以这样切换
java -jar /usr/local/Cellar/jenkins/2.79/libexec/jenkins.war --httpPort=9999
brew安装的时候也出现了offline的提示,看了插件库也是一样的报错,然后找到了一个解决方案:
在安装插件时出现这个问题(原因和解决方案看下面地址)
Jenkins PKIX path building failed
http://www.cnblogs.com/cuiliqiang/p/4039395.html
brew 安装的方式,首先需要你本地装了Homebrew
brew install jenkins
终端命令启动
jenkins
开机自动启动:
ln -sfv /usr/local/opt/jenkins/*.plist ~/Library/LaunchAgents
卸载
brew uninstall jenkins
jenkins 启动需要双击jenkins.war文件(如果使用Homebrew安装只需要在终端 使用命令 jenkins)
在本地浏览器输入localhost:8080 如果没出现jenkins页面应该是服务没起来。
如果终端机使用jenkins命令报以下错误则是端口冲突
可以手动修改jenkins端口号
终端使用该命令:java -jar jenkins.war(该文件绝对路径) --httpPort=9999
brew安装的路径应该是这个/usr/local/Cellar/jenkins/2.79/libexec/jenkins.war
然后浏览器localhost:9999 应该就会出现jenkins界面
java -jar /usr/local/Cellar/jenkins/2.79/libexec/jenkins.war --httpPort=9999
- 首先要得到StartCom的证书文件(xxx.cer)。从哪里获得呢?既然浏览器能够正常访问,说明系统中是信任StartCom的证书的,所以先打开系统的证书管理界面。在Mac中是Keychain,打开之后找到StartCom的证书,然后右键导出成一个.cer文件,命名为startcom.cer。
- 然后使用下面的命令把上面那个cer文件导入到Java的运行时系统中:
keytool -import -alias startcom -keystore %JRE_HOME/lib/security/cacerts -file startcom.cer
运行该命令时会提示输入密码,如果你没有改过的话密码是’changeit’
但当我运行pkg安装方式的Jenkins时,发现上面那个问题还存在,脑袋疼。。。不知道为什么,如果有大神知道的话可以评论里告知一下。
后面的操作都是在brew方式安装的Jenkins配置的
开始先安装了一些插件:像Xcode git svn这些都是有必要装一下的
我们公司时gitLab 所以也安装了这些插件,可以直接在插件库里面过滤,或者网上找一下。
然后就是配置一些证书(用于获取用户权限的证书,比如从gitLab拉取代码权限这些)
如果通过SSH这种方式去获取用户权限需要配置SSH,简单讲一下:
拉取代码的时候GitLab可以通过git和http方式去获取密码,git这种方式需要配置SSH key。
在使用SSH key时候还是遇到比较多的问题的,好像都是GitLab服务器的问题。
使用http这种去拉取代码还是比较顺利的
配置SSH Key
在Jenkins管理页面,选择“Credentials”,然后选择“Global credentials (unrestricted)”,点击“Add Credentials” 具体配置如下图:
ID会自动生成
Passphrase 是生成SSH Key第二步那个加密私钥的密码
——————————顺便扯一下ssh公钥和私钥的生成——————————
本机生成SSH:ssh-keygen -t rsa -C “Your email” , 生成过程中需设置密码,最终生成id_rsa和id_rsa.pub(公钥)
Gitlab上添加公钥:复制id_rsa.pub里面的公钥添加到Gitlab
Jenkins上配置密钥到SSH:复制id_rsa.pub里面的公钥添加到Jenkins(private key选项)
生成SSH 时会有一步让你输Passphrase,建议不要设密码,我踩坑的时候设置了这个在我构建项目的时候每次都让我输入,验证身份,会比较麻烦
如果在项目配置中采用xcode 这种方式去构建版本的话需要去这里配置下Keychains and Provisioning Profiles
Keychains and Provisioning Profiles Management
后面就是配置项目了,网上还是有比较多教程的,跟着配就行了,我这边在构建环节没有用Xcode的方式,开始尝试了,但是失败了。这个坑周末填了两天都没走出来,网上说这是xcode 9 的一个bug,找不到描述文件。
Error Domain=IDEProvisioningErrorDomain Code=9 ""********.app" requires a provisioning profile." UserInfo={NSLocalizedDescription="********.app" requires a provisioning profile., NSLocalizedRecoverySuggestion=Add a profile to the "provisioningProfiles" dictionary in your Export Options property list.}
https://issues.jenkins-ci.org/browse/JENKINS-45509
尝试了各种小道方法,还是不行,所以最后打算在构建环节 使用Execute shell的方式配合fastlane 脚本进行构建项目。
Fastlane是用Ruby语言编写的一套自动化工具集和框架,每一个工具实际都对应一个Ruby脚本,用来执行某一个特定的任务,而Fastlane核心框架则允许使用者通过类似配置文件的形式,将不同的工具有机而灵活的结合在一起,从而形成一个个完整的自动化流程。
感觉网上Fastlane比Jenkins的资料多一点,Fastlane不能远程操作,拉取代码等,所以采用了这两者的结合方式,感觉还是比较好用的。
下面讲一下 fastlane
首先,安装 安装方式网上很多,随便搜一下就有了,我在安装过程中没遇到什么问题。
就遇到一个xcpretty 找不到,但是这个应该是fastlane会配套安装的,不知道是不是版本问题,还有fastlane更新比较快,一周升级了三个小版本。
安装好之后 cd到工程目录下,然后
fastlane init
这里肯定会被创建的是Appfile和Fastfile。如果Deliverfile,screenshots和metadata目录没被创建,可以运行deliver init来创建。(这里备注下,我在使用299账号进行init操作时候只生成了Appfile和Fastfile文件,fastlane应该做了能不能提交市场的区分吧,在使用99账号进行init 操作时则都生成了)
Fastfile => 用来定义所有的lane任务
Appfile => 是用来存储一些公共信息的,比如app_identifier,apple_id,team_id,itc_team_id等。
Deliverfile => deliver的配置文件
PS:
这里有个小问题,iTC和ADC中的Team ID是不一样的,在fastlane init中只会自动在Appfile里写入ADC的team_id,所以在这个过程中会不停的问你iTC的Team ID,所以在创建完Appfile后,手动在里面添加itc_team_id。
这个注意下,在Jenkins运行Fastfile脚本时候需要在Appfile中先指定团队名以及团队id,不然会打包不成功,因为你不指定证书,Fastfile会询问你,Jenkins中你没办法操作,不像终端
Fastfile是进行任务操作的一个文件
里面会有一些 before_all do after_all do这些操作,这个看看名字就知道了吧,before_all do一般做一些环境以及路径的配置,cocoapods 的一些操作,当然你也可以直接也在命令主体里面写
这样就可以看成一个方法,可以进入到你要操作的项目的目录下 在终端使用 fastlane upload ,下面的方法就会执行了,注意fastlane在写脚本的时候记得 configuration 设置成你要打包时候的设置成你要打包的那个configuration。
desc "Deploy a new version to the App Store"
lane :upload do
# match(type: "appstore")
# snapshot
gym(
scheme: "******************", # Build your app - more options available
clean:true, # 在构建前先clean
configuration:"Release", # 配置为Release版本
codesigning_identity: "iPhone Distribution: ****************** Co. Ltd. (JQ******************)”,
export_method:"enterprise",
)
pgyer(api_key: "15a8******************78245", user_key: "faf7******************9edf2ff1")
# frameit
end
这个是打包上传蒲公英的方法,但是记得在fastlane init操作的时候填299的账号,同样,上传appstore时fastlane init操作时记得填99的账号
Fastlane是一套工具集,包括:
测试
scan => 自动运行测试工具,并且可以生成漂亮的HTML报告
证书,配置文件
cert => 自动创建管理iOS代码签名证书
sigh=> 一声叹息啊,这么多年和Provisioning Profile战斗过无数次。总是有这样那样的问题导致配置文件过期或者失效。sigh是用来创建、更新、下载、修复Provisioning Profile的工具。
pem=> 自动生成、更新推送配置文件
match => 一个新的证书和配置文件管理工具。
截图
snapshot => 用Xcode7推出的UI test功能实现自动化截图
frameit=> 可以把截的图片自动套上一层外边框
编译
shenzhen => 当年大名鼎鼎的自动编译工具,现在已经被弃用了
gym=> Fastlane家族的自动化编译工具,和其他工具配合的非常默契
发布
produce => 如果你的产品还没在iTunes Connect(iTC)或者Apple Developer Center(ADC)建立,produce可以自动帮你完成这些工作
deliver => 自动上传截图,APP的元数据,二进制(ipa)文件到iTunes Connect
TestFlight管理
pilot=> 管理TestFlight的测试用户,上传二进制文件
boarding => 建立一个添加测试用户界面,发给测试者,可自行添加邮件地址,并同步到iTC
辅助工具spaceship=> 为pilot,boarding和deliver等工具提供和 iTC 和 ADC 的交互API。spaceship本来是个独立的项目,后来被Fastlane收编进来
WatchBuild=> 是一个独立的iTC监控工具,开启WatchBuild可以监控iTC上的文件状态,弹出MacOS自带的Notification
Android
supply => 自动上传到Google Play工具(如果有时间,我想把国内提供API的Android Store都写个插件自动上传,这个问题从10年我刚开始工作就觉得是个痛点)
screengrab => Android的自动截图工具
Fastlane功能强大,只尝试了比较少的功能,时时更新。
——————————fastlane一些脚本————————————
提交到苹果市场
lane :upload do
# match(type: "appstore")
# snapshot
gym(
scheme: "******", # Build your app - more options available
clean:true, # 在构建前先clean
configuration:"Release", # 配置为Release版本
export_method:"app-store",
)
deliver(force: true)
end
走testflight进行内测
lane :uploadTotest do
# match(type: "appstore")
# snapshot
gym(
scheme: "*******", # Build your app - more options available
clean:true, # 在构建前先clean
configuration:"Release", # 配置为Release版本
export_method:"app-store",
)
pilot
# frameit
end
这个会等地比较久的时间,因为ipa到苹果市场要