前言
按照 iOS使用Jenkins自动打包+上传到 fir+钉钉通知(一) 的步骤来配置已可快速实现自动打包了。但测试、产品、设计人员反馈,通过复制打包任务的方式新建任务,仍显不够方便。鉴于此,提供一种通过选择分支和配置来打包的方式就能简化打包流程。
参数化构建页面概览如下:
参数化构建概览
使用方法
- 在任务详情页,点击 Build with Parameters
- 选择 打包分支
- 选择 打包配置
- 点击 开始构建 即可打包。
多次点击 开始构建 会创建多个任务,按照先后顺序排队,上一个任务完成后,自动开始下一个打包任务。
参数化构建
选择分支
步骤一 使用选择分支的功能,需要先安装 Git Parameter 插件。
Git Parameter
在 Jenkins 首页-系统管理-插件管理-Installed plugins 页面的输入框中,输入Git Parameter,选中Git Parameter,然后安装。安装完成后,在网址中输入链接 http://localhost:8080/restart 重启 Jenkins。
步骤二 安装好插件后,进入任务详情页,点击 配置-General,然后勾选上 参数化构建过程。
勾选参数化构建过程
步骤三 添加参数
添加参数
勾选上 参数化构建过程 后,点击 添加参数 ,在下拉菜单中选中 Git 参数。
步骤四 配置 Git 参数
- 在 Git 参数-名称中输入自定义名称,如:branchName。
- 在参数类型选项中选择-分支
- 在默认值中输入默认的打包分支
-
勾选上 Required Parameter
配置 Git 参数 - 配置完参数后,在源码管理中,将指定分支中的分支名换成
$branchName
即可将选中的分支用于打包分支。
在这里插入图片描述
打包配置选项
配置好了选择分支的功能,还要再配置一下选择 debug/release 的功能。点击 添加参数 ,在下拉菜单中选中 选项参数。
配置选项
- 在 选项参数-名称中输入自定义名称,如: configuration。
- 在选项中输入选项 Debug、Release,使用换行来分隔选项。
- 描述可输入备注信息,可不填。
配置
经过上面的配置后,点击 应用-保存 后,即可在任务详情页看到 Build with Parameters 选项了。
[图片上传失败...(image-b36150-1676282831388)]
在打包脚本中,使用 $configuration 就可以获取到选中的打包配置了。
附加参数
在自动打包应用中,根据反馈,希望知道是谁启动的打包任务,使用哪台打包机器打的包。基于此,需要额外的附加参数。
- shell 脚本中使用
${USER}
可以获取到当前电脑登录的用户名。 - shell 脚本中使用
$BUILD_USER
可以获取到 build user vars plugin 插件提供的环境变量,代表登录 jenkins 的用户名。安装 build user vars plugin 插件的方法,不再赘述。
build user vars plugin
启动电脑自动启动 Jenkins 服务
启动电脑自动启动 Jenkins 服务可参考文章:Mac开机自动运行shell脚本
git fetch --tags 超时
打包时偶尔遇到打包失败的情况,查看打包日志输出发现是 git fetch --tags 命令超时,原因是网速差的情况下请求超时导致的。解决此问题,可参考文章:Jenkins ERROR: Timeout after 10 minutes
git fetch --tags 超时
完整打包脚本
经过上面的配置后,打包脚本也要随之修改。
打包脚本
脚本如下:
export LANG=en_US.UTF-8
export LANGUAGE=en_US.UTF-8
export LC_ALL=en_US.UTF-8
cd ~/projectName
git fetch
lastName="${GIT_BRANCH##*/}"
currentBranch="$(git rev-parse --abbrev-ref HEAD)"
macUser="${USER}"
configuration="${configuration}"
echo "currentBranch=$currentBranch, lastName=$lastName, macUser=$macUser, configuration=$configuration"
if [ "$currentBranch" != "$lastName" ]; then
time=$(date "+%Y-%m-%d %H:%M:%S")
git stash -u -m "$BRANCH_NAME $time"
git checkout $lastName
fi
git pull
pod install
# 更新插件。fir_cli 插件不及时更新的话,可能会导致无法上传应用文件。
# sudo 是以管理员身份执行命令,在<< EOF与EOF之间输入你的开机密码
sudo -S bundle exec fastlane update_plugins << EOF
EOF
# 安装 fir 插件。sudo 是以管理员身份执行命令,在<< EOF与EOF之间输入你的开机密码
sudo -S fastlane add_plugin fir_cli << EOF
EOF
if [ "$configuration" = "Debug" ]; then
echo "fastlane project_Debug: macUser=$macUser BUILD_USER = $BUILD_USER, BRANCH_NAME = $GIT_BRANCH, jobName = $JOB_NAME outputDirectory = /Users/username/debug/"
bundle exec fastlane project_Debug branchName:$GIT_BRANCH jobName:$JOB_NAME changeLog:"$SCM_CHANGELOG" buildUser:$BUILD_USER macUser:$macUser outputDirectory:"/Users/username/debug/"
else
echo "fastlane project_Release: macUser=$macUser BUILD_USER = $BUILD_USER, BRANCH_NAME = $GIT_BRANCH, jobName = $JOB_NAME outputDirectory = /Users/username/release/"
bundle exec fastlane project_Release branchName:$GIT_BRANCH jobName:$JOB_NAME changeLog:"$SCM_CHANGELOG" buildUser:$BUILD_USER macUser:$macUser outputDirectory:"/Users/username/release/"
fi
Fastlane 配置
脚本配置了参数后,在 fastlane 的配置文件 Fastfile 中接收参数,然后输出到钉钉消息中。
default_platform(:ios)
platform :ios do
desc "iOS 自动打包"
lane :project_Debug do |options|
scheme_name = "project"
output_directory = "./debug/"
custom_directory = options[:outputDirectory]
if !(custom_directory.nil? || custom_directory.empty?)
output_directory = custom_directory
end
puts "打包输出路径为 #{output_directory}"
#increment_build_number
#version = get_version_number(xcodeproj: "project.xcodeproj", target: "#{scheme_name}")
buildNumber = get_build_number
output_name = "#{scheme_name}_#{buildNumber}_#{Time.now.strftime('%Y%m%d%H%M%S')}.ipa"
gym(scheme: scheme_name,
workspace: "project.xcworkspace",
include_bitcode: false,
configuration: "Debug",
include_symbols: true,
export_method: "development",
output_directory: output_directory,
build_path: output_directory,
archive_path: output_directory,
output_name: output_name)
branchName = options[:branchName]
jobName = options[:jobName]
buildUser = options[:buildUser]
macUser = options[:macUser]
changeLog = options[:changeLog]
answer = fir_cli api_token:"xxxx", need_release_id: true
puts "上传后的结果:#{answer}"
download_url = "https://hey.scandown.com/#{answer[:short]}?release_id=#{answer[:release_id]}"
dingdingMsg = "打包结果通知:Jenkins 打包成功。Debug 开发包。\n打包者:#{buildUser}\n分支名:#{branchName}\n任务名:#{jobName}\n打包使用的是#{macUser}的电脑\n下载二维码链接:#{download_url} \n修改日志: \n#{changeLog} \n"
puts "打包结束时,输出文案:#{dingdingMsg}"
#fir_cli api_token:"xxxx", dingtalk_at_all: true, #dingtalk_access_token:"xxxx", #dingtalk_custom_message: dingdingMsg
# 构造消息格式
text = {
"at": {
"isAtAll": false
},
"text": {
"content": "#{dingdingMsg}"
},
"msgtype": "text"
}
puts "发送的钉钉消息:#{text}"
dingTalk_url = "https://oapi.dingtalk.com/robot/send?access_token=xxxx"
uri = URI.parse(dingTalk_url)
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri)
request.add_field('Content-Type', 'application/json')
request.body = text.to_json
response = https.request(request)
puts "------------------------------"
puts "Response #{response.code} #{response.message}: #{response.body}"
end
lane :project_Release do |options|
scheme_name = "project"
output_directory = "./release/"
custom_directory = options[:outputDirectory]
if !(custom_directory.nil? || custom_directory.empty?)
output_directory = custom_directory
end
puts "打包输出路径为 #{output_directory}"
#increment_build_number
#version = get_version_number(xcodeproj: "project.xcodeproj", target: "#{scheme_name}")
buildNumber = get_build_number
output_name = "#{scheme_name}_#{buildNumber}_#{Time.now.strftime('%Y%m%d%H%M%S')}.ipa"
gym(scheme: scheme_name,
workspace: "project.xcworkspace",
include_bitcode: false,
configuration: "Release",
include_symbols: true,
export_method: "development",
output_directory: output_directory,
build_path: output_directory,
archive_path: output_directory,
output_name: output_name)
branchName = options[:branchName]
jobName = options[:jobName]
buildUser = options[:buildUser]
macUser = options[:macUser]
changeLog = options[:changeLog]
answer = fir_cli api_token:"xxxxxx", need_release_id: true
puts "上传后的结果:#{answer}"
download_url = "https://hey.scandown.com/#{answer[:short]}?release_id=#{answer[:release_id]}"
dingdingMsg = "打包结果通知:Jenkins 打包成功。Release 线上包。\n打包者:#{buildUser}\n分支名:#{branchName}\n任务名:#{jobName}\n打包使用的是#{macUser}的电脑\n下载二维码链接:#{download_url} \n修改日志: \n#{changeLog} \n"
puts "打包结束时,输出文案:#{dingdingMsg}"
#fir_cli api_token:"xxxx", dingtalk_at_all: true, #dingtalk_access_token:"xxx", #dingtalk_custom_message: dingdingMsg
# 构造消息格式
text = {
"at": {
"isAtAll": false
},
"text": {
"content": "#{dingdingMsg}"
},
"msgtype": "text"
}
puts "发送的钉钉消息:#{text} "
dingTalk_url = "https://oapi.dingtalk.com/robot/send?access_token=xxxx"
uri = URI.parse(dingTalk_url)
https = Net::HTTP.new(uri.host, uri.port)
https.use_ssl = true
request = Net::HTTP::Post.new(uri.request_uri)
request.add_field('Content-Type', 'application/json')
request.body = text.to_json
response = https.request(request)
puts "------------------------------"
puts "Response #{response.code} #{response.message}: #{response.body}"
end
end