fir-cli 1.7.4.1 → 2.0.0.beta

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
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: