Jenkins master-slave 的应用及 iOS 项目持续集成
背景
在公司一台服务机上搭建了Jenkins
,Linux
环境,主要用于WEP 前端
、Android
、iOS
的CI
服务,在没有过多去了解的情况下,我想当然的以为如果要打包 iOS
,Jenkins
宿主机系统环境必须是MacOS
,因为知道除了Mac
,其它系统均无法打包iOS
或Mac
应用程序(当然这点在目前看来仍然是对的),于是在公司那台硬盘只剩下可怜巴巴的20G
空间的Mac mini
上安装了Jenkins
,叫安卓同事把他的Jenkins job
又重新放在了Mac mini
上,本想着事情就这么不完美的收尾了,今天忽然在群里看见开发者朋友讨论Jenkins
说到Jenkins
支持master-slave
(主从)模式,支持非宿主机作为一个Node
节点为其服务,一脸蒙蔽,又要把Jenkins
放回Ubuntu
,让这台mini
单独为iOS
打包服务。
新建Node
节点机
基本设置
步骤 Manage Jenkins
-> Manage Nodes
-> New Node
;
取名,比如叫slave-iOS
,勾选Permanent Agent
,下一步;
看说明填写:
- Name: 节点机名称
- Description: 节点机描述
of executors:节点机最大
job
并发数- Remote root directory : 节点机用于存放
workspace
的目录,确保你要使用的用户有该目录的读写权限,比如设置为/Users/VanJay/Documents/Work/tungee/jenkins
- Labels:标签,用于
Jenkins
查找Node
- Usage:自行选择,
- Use this node as much as possible:最大程序使用
- Only build jobs with label expressions matching this node:只在使用该节点机才使用
- Launch method:连接节点机的方式
- Launch agent agents via SSH:通过
SSH
连接- Host:节点机
IP
- Credentials:凭据,自行添加,如果使用
Username with password
,记得把验证策略下面这项选第三项 - Host Key Verification Strategy:
- Known hosts file Verification Strategy:把
master``ssh
公钥拷贝到slave
机known_hosts
- Manually provided key Verification Strategy:手动提供 key
- Manually trusted key Verification Strategy:手动信任
- Non verifying Verification Strategy:不验证
- Known hosts file Verification Strategy:把
- Host:节点机
- Launch agent via execution of command on the master:指定
shell
脚本连接
- Launch agent agents via SSH:通过
- AvailabilityL
slave
机可用性- Keep this agent online as much as possible:让
slave
尽可能在线 - Take this agent online according to a schedule:根据计划保持在线
- Take this agent online when in demand, and offline when idle:需要时在线,闲置时离线
- Keep this agent online as much as possible:让
Node Properties:节点机属性设置
可以在slave
机上设置工具位置和环境变量
- Environment variables:自定义环境变量,比如可以导出
PATH=$PATH:/usr/local/bin
- Tool Locations:工具位置:比如可以设置
JDK
目录/Library/Java/JavaVirtualMachines/jdk1.8.0_91.jdk/Contents/Home
使用slave
机器
在job
里General
项下勾选Restrict where this project can be run
,指定slave
机label
就可以使用了。
事情总不会那么一帆风顺
使用slave
机器后你会发现原本在slave
本机跑没事的shell
在这里可能有问题,基本都是commomand not fuond
,都是命令找不到,那就export
这些命令,把整个/usr/local/bin
或者/usr/bin
加进去(没必要,个人建议用到什么加什么)。
比如加入报pod command not found
,在slave
机运行which pod
:
☁ blog [master] ⚡ which pod
/usr/local/bin/pod
嵌入环境变量
安装Inject environment variables
插件,安装方法可在本博客搜索 Ubuntu-18-04-搭建-Jenkins
查看文章。
正常shell
打包
source ~/.alias
# 清除上一次生成的 beta 包
rm -rf ${OUTPUT_FOLDER}
export LANG=en_US.UTF-8
PODS_DIR="Pods"
if [[ -d "$PODS_DIR" ]]; then
rm -rf "$PODS_DIR"
fi
setproxy
pod install
unsetproxy
# 解锁 keychain
security default-keychain -s login.keychain
security unlock-keychain -p "123456." login.keychain
fastlane beta
source ~/.alias
是为了能找到setproxy
和unsetproxy ``shell
翻墙加快 pod install
速度,必须解锁keychain
,否则无法正常签名,导致构建失败,如果是在本机操作则不需要这两项。
fastlane 内容
只编写了打beta
和release
包
fastlane_version "2.28.3"
default_platform :ios
scheme_name = "DongKe"
workspace = 'DongKe.xcworkspace'
configuration_Debug = 'Debug'
configuration_Release = 'Release'
export_method_ad_hoc = 'ad-hoc'
export_method_appstore = 'app-store'
team_id = 'TEAM_ID'
username = 'xxx@xxx.com'
app_identifier = 'app_identifier'
platform :ios do
before_all do
# cocoapods
end
desc "截图"
lane :snap do
snapshot(
scheme: scheme_name
)
frameit(white: true, path: 'fastlane/screenshots')
end
lane :test do
end
desc "打包测试包"
lane :beta do |options|
#根据传入参数version设置app的版本号
# increment_version_number(version_number: option[:version])
# #自动增加build号
# increment_build_number
# 获取是第几轮测试
# test_turn = options[:test_turn]
# 自动运行测试工具
# scan
# 崩溃分析
# crashlytics
#证书签名
# sigh(
# adhoc: true,
# output_path: 'fastlane/mobileprovision'
# )
#编译打包
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 = File.expand_path("..", Dir.pwd) + File::Separator + 'build/beta/' + Time.now.strftime('%Y-%m-%d')
output_name = "#{scheme_name}_#{build}_#{export_method_ad_hoc}_#{Time.now.strftime('%Y-%m-%d %H%M')}.ipa"
gym(
silent: true,
clean: true,
buildlog_path: "fastlane/fastlane_log",
workspace: workspace,
scheme: scheme_name,
configuration: configuration_Release,
output_directory: output_directory,
output_name: output_name,
export_method: export_method_ad_hoc,
export_xcargs: "-allowProvisioningUpdates"
)
# 上传到 fir
# sh "fir publish #{output_directory}/#{output_name} -V -Q"
end
desc "打包正式包"
lane :release do |options|
#证书签名
# sigh(
# adhoc: false,
# output_path: './fastlane/mobileprovision'
# )
#编译打包
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 = File.expand_path("..", Dir.pwd) + File::Separator + 'build/release/' + Time.now.strftime('%Y-%m-%d')
output_name = "#{scheme_name}_#{build}_#{export_method_appstore}_#{Time.now.strftime('%Y-%m-%d %H%M')}.ipa"
gym(
silent: true,
clean: true,
buildlog_path: "fastlane/fastlane_log",
workspace: workspace,
scheme: scheme_name,
configuration: configuration_Release,
output_directory: output_directory,
output_name: output_name,
export_method: export_method_appstore,
export_xcargs: "-allowProvisioningUpdates"
)
end
lane :all do |options|
beta
release
end
after_all do |lane|
end
error do |lane, exception|
end
end