做为一个移动端程序员,每次 feature add 或者 bug fix 后常常要打包交付给 QA,之前传统的操做都是手动点击 Xcode -> Product -> Archive -> Organizer -> Distrubute App -> ipa 上传到第三方内测分发平台(蒲公英、fir)-> 手动填写更新日志 -> 发送安装连接到部门群(钉钉或者企业微信)
,看起来好像很机械和繁琐,又没啥技术含量是吧......ios
若是能把这部分工做给自动化了就行了,天天能够省一点时间出来发呆也挺好的。需求整理一下大概是这样:git
调研了一下,Mac OS 能够基于 launchctl 来配置定时任务。能够配置到不一样级别的 LaunchAgents 下,几种的区别以下:程序员
~/Library/LaunchAgents 由用户本身定义的任务项
/Library/LaunchAgents 由管理员为用户定义的任务项
/Library/LaunchDaemons 由管理员定义的守护进程任务项
/System/Library/LaunchAgents 由Mac OS X为用户定义的任务项
/System/Library/LaunchDaemons 由Mac OS X定义的守护进程任务项
复制代码
咱们配置在用户目录下就行,也就是这个目录 ~/Library/LaunchAgents,按照固定的格式新建一个 Plist 文件就行,能够看到已经有一些第三方的任务在这里了:github
个人配置文件是这样:shell
<plist version="1.0">
<dict>
<!-- Label惟一的标识 -->
<key>Label</key>
<string>com.autoArchiveTask.plist</string>
<key>Program</key>
<string>/Users/username/Desktop/code/Project/run.sh</string>
<!-- 指定要运行的脚本 -->
<key>ProgramArguments</key>
<array>
<string>/Users/username/Desktop/code/Project/run.sh</string>
</array>
<!-- 指定要运行的时间 -->
<key>StartCalendarInterval</key>
<array>
<dict>
<key>Minute</key>
<integer>00</integer>
<key>Hour</key>
<integer>11</integer>
</dict>
<dict>
<key>Minute</key>
<integer>00</integer>
<key>Hour</key>
<integer>16</integer>
</dict>
</array>
<!-- 标准输出文件 -->
<key>StandardOutPath</key>
<string>/Users/username/Desktop/code/Project/run.log</string>
<!-- 标准错误输出文件,错误日志 -->
<key>StandardErrorPath</key>
<string>/Users/username/Desktop/code/Project/run.error</string>
</dict>
</plist>
复制代码
相关字段的解释以下:macos
配置好了就能够加载了,加载后就生效了,相关的命令以下:json
# 加载任务, -w选项会将 plist 文件中无效的 key 覆盖掉,建议加上
launchctl load -w xxx.plist
# 删除任务
launchctl unload -w xxx.plist
# 查看任务列表, 使用 grep '任务部分名字' 过滤
launchctl list | grep 'xxx'
# 当即执行一次任务,可用来测试
launchctl start xxx.plist
复制代码
这个使用 fastlane 就行,很好很强大。相关的配置可参见官网,建议使用 brew 方式安装。配置安装文档就行,c#
因为我这个是多 target 工程,因此我这边的可能多一点配置,个人 Fastfile 文件配置以下:api
default_platform(:ios)
# 网络请求依赖
require 'net/http'
require 'uri'
require 'json'
platform :ios do
desc "发布app到 App Store 或者 Fir.im "
lane :customer_hoc do
# add actions here: https://docs.fastlane.tools/actions
sh "fastlane adhoc --env Customer"
end
desc "发布app到 App Store 或者 Fir.im "
lane :driver_hoc do
# add actions here: https://docs.fastlane.tools/actions
sh "fastlane adhoc --env Driver"
end
desc "发布指定Target到 Fir.im"
lane :adhoc do
gym(
clean:true, #打包前clean项目
workspace: "Hedgehog.xcworkspace",
export_method: "ad-hoc", #导出方式
scheme: ENV['SCHEME_NAME'], #scheme
output_name: ENV['SCHEME_NAME']+".ipa", # ipa 文件名
output_directory: "./ipa", #ipa的存放目录
export_options: {
provisioningProfiles: {
"cn.ccmore.hedgehog.customer"=>"CustomerAdhoc",
"cn.ccmore.hedgehog.driver"=>"DricerAdhoc"
}
}
)
# 前往fir.im获取 api token, 将鼠标放置右上角帐号上面, 在下拉窗选择API token
# 若使用的蒲公英, 请前往 https://www.pgyer.com/ 查看上传方法
# 若是使用Firimfile, 此处为 firim 便可
firim(firim_api_token:'xxxx')
# 钉钉机器人
app_patch = "ipa/" + ENV['SCHEME_NAME']+".ipa"
app_version = get_ipa_info_plist_value(ipa: app_patch, key: "CFBundleShortVersionString")
app_build_version = get_ipa_info_plist_value(ipa: app_patch, key: "CFBundleVersion")
app_name = get_ipa_info_plist_value(ipa: app_patch, key: "CFBundleDisplayName")
# 根据 SCHEME_NAME 区分下载连接
app_url = "https://fir.im/6udv"
if ENV['SCHEME_NAME'] == "Driver" then
app_url = "https://fir.im/sa4q"
end
app_icon = "./Hedgehog/ipa/icons/57.png"
dingTalk_url = "https://oapi.dingtalk.com/robot/send?access_token=xxx"
markdown =
{
msgtype: "link",
link: {
text: "iOS #{ENV['SCHEME_NAME']} 更新了!!!",
title: "iOS #{ENV['SCHEME_NAME']} #{app_version} (#{app_build_version}) 内测版",
picUrl: "#{app_icon}",
messageUrl: "#{app_url}"
}
}
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 = markdown.to_json
response = https.request(request)
puts "------------------------------"
puts "Response #{response.code} #{response.message}: #{response.body}"
end
end
复制代码
上传到第三方内测平台(蒲公英、fir等)Fastlane 也有相关的插件,一行代码搞定,如 Fir 就是:安全
# 前往fir.im获取 api token, 将鼠标放置右上角帐号上面, 在下拉窗选择API token
# 若使用的蒲公英, 请前往 https://www.pgyer.com/ 查看上传方法
# 若是使用Firimfile, 此处为 firim 便可
firim(firim_api_token:'xxxx')
复制代码
TODO: 等待实现。
我这边目前使用的钉钉进行协做,能够在相关工做群使用钉钉机器人自动发送消息。找钉钉群管理员添加一下获取 token 就行。能够向这个地址 https://oapi.dingtalk.com/robot/send?access_token=Your Token
发送纯文本、图文、markdown 等格式的消息,还能够填写须要 @ 的测试妹子们。
其余企业微信好像也是能够的,能够自行去查看文档。
首先我配置的定时脚本路径在 /Users/username/Desktop/code/Project/run.sh,没有和定时任务的 Plist 配置文件在一个目录下,而配置的定时脚本声明的是 #!/bin/sh,意思是使用 /bin/sh 来解释执行,可是却没有给彻底磁盘访问的权限。
给足访问权限就行。系统偏好设置 -> 安全性与隐私-> 彻底磁盘访问权限,查看是否有勾选☑️ 在定时脚本中声明的解释执行的 shell 的路径,就是**#!/bin/** 后面接的,有 bash 、sh、 zsh 等,个人是 sh。没有的话就添加进去。
虽然 cd 到了当前项目目录,但仍是报 fastlane 找不到
使用全路径 fastlane 执行命令
/Users/username/.fastlane/bin/fastlane lane
复制代码
总共折腾了一两天时间,流程基本都跑通了,还剩抓取指定时间段内的 git commit message 当作更新日志的 TODO,整体上仍是很愉悦和有成就感的,之后就能够专心干其余的事情了,打包几乎无感,也不用怕忘记。nice!
效果以下:
相关配置文件已经上传到 GitHub 仓库,地址点击这里。
分享我的技术学习记录和跑步马拉松训练比赛、读书笔记等内容,感兴趣的朋友能够关注个人公众号「by在水一方」。