公司产品版本比较多,很多版本都需要独立化部署。导致产生了每个地址需要打包,每次打包就是一件麻烦的事情,常常一下午的时间过去了却都浪费在打包这件事情上了。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。
此文档是二次更新的,因为第一次写的时候,就根据安装记录写出来了,第二次在别的机器上部署的时候,就出现了各种问题,所以就有了这次的更新内容。
使用Mac的小伙伴都应该能感受OSX的好处,本人对Mac中毒很深,要是让我说一点什么不好的话,就是价格太高。
各种环境,系统都自带了ruby,python等等,且不会出现全家桶的问候。
Mac系统自带ruby,但是是给系统自己使用,权限很小,所以在平时使用过程中,会出现很多问题,而且版本一般都比较低,所以大多人都在自己使用RVM来管理自己使用的ruby.
参照此文档来安装 RVM使用ruby 使用RVM来管理rubyhttps://www.jianshu.com/p/c44ef74d99f9
ruby安装完成之后,来进行下一步。
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安装的有问题。
文件名 | 描述 |
---|---|
Appfile | 从 Apple Developer Portal 获取和项目相关的信息 详情 |
Fastfile | 核心文件,存放lane任务 |
Deliverfile | deliver的配置文件,从 iTunes Connect 获取和项目相关的信息详细 |
metadata | 同步iTC中的元数据 |
screenshots | 同步iTC中的截图 |
文件名 | 描述 |
---|---|
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的自动截图工具 |
app_identifier(“bundle identifier”) # The bundle identifier of your app
apple_id(“[email protected]”) # 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就能看到。
里面存放了很多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 :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
没有在gym或者fastfile写应用的名字的话。打包的时候会自动检测当前目录下的文件。列出来供你选择。也可以设置一下在gym中直接赋值,或者fastfile中增加即可。
gym是用来自动化编译打包工具.shenzhen的代替品.【本文使用gym打包】
fastlane初始化Gym fastlane gym init
会生成一个Gymfile的文件。
然后手动配置证书-Gymfile增加下面代码,同时不要使用自动生成配置文件这个选项sigh(force: true)
export_options(
provisioningProfiles: {
"com.xxx.xxx" => "profilesName",
"com.xxx.xxxxxx" => "profilesName1"
})
使用过程中出现了很多问题,大部分问题都已经有人躺过水了,所以有问题先去看看issues
https://github.com/fastlane/fastlane/issues
问题 | 问题 |
---|---|
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 1.5以上版本,推荐安装最新版本的JDK[注意不支持java9]。可以通过以下命令查看是否安装JDK和JDK版本。JDK下载链接
http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html
如需卸载请看下文
java -version
下载完毕JDK后如图按照提示安装即可
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启动后,在浏览器页面输入以下地址:
http://localhost:8888//端口指定的多少写多少
第一次运行会出现如下界面,提示需要填写指定路径文件里面的内容(该内容也可以在终端上面看到)。
根据提示目录打开initialAdminPassword文件,复制出密码,填写,Continue.
Jenkins用户/secrets/目录是没有读写权限的。修改权限。
这样Jenkins初始化完毕了,可以快乐的使用了。还是介绍下如何使用吧。
上文说了,如何初始化进入Jenkins,那么如果我关了再次怎么进入呢。别急hold~ 两种方式都可以
java -jar jenkins.war
sudo touch /Library/LaunchDaemons/org.jenkins-ci.plist
如果您使用了不同的用户名,请务必在plist中使用它。需要指定用户名,否则会以系统根用户的身份运行,这会让您在使用Jenkins时遇到麻烦
plist内容如下
Label Jenkins KeepAlive ProgramArguments /usr/bin/java -Dmail.smtp.starttls.enable=true -jar /usr/local/opt/jenkins/libexec/jenkins.war --httpListenAddress=127.0.0.1 --httpPort=8080 RunAtLoad UserName jenkins
现在可以重新启动或者运行下方命令来查看运行在http://localhost:8888的Jenkins 。
sudo launchctl load -w /Library/LaunchDaemons/org.jenkins-ci.plist
使用默认方式安装的基本插件都包含了,如果有需要可以自己来管理插件
在工作中可能要在Jenkins中创建用户,这样你的团队的其他成员就可以访问自己的工作。首先打开左侧菜单中的“管理Jenkins”页面,然后转到“配置全局安全性”。
启用安全性,如果不那么将允许任何登录用户做任何事情。
进入系统管理 -> Configure Global Security -> 点击”启用安全” 。启用安全下面选择,“Jenkins专有用户数据库”,勾选允许用户可以注册。然后在“授权策略”中选择“任何用户可以做任何事(没有任何限制)”。当然,也可以使用LDAP身份认证机制,直接使用外部统一的身份机制来做认证。
返回注册一个账户,登录之后再次进入安全管理。勾选“登录用户可以做任何事”,这样就只有登录用户才能做操作了。
设置源码的仓库,以便让 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也可以。默认使用上边方法即可。
cd /users/xxx/xxx //你项目根目录fastlane topgyer desc:更新内容!
来个整体截图
http://blog.csdn.net/birthmarkqiqi/article/details/62236437https://www.jianshu.com/p/047362b11403
创建关键字
执行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对接。
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
《一两浊酒》是我的个人公众号,我会分享一些自己的感悟,技术,理财和学习方法。如果您喜欢我的文章,可以关注公众号,获取最新内容及专辑。