fastlane自动化打包(android)
目录
一、前言
一、环境搭建
二、初始化项目
三、打包apk
四、发布到蒲公英
五、钉钉通知相关人员
一、前言
项目中经常会进行打包分发, 但是常规的打包过程不免会非常的乏味无聊, 重复性的劳动, 实在没啥意思, 今天就来介绍fastlane工具进行android自动打包, 上传蒲公英(也可以firim)并进行钉钉群组通知相关人员。
Fastlane是一整套的客户端CICD工具集合。Fastlane可以非常快速简单的搭建一个自动化发布服务,并且支持Android,iOS,MacOS。
Fastlane命令执行的底层并不是自己实现的,而是调用其他的插件或者工具执行的。比如说打包,Fastlane中的gym工具只是xcodebuild工具的一个封装,调用的其实还是xcodebuild中的打包命令。
Fastlane本身没有一套特殊语法,使用的Ruby语言。
Fastlane的插件工具叫做action,每一个action都对应一个具体的功能。
一、 环境搭建
1、苹果系统自带有ruby
ruby -v
2、安装今天的主角fastlane
sudo gem install fastlane -NV
安装权限.jpg
通过修改用户读写权限可以解决
sudo chmod -R 777 /usr/bin/
或者
sudo gem install -n /usr/local/bin fastlane
3、安装蒲公英的 Fastlane 插件
fastlane add_plugin pgyer
如果遇到这种情况:Could not find action, lane or variable 'pgyer'.
pgyer.jpg
可能是你安装pgyer插件的时候,不是在项目fastlane文件夹下安装的,重新安装一下就可以解决上面的错误。
4、安装获取应用版本的 Fastlane 插件
fastlane add_plugin android_versioning
如果出现类似pgyer的错误,同理在项目fastlane文件夹下重新安装就可以避免找不到插件的命令错误。
二、初始化项目
在使用 Fastlane 之前,我们首先需要在项目中初始化 Fastlane。首先进入 App 的开发目录,执行以下命令来初始化 Fastlane:
fastlane init
三、打包apk
激动人心的时刻终于来了,开始打包。
gradle(
task: 'assemble',
build_type: 'Release',
properties: {
"android.injected.signing.store.file" => Dir.pwd + "/street.keystore",
"android.injected.signing.store.password" => "123456",
"android.injected.signing.key.alias" => "street",
"android.injected.signing.key.password" => "123456",
},
);
四、发布到蒲公英
pgyer(api_key: pgy_api_key, user_key: pgy_user_key)
五、钉钉通知相关人员
markdown = {
msgtype: "markdown",
markdown: {
title: "#{app_name}Android内测更新",
text: ding_talk_update_text,
# picUrl: "#{app_icon}",
# messageUrl: "#{app_url}"
},
at: {
atMobiles: ["18*****38","13*****77","18*****93"],
isAtAll: false
}
}
ding_talk_url = "https://oapi.dingtalk.com/robot/send?access_token="
ding_talk_secret = ""
timestamp = DateTime.now.strftime('%Q') # "1384526946523" (milliseconds)
finaly_sign = ''
if ding_talk_secret
data = timestamp + "\n" + ding_talk_secret
digest = OpenSSL::Digest.new('SHA256')
sign_data = OpenSSL::HMAC.digest(digest, ding_talk_secret.force_encoding("UTF-8"), data.force_encoding("UTF-8"))
finaly_sign = Base64.encode64(sign_data).gsub("\n",'')
finaly_sign = CGI::escape(finaly_sign)
end
ding_talk_url = ding_talk_url + "×tamp=#{timestamp}&sign=#{finaly_sign}"
puts ding_talk_url
uri = URI.parse(ding_talk_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
puts request.body
response = https.request(request)
lane :toPgy do
puts("开始打包Android APK!");
gradle(
task: 'assemble',
build_type: 'Release',
properties: {
"android.injected.signing.store.file" => Dir.pwd + "/street.keystore",
"android.injected.signing.store.password" => "skyinfor2016",
"android.injected.signing.key.alias" => "ZhongshanStreet",
"android.injected.signing.key.password" => "skyinfor2016",
},
);
puts("------打包后App信息:------")
#上传到蒲公英
pgyer(api_key: "bfb444cc09c3be7695c845b32ec89d3a", user_key: "fb6d0c133cebfe401fc5ad8153612520")
#更新日志
update_log="更新后台定位"
# 获取Apk默认输出路径
apk_file_path = lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH];
# 重新命名Fastlane默认Apk文件,并移动到/fastlane/packages目录下
fastlane_directory = Dir.pwd
app_name="数字孪生"
# 获取版本号
app_version = get_version_code(app_project_dir: './app');
formatted_file_size="未知"
time_now=Time.now.strftime(“%Y-%m-%d %H:%M:%S”)
pgy_qrcode="https://www.pgyer.com/app/qrcode/9pHS"
pgy_app_url="https://www.pgyer.com/9pHS"
contacts_format="@13024266977"
app_icon="https://www.pgyer.com/app/qrcode/9pHS"
app_url=""
ding_talk_update_text = <<-EOF
#### #{app_name}Android-应用更新
> 版本信息:#{app_version}\n
> 应用大小:#{formatted_file_size} \n
> 更新时间:#{time_now}\n
> 关键词:天覆发版专用\n
> 更新内容:#{update_log}\n
扫描二维码下载:
![二维码](#{pgy_qrcode})\n
[点我进入主页下载](#{pgy_app_url}) #{contacts_format}
EOF
markdown = {
msgtype: "markdown",
markdown: {
title: "#{app_name}Android内测更新",
text: ding_talk_update_text,
# picUrl: "#{app_icon}",
# messageUrl: "#{app_url}"
},
at: {
atMobiles: ["18516666838","13024266977","18225819193"],
isAtAll: false
}
}
ding_talk_url = "https://oapi.dingtalk.com/robot/send?access_token=13b87d0200ce93b51d9d7c04075be8b31c5c17ae342e67cf5a76b2dc06490a63"
ding_talk_secret = "SECbb33329836b0421b8e6271b2a34f913575d7e41f9076ae9b636418e2a5c206c9"
timestamp = DateTime.now.strftime('%Q') # "1384526946523" (milliseconds)
finaly_sign = ''
if ding_talk_secret
data = timestamp + "\n" + ding_talk_secret
digest = OpenSSL::Digest.new('SHA256')
sign_data = OpenSSL::HMAC.digest(digest, ding_talk_secret.force_encoding("UTF-8"), data.force_encoding("UTF-8"))
finaly_sign = Base64.encode64(sign_data).gsub("\n",'')
finaly_sign = CGI::escape(finaly_sign)
end
ding_talk_url = ding_talk_url + "×tamp=#{timestamp}&sign=#{finaly_sign}"
puts ding_talk_url
uri = URI.parse(ding_talk_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
puts request.body
response = https.request(request)
puts "------------------------------"
puts "Response #{response.code} #{response.message}: #{response.body}"
end