fir-cli 1.7.4.1 → 2.0.0.beta

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 5f723191be804ce033110a2bc4a06ce2b414faf41946ee6ce9381387dd17a5f2
4
- data.tar.gz: ce3e48b02cd7aaebe5177d7779f2f246d2be3bc81b8722becd45280072eba325
3
+ metadata.gz: 673a534b58afadd5a2b7491884a074dd2db722b636929ac3a43c5de1778e981d
4
+ data.tar.gz: fcf5a3e79f1bfaf937d6ae13bfed6f40c3f405e59344c797c1fe7a43f8489ddd
5
5
  SHA512:
6
- metadata.gz: a20bf8b51310992a44ab78bc636bd3d7e88291857aa2098e57b59b0e59ceab0d68d6e7fe7569bc19db7e2d0a55c9d5bbf9630ee8820f65bdec8526ec3e7b8cb1
7
- data.tar.gz: ffab9cc8875d30a33015627411013709e14d87a98ae03a34cd6471715e6220ec253bd84394961a4d4c849eee1a50ba1dd1e331cad393e70ef902ce96e9932987
6
+ metadata.gz: 3d62c7e16583cf776c29bbbaec8dfae9104b01534cbf52882545bebf688fda89a51dd928cbd31ae7ccab6ac833fffd1650c13f9c2639f526396c1bdd4ec60a99
7
+ data.tar.gz: 31d38f670026014742b1a4c1cf87b5f1e33d13bb294266d327dc517a655a395a84629f226285432899c0755882e3304a2ab199b21994f227b348fa54f7d20b53
data/.travis.yml CHANGED
@@ -1,7 +1,5 @@
1
1
  rvm:
2
2
  - 2.4
3
- - 2.5
4
- - 2.6
5
3
  env:
6
4
  matrix:
7
5
  - USE_OFFICIAL_GEM_SOURCE=true
data/README.md CHANGED
@@ -14,6 +14,7 @@ fir.im-cli 可以通过指令查看, 上传, iOS/Android 应用.
14
14
 
15
15
 
16
16
  # 最近更新
