使用初衷
公司产品版本比较多,很多版本都需要独立化部署。导致产生了每个地址需要打包,每次打包就是一件麻烦的事情,常常一下午的时间过去了却都浪费在打包这件事情上了。So…研究了下Fastlane+Jenkins+蒲公英。可以方便的发布和管理版本。爬了很多坑。写出来让大家参考下。
蒲公英也可以用fir.im代替,后续也可以持续集成webhook机器人,邮件等通知推送。
方案选择
方案很多种,看自己情况选择。
1、利用空闲苹果电脑做服务器,跑Jenkins用来自动监听,只要git合并上传,就自动打包。
2、本地安装jerkins(不建议)。
3、本地主动触发/利用Alfred编写插件执行流程。
基础名词
-
Ruby,一种简单快捷的面向对象(面向对象程序设计)脚本语言
-
RVM是一个命令行工具,它允许您轻松地安装,管理和使用从解释器到多组gems多个ruby环境。
-
Gems RubyGems简称gems,是一个用于对 Ruby组件进行打包的 Ruby 打包系统。例如经常用的cocoapods就需要 gem 来管理。
-
Fastlane是Felix Krause大神写的fastlane是一套使用Ruby写的自动化工具集,用于iOS和Android的自动化打包、发布等工作。
-
pgyer/fir 第三方发布测试平台。
爬坑攻略
如果你在安装期间想很顺利的话,请务必按照步骤去做,本教程只针对Mac。
此文档是二次更新的,因为第一次写的时候,就根据安装记录写出来了,第二次在别的机器上部署的时候,就出现了各种问题,所以就有了这次的更新内容。
Ruby处理
使用Mac的小伙伴都应该能感受OSX的好处,本人对Mac中毒很深,要是让我说一点什么不好的话,就是价格太高。
各种环境,系统都自带了ruby,python等等,且不会出现全家桶的问候。
Mac系统自带ruby,但是是给系统自己使用,权限很小,所以在平时使用过程中,会出现很多问题,而且版本一般都比较低,所以大多人都在自己使用RVM来管理自己使用的ruby.
参照此文档来安装 RVM使用ruby 使用RVM来管理rubyhttps://www.jianshu.com/p/c44ef74d99f9
ruby安装完成之后,来进行下一步。
Fastlane 安装初始化
- 确保你已经安装了最新版本的Xcode命令行工具:
xcode-select --install
下方图片是已经安装则不用处理。
-
官方文档支持三种方式安装,我使用的是ruby,刚才不是使用RVM来管理自己的ruby 么,接下来我们来安装fastlane
gem install fastlane -NV
方法 | os支持 | 描述 |
---|---|---|
Homebrew | 苹果系统 | brew cask install fastlane |
安装程序脚本 | 苹果系统 | 下载zip文件。然后双击install脚本(或在终端窗口中运行)。 |
RubyGems | 带有Ruby版本> 2.0.0 | gem install fastlane -NV |
如果使用的是系统自带的ruby,可能会报错没有权限。
ERROR: While executing gem ... (Gem::FilePermissionError) You don't have write permissions for the /Library/Ruby/Gems/2.3.0 directory.ERROR: While executing gem ... (Gem::FilePermissionError) You don't have write permissions for the /usr/bin directory.
查看自己是否使用的是自己管理的ruby
which ruby> 返回/Users/seven/.rvm/rubies/ruby-2.4.1/bin/ruby> 则说明已经使用RVM管理的Ruby了,非系统自带的。> 如果是usr/bin这个目录下的则说明还在使用系统自带的,可能会出现一系列权限的问题,请更换。
如果你非要使用系统自带的,也可以,也可能出现问题,也可能没事,跟系统版本也有关系,
下面给出系统自带问题的一些些方法。如跟我一样使用非系统自带ruby,请跳过此步骤。
> 方法一:sudo gem install fastlane -NV //提升权限,部分系统权限还是不够。> 方法二:安装到别的目录使用指定目录安装: sudo gem install -n /usr/local/bin fastlane> 方法三:还是使用RVM管理ruby
- 初始化
安装完毕后,在终端进入到你的项目目录下。初始化fastlane
fastlane init
如果没有报错,就跳过此条继续报错Exit status of command ‘bundle exec pod install’ was 1 instead of 0. bundler: failed to load command: pod (/usr/local/bin/pod)解决方法:在项目根目录下 fastlane/Fastfile 修改文件中的cocoapods’ cocoapods(use_bundle_exec: false)’
这4个选项意思分别是:
-
自动截屏。
-
自动发布beta版本用于TestFlight。
-
自动的App Store发布包。我们的目标是要提交审核到APP Store,按道理应该选这个,但这里我们先不选,因为选择了以后会需要输入用户名密码,以及下载meta信息,需要花费一定时间,这些数据我们可以后期进行配置。
-
手动设置。(推荐)
如果选择了3 会提示让你输入账号(我选择手动配置)
按照提示输入开发者账号(付费账号) 输入Bundle Identifier 用于初始化配置,后期可在配置文件改。随便输入根据提供的信息,fastlane会自动为您生成一个配置。
您可以看到新创建的./fastlane目录,包含Appfile和Fastfile文件。
最有趣的文件是fastlane/Fastfile,其中包含分发您的应用程序所需的所有信息。
这样就完成了初始化
蒲公英插件安装
初始化完毕后直接在终端输入
//fastlane fastlane search_plugins//列出可用插件fastlane add_plugin pgyer//安装插件
插件安装成功./fastlane目录下会生成Pluginfile的一个文件。插件安装不成功,就是fastlane安装的有问题。
配置Fastlane
文件名 | 描述 |
---|---|
Appfile | 从 Apple Developer Portal 获取和项目相关的信息 详情 |
Fastfile | 核心文件,存放lane任务 |
Deliverfile | deliver的配置文件,从 iTunes Connect 获取和项目相关的信息详细 |
metadata | 同步iTC中的元数据 |
screenshots | 同步iTC中的截图 |
fastlane工具集是配置fastlane最重要的
文件名 | 描述 |
---|---|
match | 证书和配置文件管理工具会重置证书,推荐新项目使用。🌟🌟🌟🌟🌟 |
cert | 自动创建管理iOS代码签名证书,会去自动创建证书,永远不会撤销现有的证书。如不能创建会报错。 |
sigh | 用来创建、更新、下载、修复Provisioning Profile的工具 |
gym | 自动化编译打包工具.shenzhen的代替品.🌟🌟🌟🌟🌟【本文使用gym打包】 |
pem | 自动生成、更新推送配置文件 |
produce | 如果你的产品还没在iTunes Connect(iTC)或者Apple Developer Center(ADC)建立,produce可以自动帮你完成这些工作 |
deliver | 自动上传截图,APP的元数据,二进制(ipa)文件到iTunes Connect |
snapshot | 自动截图(基于Xcode7的UI test) |
frameit | 可以把截的图片自动套上一层外边框 |
pilot | 管理TestFlight的测试用户,上传二进制文件 |
boarding | 建立一个添加测试用户界面,发给测试者,可自行添加邮件地址,并同步到iTunes Connect(iTC) |
scan | 自动运行测试工具,并且可以生成漂亮的HTML报告 |
spaceship | 为pilot,boarding和deliver等工具提供和 iTC 和 ADC 的交互API。spaceship本来是个独立的项目,后来被Fastlane收编进来 |
WatchBuild | 是一个独立的iTC监控工具,开启WatchBuild可以监控iTC上的文件状态,弹出MacOS自带的Notification |
supply | Android自动上传到Google Play工具 |
screengrab | Android的自动截图工具 |
关于Appfile:
-
app_identifier(“bundle identifier”) # The bundle identifier of your app
-
apple_id(“xxx@xx.com”) # Your Apple email address
-
itc_team_id(“App Store Connect Team ID”) # App Store Connect Team ID
-
team_id(“Developer Portal Team ID”) # Developer Portal Team ID
这些在xcode或者appstore就能看到。
关于fastfile:
-
里面存放了很多lane,每个lane相当于按顺序执行的工作流。每个lane可以存放多个action,action可以看做具体的执行动作
-
生命周期
执行顺序 | 方法名 | 说明 |
---|---|---|
1 | before_all | 在执行 lane 之前只执行一次 |
2 | before_each | 每次执行 lane 之前都会执行一次 |
3 | lane | 自定义的任务 |
4 | after_each | 每次执行 lane 之后都会执行一次 |
5 | after_all | 在执行 lane 成功结束之后执行一次 |
6 | error | 在执行上述情况任意环境报错都会中止并执行一次 |
- 任务定义
定义 | 是否必须 | 说明 | 备注 |
---|---|---|---|
desc | false | 方法描述 | 可多次使用达到换行的目的 |
name | true | 方法名 | 符号化的方法名 |
options | false | 方法参数 | 返回 Hash 类型 |
task | true | 方法主体 | 参考 ruby 的方法代码且支持 ruby 代码 |
- 一个简单的lane
lane :deploy do # 执行 pod instasll cocoapods # 执行 carthage bootstrap carthage # 增加build版本号 increment_build_number # 编译代码 gym # 发布到Apple Store deliver(force: true)end
-
fastlane示例
-
这个是我自己 配置到蒲公英的。同时导出ipa到./build文件夹下,以版本号和打包时间命名。这样就保留了每一版本包了。记得要在git中忽略./build文件夹。否则你会后悔的。
只需要项目根目录下执行即可(暂时还不行,需要看下下方gym配置)
fastlane topgyer desc:更新内容
desc "上传到测试版本到蒲公英"
desc "生成本地版本"
lane :topgyer do|option|
puts "*************| 开始打包喽 |*************"
#自动增加build
# increment_build_number
#自动生成证书
cert
#自动生成配置文件
# sigh(force: true)//我使用的是手动配置关闭这个。如需自动则打开即可
#gym配置,打包输出。
#fastlane gym --export_method ad-hoc
#fastlane gym --export_method enterprise
#fastlane gym --export_method app-store
scheme_name = "xxxx"//应用名词
version = get_version_number_from_plist(xcodeproj: "#{scheme_name}.xcodeproj",
target: scheme_name,
plist_build_setting_support: true,
build_configuration_name: 'Release')
build = get_build_number_from_plist(xcodeproj: "#{scheme_name}.xcodeproj",
target: scheme_name,
plist_build_setting_support: true,
build_configuration_name: 'Release')
# 获取version和build版本号()
# version = get_info_plist_value(path: "./#{scheme_name}/Info.plist", key: "CFBundleShortVersionString")
# build = get_info_plist_value(path: "./#{scheme_name}/Info.plist", key: "CFBundleVersion")
#导出路径
output_directory = "./build"
#导出名称
output_name = "#{scheme_name}_#{version}_#{build}_#{Time.now.strftime('%Y%m%d%H%M%S')}.ipa"
gym(
export_method: "enterprise",//企业账号
scheme: scheme_name, //名词
clean: true,//是否清理上次编译
output_directory: output_directory,//导出路径
output_name: output_name//导出名词
)
puts "*************| 打包完成,开始上传到蒲公英 |*************"
pgyer(api_key: "1212121", update_description: "#{option[:desc]}-#{version}_#{build}")//蒲公英设置查看key
puts "*************| 上传蒲公英成功🎉 |*************"
puts "*************| 上传蒲公英成功🎉 |*************"
puts "*************| 上传蒲公英成功🎉 |*************"
#钉钉webhook机器人 url就是上方机器人信息中的webhook地址
curl = %Q{
curl 'url' \
-H 'Content-Type:application/json' \
-d '{
"msgtype":"markdown",
"markdown":{
"title":"测试包新版本来啦!🚀🚀🚀",
"text":"### 测试包新版本来啦!🚀🚀🚀
#### 下载地址:下载地址 ![](这里是对应的二维码图片地址)
##### @所有人"
},
"at":{
"isAtAll":true
}
}'
}
system curl
end
scheme 设置
没有在gym或者fastfile写应用的名字的话。打包的时候会自动检测当前目录下的文件。列出来供你选择。也可以设置一下在gym中直接赋值,或者fastfile中增加即可。
关于Gymfile:
-
gym是用来自动化编译打包工具.shenzhen的代替品.🌟🌟🌟🌟🌟【本文使用gym打包】
-
fastlane初始化Gym
fastlane gym init
会生成一个Gymfile的文件。 -
然后手动配置证书-Gymfile增加下面代码,同时不要使用自动生成配置文件这个选项sigh(force: true)
-
export_options( provisioningProfiles: { "com.xxx.xxx" => "profilesName", "com.xxx.xxxxxx" => "profilesName1" })
Fastlane问题汇总
使用过程中出现了很多问题,大部分问题都已经有人躺过水了,所以有问题先去看看issues
https://github.com/fastlane/fastlane/issues
gym编译报错解决不了请先检查三遍证书是否有问题
初始化报错请检查安装路径是否有问题。
问题 | 问题 |
---|---|
ruby -v 版本低于2.0.0 | gem版本不对 请升级ruby请更新gems |
cocoapods没有放到Gemfile中 | Gemfile文件中增加cocoapods |
fastlane init 提示sudo | 请检查ruby路径。如果没问题请检查user目录下.bash_profile。环境变量设置是否有效。export PATH=“ H O M E / . f a s t l a n e / b i n : HOME/.fastlane/bin: HOME/.fastlane/bin:PATH” |
The generated archive is invalid, this can have various reasons:Usually it’s caused by the Skip Install option in Xcode, set it to NO | xcode中修改build settings Skip Install 选项为NO |
如果初始化成功 | 其他的问题大部分都是证书问题了。 |
以上Fastlane本地配置就完成了,想要继续深入可以往下看利用jenkins持续集成。
Jenkins持续集成
在持续集成(Continuous integration,简称CI)这块,Jenkins无疑是目前使用的比较多的一个开源框架
JDK
系统要求:必须安装JDK 1.5以上版本,推荐安装最新版本的JDK[注意不支持java9]。可以通过以下命令查看是否安装JDK和JDK版本。JDK下载链接
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
如需卸载请看下文
java -version
- java卸载方法 以Mac为例子 [shift +cmd+g] 前往文件夹
- 在系统偏好设置面板移除Java
- JDK安装
下载完毕JDK后如图按照提示安装即可
安装 Jenkins
Jenkins的官网 下载最新的 war 包。
https://jenkins.io/download/
推荐使用【Long-term Support (LTS)稳定版】
下载完成后,打开终端,进入到 war 包所在目录直接运行,也可以将war包丢在Tomcat的webapp目录下面。
终端方式执行以下命令:
java -jar jenkins.war//默认对端口是8080如需指定可更改java -jar jenkins.war --httpPort=8888 //指定8888端口二者选一即可
初始化Jenkins
待Jenkins启动后,在浏览器页面输入以下地址:
http://localhost:8888//端口指定的多少写多少
注意不要关闭终端
第一次运行会出现如下界面,提示需要填写指定路径文件里面的内容(该内容也可以在终端上面看到)。
根据提示目录打开initialAdminPassword文件,复制出密码,填写,Continue.
Jenkins用户/secrets/目录是没有读写权限的。修改权限。
这样Jenkins初始化完毕了,可以快乐的使用了。还是介绍下如何使用吧。
Jenkins使用
- 启动方式
上文说了,如何初始化进入Jenkins,那么如果我关了再次怎么进入呢。别急hold~ 两种方式都可以
- 方式一 跟初始化一样,进入war包所在目录通过命令启动,
java -jar jenkins.war
- 方式二 运行命令来创建配置文件
sudo touch /Library/LaunchDaemons/org.jenkins-ci.plist
如果您使用了不同的用户名,请务必在plist中使用它。需要指定用户名,否则会以系统根用户的身份运行,这会让您在使用Jenkins时遇到麻烦
plist内容如下
<?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>Label</key> <string>Jenkins</string> <key>KeepAlive</key> <true/> <key>ProgramArguments</key> <array> <string>/usr/bin/java</string> <string>-Dmail.smtp.starttls.enable=true</string> <string>-jar</string> <string>/usr/local/opt/jenkins/libexec/jenkins.war</string> <string>--httpListenAddress=127.0.0.1</string> <string>--httpPort=8080</string> </array> <key>RunAtLoad</key> <true/> <key>UserName</key> <string>jenkins</string> </dict></plist>
现在可以重新启动或者运行下方命令来查看运行在http://localhost:8888的Jenkins 。
sudo launchctl load -w /Library/LaunchDaemons/org.jenkins-ci.plist
Jenkins配置
插件管理
使用默认方式安装的基本插件都包含了,如果有需要可以自己来管理插件
安全配置
在工作中可能要在Jenkins中创建用户,这样你的团队的其他成员就可以访问自己的工作。首先打开左侧菜单中的“管理Jenkins”页面,然后转到“配置全局安全性”。
启用安全性,如果不那么将允许任何登录用户做任何事情。
-
进入系统管理 -> Configure Global Security -> 点击”启用安全” 。启用安全下面选择,“Jenkins专有用户数据库”,勾选允许用户可以注册。然后在“授权策略”中选择“任何用户可以做任何事(没有任何限制)”。当然,也可以使用LDAP身份认证机制,直接使用外部统一的身份机制来做认证。
-
返回注册一个账户,登录之后再次进入安全管理。勾选“登录用户可以做任何事”,这样就只有登录用户才能做操作了。
创建项目
-
“新建” —> 勾选“构建一个自由风格的软件项目”
-
General
-
源码管理–Git
-
设置源码的仓库,以便让 Jenkins 知道我们的 iOS 项目的代码在哪里。因为我的代码放在自己的仓库中(如果你用 Github 等其他仓库也是类似),所以要先告诉 Jenkins 如何获取代码。RepositoryUrl就是git地址
首先,我们需要配置 SSH,我们可以在 Jenkins 的证书管理中添加 SSH。在 Jenkins 管理页面,选择“Credentials”,然后选择“Global credentials (unrestricted)”,点击“Add Credentials”,如下图所示,我们填写自己的 SSH 信息,然后点击“Save”,这样就把 SSH 添加到 Jenkins 的全局域中去了。
-
类型SSH
-
userName 就是git中的名字 能知道是谁上传下载的就可以
-
PrivateKey ssh中的私钥,/Users/用户名/.ssh/id_rsa
-
Passphrase git密码。
-
关于如何获取SSH大家可以看文尾,熟悉的人应该都会,不在此介绍
-
回到刚刚新建的任务中,在源码管理中,选择 Git,按下图填好相关信息。注意:Credentials 不需要选择。
-
同时也试了使用账号密码的Credentials。选择你账号密码创建的Credentials也可以。默认使用上边方法即可。
自动测试忽略,不需要设置触发器。
构建环境设置
- 直接用 fastlane 这个工具,所以这里不需要特别设置。
构建设置
- 选择使用shell进行构建 更新内容自己维护
cd /users/xxx/xxx //你项目根目录fastlane topgyer desc:更新内容!
构建后增加步骤
- 可以邮件通知人员,逗号隔开,通知构建失败
来个整体截图
开始构建
-
返回面板会发现自己刚才新建的任务
-
点击任务名称进入详情、可以修改任务配置项和构建版本
-
点击构建
-
休息一会
-
登陆蒲公英就会发现多了一个版本。
构建日志查看
- 构建失败或者想看到输出的,可以在任务详情,构建历史中,选择构建中的版本。
- 选择Console Output即可看到控制台输出
- 截取下最后输出success送给你
节点管理可以参考以下,暂时不介绍
http://blog.csdn.net/birthmarkqiqi/article/details/62236437https://www.jianshu.com/p/047362b11403
附加1 本地alfred自动构建后webhook通知
-
创建关键字
-
执行shell脚本
cd && cd '/Users/name/Desktop/test/'rm -r buildfastlane topgyer desc:{query}exit 0
这样就不用手动去打开页面,然后去执行了,省去了繁琐步骤。
-
webhook
webhook的话,如果用企业微信,蒲公英上传程序后默认可以集成,只需在蒲公英后台url中填写企业微信中群聊添加机器人Webhook的Url 就行了。
企业微信,钉钉,飞书集成可以看这个蒲公英官方文档。https://seed.pgyer.com/WGNQkEpP
当然也可以去各个应用端自己看api对接。
附加2 SSH设置
https://code.aliyun.com/help/ssh/README#ssh-keys
SSH key 可以让你在你的电脑和Code服务器之间建立安全的加密连接。先执行以下语句来判断是否已经存在本地公钥:
cat ~/.ssh/id_rsa.pub
如果你看到一长串以 ssh-rsa
或 ssh-dsa
开头的字符串, 你可以跳过 ssh-keygen
的步骤。
提示: 最好的情况是一个密码对应一个ssh key,但是那不是必须的。你完全可以跳过创建密码这个步骤。请记住设置的密码并不能被修改或获取。
你可以按如下命令来生成ssh key:
ssh-keygen -t rsa -C "你的邮箱@xx.com"
这个指令会要求你提供一个位置和文件名去存放键值对和密码,你可以点击Enter键去使用默认值。
用以下命令获取你生成的公钥:
cat ~/.ssh/id_rsa.pub
复制这个公钥放到你的个人设置中的SSH/My SSH Keys下,请完整拷贝从ssh-
开始直到你的用户名和主机名为止的内容。
如果打算拷贝你的公钥到你的粘贴板下,请参考你的操作系统使用以下的命令:
Windows:
clip < ~/.ssh/id_rsa.pub
Mac:
pbcopy < ~/.ssh/id_rsa.pub
GNU/Linux (requires xclip):
xclip -sel clip < ~/.ssh/id_rsa.pub
《一两浊酒》是我的个人公众号,我会分享一些自己的感悟,技术,理财和学习方法。如果您喜欢我的文章,可以关注公众号,获取最新内容及专辑。