背景:我们移动端一直使用CI+蒲公英+钉钉消息提醒。 目前iOS端用的是fastlane,比较方便。 但是最近却出现了打包提测钉钉群没有及时提醒,导致测试老师苦苦等待,开发人员还要背锅被说效率低。于是我就打算看看怎么个事。一看原来发现前面都很顺畅,最后两步上传蒲公英和钉提醒出现了问题。原来是蒲公英不打算维护他们1.0的开放接口了。
蒲公英开放接口2.0传送门 打开之后发现实现步骤比之前略微繁琐了,但是返回的内容更加实用了,于是秉承着能不动手就直接copy的原则打开了他们的示例工程,在这里,打开之后,直接好家伙,真全。涵盖脚本:C#、java、nodejs、php、python、shell,可是我用的是ruby啊,🤔。
纠结一番之后,还是用ruby吧,其实shell也可以用,毕竟习惯了,毕竟现在AI这么厉害,直接翻译,我把官方实现的python源码做了修改,具体如下:
require 'net/http'
require 'uri'
require 'json'
require 'rest-client'
#定义一个通用模块,来实现蒲公英的上传流程
module PgyerUtil
#定义函数来获取上传ipa所需要的token
def self.get_cosp_token(api_key, install_type, password = '', update_description = '')
url = URI.parse('https://www.pgyer.com/apiv2/app/getCOSToken')
headers = { 'enctype' => 'multipart/form-data' }
payload = {
'_api_key' => api_key,
'buildType' => 'ios',
'buildInstallType' => install_type,
'buildPassword' => password,
'buildUpdateDescription' => update_description
}
begin
response = Net::HTTP.post_form(url, payload)
if response.code == '200'
#puts JSON.parse(response.body)
return JSON.parse(response.body)
else
raise "HTTP Error: #{response.code}"
end
rescue StandardError => e
puts "请求失败: #{e.message}"
return nil
end
end
#定义函数来实现上传操作(外部调用)
def self.upload_to_pgyer(path:, api_key:, install_type:, password: '', update_description: '', callback: nil)
#先获取token等信息
token_result = get_cosp_token(api_key, install_type, password, update_description)
if token_result && token_result['code'] == 0
puts token_result['data']['endpoint']
upload_url = token_result['data']['endpoint']
file = File.open(path, 'rb')
payload = token_result['data']['params']
puts "上传中..."
uri = URI.parse(upload_url)
http = Net::HTTP.new(uri.host, uri.port)
http.use_ssl = true
request = Net::HTTP::Post.new(uri, initheader = { 'enctype' => 'multipart/form-data' })
form_data = payload.merge({ 'file' => UploadIO.new(file, 'application/octet-stream', File.basename(path)) })
request.set_form(form_data, 'multipart/form-data')
begin
response = http.request(request)
if response.code == '204'
puts "上传成功,正在获取包处理信息,请稍等..."
get_build_info(api_key, token_result, &callback)
else
puts "HTTP Error, Code: #{response.code}"
callback.call(false, nil) if callback
end
rescue StandardError => e
puts e
puts '服务器暂时无法为您服务'
ensure
file.close
end
else
puts '获取上传Token失败'
callback.call(false, nil) if callback
end
end
# 定义函数获取上传成功后的应用信息,用于发送通知给需要的人员,这个函数有点奇怪
# 就是延迟请求多次,请求次数和延迟时间都可调整,官方说上传成功了,请求应用信息可能会不成功,让多试几次
def self.get_build_info(api_key, json, &callback)
max_retries = 5 #设置最多请求次数
retries = 0
url = URI.parse('https://www.pgyer.com/apiv2/app/buildInfo')
query = {
'_api_key' => api_key,
'buildKey' => json['data']['key'],
}
begin
loop do
# 使用 URI.encode_www_form 将哈希转换为查询字符串
query_string = URI.encode_www_form(query)
# 将查询字符串附加到 URL 上
full_url = "#{url}?#{query_string}"
response = Net::HTTP.get_response(URI(full_url))
if response.code == '200'
result = JSON.parse(response.body)
puts result
if [1247, 1246].include?(result['code']) && retries < max_retries
sleep 5 #如果应用信息没有返回,就等5s再请求1次
retries += 1
next
else
callback.call(true, result) if callback
break
end
else
puts "HTTP Error, Code: #{response.code}"
callback.call(false, nil) if callback
break
end
end
rescue StandardError => e
puts "获取包处理信息失败: #{e.message}"
callback.call(false, nil) if callback
end
end
end
通过以上蒲公英API的更新升级,可以看到他们内部应该是按照微服务的原理更细分了服务接口,不同的服务做不同的事情,很棒,但是怎么隐约感觉后面要开始收费了啊,先不管了,白嫖一天是一天吧。具体调用如下,可做参考: 我是分了多个rb文件实现的,写一个里面也行。
require_relative 'pgyer_util.rb'
#path就是你打包好的包路径,注意需要绝对路径
#api_key是你登录蒲公英账号后在个人信息地方可以获取到
#install_type:1表示公共安装,不需要密码
#password:安装密码
#update_description:更新描述
#callback:上传蒲公英成功后,并且获取应用信息成功的回调,
#可以在这里面发送钉钉通知,钉钉通知如何发送,可以参考钉钉开放api接口,和画1一样简单,就不赘述了
PgyerUtil.upload_to_pgyer(path:File.expand_path("#{p_ipa_dir}/#{ipaName}"),api_key:"#{api_key}",install_type:1,password:'',update_description:'',callback:method(:upload_complete_callback))
还有就是AI翻译后的代码运行是有问题的,上面是我调整后的,可以直接使用的,但是确实节省了很多时间。