17
+ - (2.0.0) publish 使用更快的存储商, 加速上传速度, 若感觉没以前可使用 switch_to_qiniu 恢复
17
18
  - 支持了在fastlane 直接调用, 具体请参见 [https://github.com/FIRHQ/fastlane-plugin-fir_cli](https://github.com/FIRHQ/fastlane-plugin-fir_cli)
18
19
  - publish 支持 新参数 force_pin_history, 可以 将上传的版本, 固定在下载页面上(当大于最大固定版本数后, 会挤掉最老的固定版本) [2019年11月18日]
19
20
  - publish 支持 新参数 specify_icon_file_path, 可以直接指定 app 的 icon 图标文件 [2019年11月18日]
@@ -78,7 +79,7 @@ docker run firhq/fir-cli:latest -e API_TOKEN=XXXX -v ./1.apk:1.apk publish 1.apk
78
79
 
79
80
  ## 提交反馈
80
81
 
81
- - 联系微信 `atpking`
82
+ - 联系微信 `atpking`, 请注明 "fir-cli 交流"
82
83
 
83
84
  - 使用 Github 的 [Issue](https://github.com/FIRHQ/fir-cli/issues)
84
85
 
@@ -86,3 +87,9 @@ docker run firhq/fir-cli:latest -e API_TOKEN=XXXX -v ./1.apk:1.apk publish 1.apk
86
87
 
87
88
  - 感谢 sparkrico 提供修正的 https://github.com/sparkrico/ruby_apk 解决了 android 解析的问题
88
89
 
90
+
91
+ ## 鼓励维护
92
+
93
+ 感谢支持
94
+
95
+ ![luckin](luckin_coffee.png)
data/fir-cli.gemspec CHANGED
@@ -27,6 +27,7 @@ Gem::Specification.new do |spec|
27
27
  /_/ /___/_/ |_| \____/_____/___/
28
28
 
29
29
  ## 更新记录
30
+ - (2.0.0) publish 使用更快的存储商, 加速上传速度, 若感觉没以前可使用 switch_to_qiniu 恢复
30
31
  - (1.7.4) 配合 fastlane-plugin-fir_cli 做了一些小优化
31
32
  - (1.7.3) 新增了 上传指定图标, 不上传图标 以及 将版本固定显示在下载页上
32
33
  - (1.7.2) 修正了无论是否加参数都固定出现二维码图片的bug
@@ -44,7 +45,7 @@ Gem::Specification.new do |spec|
44
45
  # spec.add_development_dependency 'byebug'
45
46
  spec.add_development_dependency 'minitest', '~> 5.7'
46
47
  spec.add_development_dependency 'pry', '~> 0.10'
47
-
48
+
48
49
  spec.add_dependency 'thor', '~> 0.19'
49
50
  spec.add_dependency 'rest-client', '~> 2.0'
50
51
  spec.add_dependency 'ruby_android_apk', '~> 0.7.7.1'
data/lib/fir/cli.rb CHANGED
@@ -107,12 +107,14 @@ module FIR
107
107
  method_option :short, type: :string, aliases: '-s', desc: 'Set custom short link'
108
108
  method_option :changelog, type: :string, aliases: '-c', desc: 'Set changelog'
109
109
  method_option :qrcode, type: :boolean, aliases: '-Q', desc: 'Generate qrcode'
110
- method_option :need_release_id, type: :boolean, aliases: '-R', desc: 'Add release id with fir url (WARNING: FIR ONLY SAVED 30 releases recently per app'
110
+ method_option :need_release_id, type: :boolean, aliases: '-R', default: false, desc: 'Add release id with fir url (WARNING: FIR ONLY SAVED 30 releases recently per app'
111
111
 
112
- method_option :force_pin_history, type: :boolean, aliases: '-H', default: false, desc: 'pin this release to the download page by force'
113
- method_option :skip_update_icon, type: :boolean, aliases: '-S', default: false, desc: 'skip update app icon'
112
+ method_option :force_pin_history, type: :boolean, aliases: '-H', default: false, desc: 'pin this release to the download page by force'
113
+ method_option :skip_update_icon, type: :boolean, aliases: '-S', default: false, desc: 'skip update app icon'
114
114
  method_option :specify_icon_file, type: :string, desc: 'specify icon file'
115
115
 
116
+ method_option :switch_to_qiniu, type: :boolean, default: false, aliases: '-N', desc: 'if app upload slowly, u can switch this option'
117
+
116
118
  method_option :mappingfile, type: :string, aliases: '-m', desc: 'App mapping file'
117
119
  method_option :dingtalk_access_token, type: :string, aliases: '-D', desc: 'Send msg to dingtalk, only need access_token, not whole url'
118
120
 
@@ -0,0 +1,78 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './app_uploader'
4
+ # require 'byebug'
5
+
6
+ module FIR
7
+ class AliUploader < AppUploader
8
+ def upload_icon
9
+ if skip_update_icon?
10
+ logger.info 'skip update icon...'
11
+ return
12
+ end
13
+ try_to_action('upload icon') do
14
+ # 拿到 icon 的授权
15
+ icon_url = uploading_info[:cert][:icon][:upload_url]
16
+ icon_info = uploading_icon_info
17
+
18
+ logger.debug "icon_url = #{icon_url}, icon_info = #{icon_info}"
19
+
20
+ put_file(icon_url, uploading_icon_info, uploading_info[:cert][:icon][:custom_headers])
21
+
22
+ callback_to_api(callback_url, callback_icon_information)
23
+ end
24
+ rescue StandardError => e
25
+ # ignore icon error
26
+ logger.info "ignore icon upload error #{e.message}"
27
+ end
28
+
29
+ def upload_binary
30
+ try_to_action 'upload binary ...' do
31
+ binary_url = uploading_info[:cert][:binary][:upload_url]
32
+ binary_info = uploading_binary_info
33
+
34
+ logger.debug "binary_url = #{binary_url}, binary_info = #{binary_info}"
35
+ headers = uploading_info[:cert][:binary][:custom_headers]
36
+ headers_copy = {
37
+ 'CONTENT-DISPOSITION' => headers[:"CONTENT-DISPOSITION"],
38
+ 'Content-Type' => headers[:"content-type"],
39
+ 'date' => headers[:date],
40
+ 'x-oss-date' => headers[:"x-oss-date"],
41
+ 'authorization' => headers[:authorization]
42
+ }
43
+
44
+ logger.debug headers_copy
45
+ put_file(binary_url, binary_info, headers_copy)
46
+
47
+ callback_to_api(callback_url, callback_binary_information)
48
+ end
49
+ rescue StandardError => e
50
+ logger.error "binary upload to ali fail, #{e.message}"
51
+ exit 1
52
+ end
53
+
54
+ protected
55
+
56
+ def put_file(url, file, headers)
57
+ RestClient::Request.execute(
58
+ method: 'PUT',
59
+ url: url,
60
+ payload: file,
61
+ headers: headers,
62
+ timeout: 300
63
+ )
64
+ end
65
+
66
+ def callback_url
67
+ "#{fir_api[:base_url]}/auth/ali/callback"
68
+ end
69
+
70
+ def uploading_icon_info
71
+ File.new(icon_file_path, 'rb')
72
+ end
73
+
74
+ def uploading_binary_info
75
+ File.new(file_path, 'rb')
76
+ end
77
+ end
78
+ end
@@ -0,0 +1,111 @@
1
+ module FIR
2
+ class AppUploader
3
+ include ApiTools::DefaultRestModule
4
+ include Config
5
+
6
+ attr_accessor :app_info, :user_info, :uploading_info, :options
7
+ def initialize(app_info, user_info, uploading_info, options)
8
+ @app_info = app_info
9
+ @user_info = user_info
10
+ @uploading_info = uploading_info
11
+ @options = options
12
+ end
13
+
14
+ def upload
15
+ upload_icon
16
+ binary_callback_info = upload_binary
17
+ # 将 binary 的callback信息返回
18
+ binary_callback_info
19
+ end
20
+
21
+ protected
22
+
23
+ def callback_to_api(callback_url, callback_binary_information)
24
+ return if callback_binary_information.blank?
25
+
26
+ post callback_url, callback_binary_information
27
+ end
28
+
29
+ def icon_file_path
30
+ if options[:specify_icon_file].blank?
31
+ app_info[:icons].max_by { |f| File.size(f) }
32
+ else
33
+ File.absolute_path(options[:specify_icon_file])
34
+ end
35
+ end
36
+
37
+ # 是否跳过 icon 上传
38
+ def skip_update_icon?
39
+ options[:skip_icon_upload].to_s == 'true'
40
+ end
41
+
42
+ def read_changelog
43
+ changelog = options[:changelog].to_s.to_utf8
44
+ return if changelog.blank?
45
+
46
+ File.exist?(changelog) ? File.read(changelog) : changelog
47
+ end
48
+
49
+ def icon_cert
50
+ uploading_info[:cert][:icon]
51
+ end
52
+
53
+ def binary_cert
54
+ uploading_info[:cert][:binary]
55
+ end
56
+
57
+ def file_path
58
+ app_info[:file_path]
59
+ end
60
+
61
+ def try_to_action(action, &block)
62
+ logger.debug "begin to #{action}"
63
+ answer = block.call
64
+ logger.debug "#{action} finished"
65
+ answer
66
+ rescue StandardError => e
67
+ logger.error "#{action} error ! #{e.message}"
68
+ raise e
69
+ end
70
+
71
+ def app_id
72
+ uploading_info[:id]
73
+ end
74
+
75
+ def callback_icon_information
76
+ return {} if icon_file_path.nil?
77
+ {
78
+ key: icon_cert[:key],
79
+ token: icon_cert[:token],
80
+ origin: 'fir-cli',
81
+ parent_id: app_id,
82
+ fsize: File.size(icon_file_path),
83
+ fname: 'blob'
84
+ }
85
+ end
86
+
87
+ def callback_binary_information
88
+ {
89
+ build: app_info[:build],
90
+ fname: File.basename(file_path),
91
+ key: binary_cert[:key],
92
+ name: app_info[:display_name] || app_info[:name],
93
+ origin: 'fir-cli',
94
+ parent_id: app_id,
95
+ release_tag: 'develop',
96
+ fsize: File.size(file_path),
97
+ release_type: app_info[:release_type],
98
+ distribution_name: app_info[:distribution_name],
99
+ token: binary_cert[:token],
100
+ version: app_info[:version],
101
+ changelog: read_changelog,
102
+ user_id: user_info[:id]
103
+ }.reject { |x| x.nil? || x == '' }
104
+ end
105
+
106
+ def logger
107
+ FIR.logger
108
+ end
109
+
110
+ end
111
+ end
data/lib/fir/util/info.rb CHANGED
@@ -26,12 +26,14 @@ module FIR
26
26
  app = ipa.app
27
27
  info = app.full_info(options)
28
28
  ipa.cleanup
29
+ info[:file_path] = ipa_path
29
30
  info
30
31
  end
31
32
 
32
33
  def apk_info(apk_path, options = {})
33
34
  apk = FIR::Parser::Apk.new(apk_path)
34
35
  info = apk.full_info(options)
36
+ info[:file_path] = apk_path
35
37
  info
36
38
  end
37
39
  end
@@ -1,146 +1,75 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # require 'byebug'
4
+ require_relative './qiniu_uploader'
5
+
6
+ require_relative './ali_uploader'
7
+
3
8
  module FIR
4
9
  module Publish
5
10
  def publish(*args, options)
6
11
  initialize_publish_options(args, options)
7
- @options = options
8
12
  check_supported_file_and_token
9
-
10
13
  logger_info_publishing_message
11
14
 
12
- @app_info = send("#{@file_type}_info", @file_path, full_info: true)
13
- @user_info = fetch_user_info(@token)
14
- @uploading_info = fetch_uploading_info
15
- @app_id = @uploading_info[:id]
15
+ logger.info 'begin to upload ...'
16
+ received_app_info = upload_app
16
17
 
17
- logger.info "begin to upload ..."
18
- upload_app
19
- logger.info "end upload "
18
+ short = received_app_info[:short]
19
+ release_id = received_app_info[:release_id]
20
+
21
+ logger.info 'end upload'
20
22
 
21
23
  logger_info_dividing_line
22
- logger_info_app_short_and_qrcode
23
24
 
24
- dingtalk_notifier
25
+ download_url = build_download_url(short, release_id)
26
+ logger.info "Published succeed: #{download_url}"
27
+
28
+ qrcode_path = build_qrcode download_url
29
+ dingtalk_notifier(download_url, qrcode_path)
25
30
  upload_mapping_file_with_publish
31
+
26
32
  logger_info_blank_line
27
- clean_files
33
+
28
34
  {
29
35
  app_id: @app_id,
30
- release_id: @release_id,
31
- short: @fir_app_info[:short]
36
+ release_id: release_id,
37
+ short: short
32
38
  }
33
39
  end
34
40
 
35
- def logger_info_publishing_message
36
- user_info = fetch_user_info(@token)
41
+ protected
37
42
 
38
- email = user_info.fetch(:email, '')
39
- name = user_info.fetch(:name, '')
43
+ def logger_info_publishing_message
44
+ email = @user_info.fetch(:email, '')
45
+ name = @user_info.fetch(:name, '')
40
46
 
41
47
  logger.info "Publishing app via #{name}<#{email}>......."
42
48
  logger_info_dividing_line
43
49
  end
44
50
 
45
51
  def upload_app
52
+
53
+ app_uploaded_callback_data = if @options[:switch_to_qiniu]
54
+ QiniuUploader.new(@app_info, @user_info, @uploading_info, @options).upload
55
+ else
56
+ AliUploader.new(@app_info, @user_info, @uploading_info, @options).upload
57
+ end
46
58
 
47
- @icon_cert = @uploading_info[:cert][:icon]
48
- @binary_cert = @uploading_info[:cert][:binary]
49
- logger.debug "in upload app begin to upload icon"
50
- upload_app_icon unless @skip_update_icon
51
- logger.debug "in upload icon finished"
52
-
53
- logger.debug "in upload app begin to upload binary"
54
- @app_uploaded_callback_data = upload_app_binary
55
- logger.debug "in upload binary"
56
- @release_id = @app_uploaded_callback_data[:release_id]
57
-
58
- force_pin_release if @force_pin_history
59
+ release_id = app_uploaded_callback_data[:release_id]
59
60
 
60
61
  logger.info "App id is #{@app_id}"
61
- logger.info "Release id is #{@app_uploaded_callback_data[:release_id]}"
62
+ logger.info "Release id is #{release_id}"
63
+
64
+ # 处理上传完毕后, 需要的后续操作
65
+ force_pin_release(release_id) if @force_pin_history
62
66
  upload_device_info
63
67
  update_app_info
64
- fetch_app_info
65
- end
66
68
 
67
- %w[binary icon].each do |word|
68
- define_method("upload_app_#{word}") do
69
- upload_file(word)
70
- storage = ENV['SOTRAGE_NAME'] || 'qiniu'
71
- information = send("#{word}_information")
72
- post("#{fir_api[:base_url]}/auth/#{storage}/callback", information) unless information.blank?
73
- end
74
- end
69
+ app_info_dict = fetch_app_info
70
+ app_info_dict[:release_id] = release_id
75
71
 
76
- def upload_file(postfix)
77
- logger.info "Uploading app #{postfix}......"
78
- url = @uploading_info[:cert][postfix.to_sym][:upload_url]
79
- info = send("uploading_#{postfix}_info")
80
- logger.debug "url = #{url}, info = #{info}"
81
- uploaded_info = post(url, info.merge(manual_callback: true),
82
- params_to_json: false,
83
- header: nil)
84
- rescue StandardError => e
85
- logger.error "Uploading app #{postfix} failed"
86
- exit 1 if postfix != 'icon'
87
- end
88
-
89
- def uploading_icon_info
90
- large_icon_path = @app_info[:icons].max_by { |f| File.size(f) }
91
- @uncrushed_icon_path = @specify_icon_file_path || convert_icon(large_icon_path)
92
- {
93
- key: @icon_cert[:key],
94
- token: @icon_cert[:token],
95
- file: File.new(@uncrushed_icon_path, 'rb'),
96
- 'x:is_converted' => '1'
97
- }
98
- end
99
-
100
- def icon_information
101
- return {} if @uncrushed_icon_path.nil?
102
- {
103
- key: @icon_cert[:key],
104
- token: @icon_cert[:token],
105
- origin: 'fir-cli',
106
- parent_id: @app_id,
107
- fsize: File.size(@uncrushed_icon_path),
108
- fname: 'blob'
109
- }
110
- end
111
-
112
- def binary_information
113
- {
114
- build: @app_info[:build],
115
- fname: File.basename(@file_path),
116
- key: @binary_cert[:key],
117
- name: @app_info[:display_name] || @app_info[:name],
118
- origin: 'fir-cli',
119
- parent_id: @app_id,
120
- release_tag: 'develop',
121
- fsize: File.size(@file_path),
122
- release_type: @app_info[:release_type],
123
- distribution_name: @app_info[:distribution_name],
124
- token: @binary_cert[:token],
125
- version: @app_info[:version],
126
- changelog: @changelog,
127
- user_id: @user_info[:id]
128
- }.reject { |x| x.nil? || x == '' }
129
- end
130
-
131
- def uploading_binary_info
132
- {
133
- key: @binary_cert[:key],
134
- token: @binary_cert[:token],
135
- file: File.new(@file_path, 'rb'),
136
- # Custom variables
137
- 'x:name' => @app_info[:display_name] || @app_info[:name],
138
- 'x:build' => @app_info[:build],
139
- 'x:version' => @app_info[:version],
140
- 'x:changelog' => @changelog,
141
- 'x:release_type' => @app_info[:release_type],
142
- 'x:distribution_name' => @app_info[:distribution_name]
143
- }
72
+ app_info_dict
144
73
  end
145
74
 
146
75
  def upload_device_info
@@ -151,7 +80,7 @@ module FIR
151
80
  post fir_api[:udids_url], key: @binary_cert[:key],
152
81
  udids: @app_info[:devices].join(','),
153
82
  api_token: @token
154
- end
83
+ end
155
84
 
156
85
  def update_app_info
157
86
  update_info = { short: @short, passwd: @passwd, is_opened: @is_opened }.compact
@@ -163,27 +92,33 @@ module FIR
163
92
  patch fir_api[:app_url] + "/#{@app_id}", update_info.merge(api_token: @token)
164
93
  end
165
94
 
95
+ # 获得 上传文件的授权信息
166
96
  def fetch_uploading_info
167
97
  logger.info "Fetching #{@app_info[:identifier]}@fir.im uploading info......"
168
98
  logger.info "Uploading app: #{@app_info[:name]}-#{@app_info[:version]}(Build #{@app_info[:build]})"
169
99
 
170
- post fir_api[:app_url], type: @app_info[:type],
171
- bundle_id: @app_info[:identifier],
172
- skip_icon_upload: @options[:skip_update_icon],
173
- manual_callback: true,
174
- api_token: @token
175
- end
176
-
177
- def fetch_release_id
178
- get "#{fir_api[:base_url]}/apps/#{@app_id}/releases/find_release_by_key", api_token: @token, key: @binary_cert[:key]
100
+ post fir_api[:app_url],
101
+ { type: @app_info[:type],
102
+ bundle_id: @app_info[:identifier],
103
+ fname: @file_path.split('/').last,
104
+ force_upload: options[:switch_to_qiniu] ? 'qiniu' : 'ali',
105
+ skip_icon_upload: @options[:skip_update_icon],
106
+ manual_callback: true,
107
+ protocol: 'https',
108
+ api_token: @token },
109
+ header: {
110
+ user_agent: 'new-cli'
111
+ }
179
112
  end
180
113
 
181
114
  def fetch_app_info
182
115
  logger.info 'Fetch app info from fir.im'
183
116
 
184
- @fir_app_info = get(fir_api[:app_url] + "/#{@app_id}", api_token: @token)
185
- write_app_info(id: @fir_app_info[:id], short: @fir_app_info[:short], name: @fir_app_info[:name])
186
- @fir_app_info
117
+ fir_app_info = get(fir_api[:app_url] + "/#{@app_id}", api_token: @token)
118
+ write_app_info(id: fir_app_info[:id],
119
+ short: fir_app_info[:short],
120
+ name: fir_app_info[:name])
121
+ fir_app_info
187
122
  end
188
123
 
189
124
  def upload_mapping_file_with_publish
@@ -197,62 +132,67 @@ module FIR
197
132
  token: @token
198
133
  end
199
134
 
200
- def logger_info_app_short_and_qrcode
201
- @download_url = "#{fir_api[:domain]}/#{@fir_app_info[:short]}"
202
- @download_url += "?release_id=#{@app_uploaded_callback_data[:release_id]}" if !!options[:need_release_id]
203
-
204
- logger.info "Published succeed: #{@download_url}"
205
-
206
- @qrcode_path = "#{File.dirname(@file_path)}/fir-#{@app_info[:name]}.png"
207
- FIR.generate_rqrcode(@download_url, @qrcode_path)
208
-
209
- logger.info "Local qrcode file: #{@qrcode_path}" if @export_qrcode
135
+ def build_qrcode(download_url)
136
+ qrcode_path = "#{File.dirname(@file_path)}/fir-#{@app_info[:name]}.png"
137
+ FIR.generate_rqrcode(download_url, qrcode_path)
138
+ # 为何在这里必须生成 QrCode ? 因为要在 dingtalk 调用
139
+ logger.info "Local qrcode file: #{qrcode_path}" if @export_qrcode
140
+ qrcode_path
210
141
  end
211
142
 
212
- private
143
+ def build_download_url(short, release_id)
144
+ url = "#{fir_api[:domain]}/#{short}"
145
+ url += "?release_id=#{release_id}" if options[:need_release_id]
146
+ url
147
+ end
213
148
 
214
149
  def options
215
150
  @options
216
151
  end
217
152
 
218
- def force_pin_release
219
- post "#{fir_api[:base_url]}/apps/#{@app_id}/releases/#{@release_id}/force_set_history",
153
+ def force_pin_release(release_id)
154
+ post "#{fir_api[:base_url]}/apps/#{@app_id}/releases/#{release_id}/force_set_history",
220
155
  api_token: @token
221
156
  end
222
157
 
223
- def clean_files
224
- File.delete(@qrcode_path) unless @export_qrcode
225
- end
158
+ def dingtalk_notifier(download_url, qrcode_path)
159
+ return if options[:dingtalk_access_token].blank?
226
160
 
227
- def dingtalk_notifier
228
- if options[:dingtalk_access_token]
229
- title = "#{@app_info[:name]}-#{@app_info[:version]}(Build #{@app_info[:build]})"
230
- payload = {
231
- "msgtype": 'markdown',
232
- "markdown": {
233
- "title": "#{title} uploaded",
234
- "text": "#{title} uploaded at #{Time.now}\nurl: #{@download_url}\n ![app二维码](data:image/png;base64,#{Base64.strict_encode64(File.read(open(@qrcode_path)))})"
235
- }
161
+ title = "#{@app_info[:name]}-#{@app_info[:version]}(Build #{@app_info[:build]})"
162
+ payload = {
163
+ "msgtype": 'markdown',
164
+ "markdown": {
165
+ "title": "#{title} uploaded",
166
+ "text": "#{title} uploaded at #{Time.now}\nurl: #{download_url}\n ![app二维码](data:image/png;base64,#{Base64.strict_encode64(File.read(open(qrcode_path)))})"
236
167
  }
237
- url = "https://oapi.dingtalk.com/robot/send?access_token=#{options[:dingtalk_access_token]}"
238
- DefaultRest.post(url, payload)
239
- end
168
+ }
169
+ url = "https://oapi.dingtalk.com/robot/send?access_token=#{options[:dingtalk_access_token]}"
170
+
171
+ # 用完了二维码, 就删了
172
+ File.delete(qrcode_path) unless @export_qrcode
173
+
174
+ DefaultRest.post(url, payload)
240
175
  rescue StandardError => e
241
176
  logger.warn "Dingtalk send error #{e.message}"
242
177
  end
243
178
 
244
179
  def initialize_publish_options(args, options)
245
- @file_path = File.absolute_path(args.first.to_s)
246
- @file_type = File.extname(@file_path).delete('.')
247
- @token = options[:token] || current_token
248
- @changelog = read_changelog(options[:changelog]).to_s.to_utf8
249
- @short = options[:short].to_s
250
- @passwd = options[:password].to_s
251
- @is_opened = @passwd.blank? ? options[:open] : false
180
+ @options = options
181
+ @file_path = File.absolute_path(args.first.to_s)
182
+ @file_type = File.extname(@file_path).delete('.')
183
+ @token = options[:token] || current_token
184
+ @changelog = read_changelog(options[:changelog]).to_s.to_utf8
185
+ @short = options[:short].to_s
186
+ @passwd = options[:password].to_s
187
+ @is_opened = @passwd.blank? ? options[:open] : false
252
188
  @export_qrcode = !!options[:qrcode]
189
+ @app_info = send("#{@file_type}_info", @file_path, full_info: true)
190
+ @user_info = fetch_user_info(@token)
191
+ @uploading_info = fetch_uploading_info # 获得上传信息
192
+ @app_id = @uploading_info[:id]
253
193
 
254
- @force_pin_history = options[:force_pin_history]
255
194
  @skip_update_icon = options[:skip_update_icon]
195
+ @force_pin_history = options[:force_pin_history]
256
196
  @specify_icon_file_path = File.absolute_path(options[:specify_icon_file]) unless options[:specify_icon_file].blank?
257
197
  end
258
198
 
@@ -268,20 +208,5 @@ module FIR
268
208
  check_token_cannot_be_blank(@token)
269
209
  fetch_user_info(@token)
270
210
  end
271
-
272
- def convert_icon(origin_path)
273
- # 兼容性不太好, 蔽掉转化图标
274
- return origin_path
275
-
276
- logger.info "Converting app's icon......"
277
-
278
- if @app_info[:type] == 'ios'
279
- output_path = Tempfile.new(['uncrushed_icon', '.png']).path
280
- FIR::Parser::Pngcrush.uncrush_icon(origin_path, output_path)
281
- origin_path = output_path if File.size(output_path) != 0
282
- end
283
-
284
- origin_path
285
- end
286
211
  end
287
212
  end
@@ -0,0 +1,34 @@
1
+ # frozen_string_literal: true
2
+
3
+ module FIR
4
+ module Util
5
+ class Publisher
6
+ include FIR::Util
7
+
8
+ attr_accessor :args, :options
9
+
10
+ def initialize(args, options)
11
+ @file_path = File.absolute_path(args.first.to_s)
12
+ @file_type = File.extname(@file_path).delete('.')
13
+ @token = options[:token] || current_token
14
+ @changelog = read_changelog(options[:changelog]).to_s.to_utf8
15
+ @short = options[:short].to_s
16
+ @passwd = options[:password].to_s
17
+ @is_opened = @passwd.blank? ? options[:open] : false
18
+ @export_qrcode = !!options[:qrcode]
19
+ end
20
+
21
+ private
22
+
23
+ def file_path
24
+ @file_path = File.absolute_path(args.first.to_s)
25
+ end
26
+
27
+ def read_changelog(changelog)
28
+ return if changelog.blank?
29
+
30
+ File.exist?(changelog) ? File.read(changelog) : changelog
31
+ end
32
+ end
33
+ end
34
+ end
@@ -0,0 +1,73 @@
1
+ # frozen_string_literal: true
2
+
3
+ require_relative './app_uploader'
4
+ # require 'byebug'
5
+
6
+ module FIR
7
+ class QiniuUploader < AppUploader
8
+ def upload_icon
9
+ if skip_update_icon?
10
+ logger.info 'skip update icon...'
11
+ return
12
+ end
13
+ try_to_action('upload icon') do
14
+ # 拿到 icon 的授权
15
+ icon_url = uploading_info[:cert][:icon][:upload_url]
16
+ icon_info = uploading_icon_info
17
+
18
+ logger.debug "icon_url = #{icon_url}, icon_info = #{icon_info}"
19
+
20
+ _uploaded_info = post(icon_url, icon_info.merge(manual_callback: true),
21
+ params_to_json: false,
22
+ header: nil)
23
+
24
+ callback_to_api(callback_url, callback_icon_information)
25
+ end
26
+ rescue StandardError => e
27
+ # ignore icon error
28
+ logger.info "ignore icon upload error #{e.message}"
29
+ end
30
+
31
+ def upload_binary
32
+ try_to_action 'upload binary ...' do
33
+ binary_url = uploading_info[:cert][:binary][:upload_url]
34
+ binary_info = uploading_binary_info
35
+
36
+ _uploaded_info = post(binary_url, binary_info.merge(manual_callback: true),
37
+ params_to_json: false,
38
+ header: nil)
39
+
40
+ callback_to_api(callback_url, callback_binary_information)
41
+ end
42
+ rescue StandardError => e
43
+ logger.error "binary upload to qiniu fail, #{e.message}"
44
+ exit 1
45
+ end
46
+
47
+ protected
48
+
49
+ def callback_url
50
+ "#{fir_api[:base_url]}/auth/qiniu/callback"
51
+ end
52
+
53
+ # 七牛需要的 icon params
54
+ def uploading_icon_info
55
+ icon_cert = uploading_info[:cert][:icon]
56
+ {
57
+ key: icon_cert[:key],
58
+ token: icon_cert[:token],
59
+ file: File.new(icon_file_path, 'rb')
60
+ }
61
+ end
62
+
63
+ # 七牛需要的 binary params
64
+ def uploading_binary_info
65
+ binary_cert = uploading_info[:cert][:binary]
66
+ {
67
+ key: binary_cert[:key],
68
+ token: binary_cert[:token],
69
+ file: File.new(file_path, 'rb')
70
+ }
71
+ end
72
+ end
73
+ end
data/lib/fir/version.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # encoding: utf-8
2
2
 
3
3
  module FIR
4
- VERSION = '1.7.4.1'
4
+ VERSION = '2.0.0.beta'
5
5
  end
data/luckin_coffee.png ADDED
Binary file
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fir-cli
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.7.4.1
4
+ version: 2.0.0.beta
5
5
  platform: ruby
6
6
  authors:
7
7
  - NaixSpirit
@@ -9,7 +9,7 @@ authors:
9
9
  autorequire:
10
10
  bindir: bin
11
11
  cert_chain: []
12
- date: 2019-11-20 00:00:00.000000000 Z
12
+ date: 2019-11-21 00:00:00.000000000 Z
13
13
  dependencies:
14
14
  - !ruby/object:Gem::Dependency
15
15
  name: bundler
@@ -198,6 +198,8 @@ files:
198
198
  - lib/fir/patches/os_patch.rb
199
199
  - lib/fir/patches/try.rb
200
200
  - lib/fir/util.rb
201
+ - lib/fir/util/ali_uploader.rb
202
+ - lib/fir/util/app_uploader.rb
201
203
  - lib/fir/util/build_apk.rb
202
204
  - lib/fir/util/build_common.rb
203
205
  - lib/fir/util/build_ipa.rb
@@ -213,9 +215,12 @@ files:
213
215
  - lib/fir/util/parser/ipa.rb
214
216
  - lib/fir/util/parser/pngcrush.rb
215
217
  - lib/fir/util/publish.rb
218
+ - lib/fir/util/publisher.rb
219
+ - lib/fir/util/qiniu_uploader.rb
216
220
  - lib/fir/version.rb
217
221
  - lib/fir/xcode_wrapper.sh
218
222
  - lib/fir_cli.rb
223
+ - luckin_coffee.png
219
224
  - test/build_ipa_test.rb
220
225
  - test/cases/test_apk.apk
221
226
  - test/cases/test_apk_txt
@@ -234,12 +239,13 @@ metadata: {}
234
239
  post_install_message: "\n ______________ ________ ____\n /
235
240
  ____/ _/ __ \\ / ____/ / / _/\n / /_ / // /_/ /_____/ / / / /
236
241
  /\n / __/ _/ // _, _/_____/ /___/ /____/ /\n /_/ /___/_/ |_| \\____/_____/___/\n\n
237
- \ ## 更新记录\n - (1.7.4) 配合 fastlane-plugin-fir_cli 做了一些小优化\n - (1.7.3) 新增了 上传指定图标,
238
- 不上传图标 以及 将版本固定显示在下载页上\n - (1.7.2) 修正了无论是否加参数都固定出现二维码图片的bug\n - (1.7.1) 增加了 钉钉推送
239
- , 增加了返回指定版本下载地址\n - (1.7.0) 过期了ipa_build 功能, 增加了对 android manifest instant run
240
- 的兼容\n - (1.6.13) 上传图标逻辑修改\n - (1.6.12) 修复了部分机器没有默认安装 byebug 的问题\n - (1.6.11)
241
- 变化了 ruby gem 仓库地址\n - [fir-cli](https://github.com/firhq/fir-cli) 已经开源\n - 欢迎
242
- fork, issue 和 pull request\n "
242
+ \ ## 更新记录\n - (2.0.0) publish 使用更快的存储商, 加速上传速度, 若感觉没以前可使用 switch_to_qiniu 恢复\n
243
+ \ - (1.7.4) 配合 fastlane-plugin-fir_cli 做了一些小优化\n - (1.7.3) 新增了 上传指定图标, 不上传图标 以及
244
+ 将版本固定显示在下载页上\n - (1.7.2) 修正了无论是否加参数都固定出现二维码图片的bug\n - (1.7.1) 增加了 钉钉推送 , 增加了返回指定版本下载地址\n
245
+ \ - (1.7.0) 过期了ipa_build 功能, 增加了对 android manifest instant run 的兼容\n - (1.6.13)
246
+ 上传图标逻辑修改\n - (1.6.12) 修复了部分机器没有默认安装 byebug 的问题\n - (1.6.11) 变化了 ruby gem 仓库地址\n
247
+ \ - [fir-cli](https://github.com/firhq/fir-cli) 已经开源\n - 欢迎 fork, issue 和 pull
248
+ request\n "
243
249
  rdoc_options: []
244
250
  require_paths:
245
251
  - lib
@@ -250,9 +256,9 @@ required_ruby_version: !ruby/object:Gem::Requirement
250
256
  version: '0'
251
257
  required_rubygems_version: !ruby/object:Gem::Requirement
252
258
  requirements:
253
- - - ">="
259
+ - - ">"
254
260
  - !ruby/object:Gem::Version
255
- version: '0'
261
+ version: 1.3.1
256
262
  requirements: []
257
263
  rubygems_version: 3.0.3
258
264
  signing_key: