pindo 4.7.0 → 4.7.2
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 +4 -4
- data/lib/pindo/base/aeshelper.rb +30 -2
- data/lib/pindo/base/githelper.rb +7 -9
- data/lib/pindo/client/aws3sclient.rb +1 -1
- data/lib/pindo/client/bossconfigclient.rb +3 -3
- data/lib/pindo/client/giteeclient.rb +2 -2
- data/lib/pindo/client/pgyerclient.rb +97 -102
- data/lib/pindo/command/appstore/iap.rb +1 -1
- data/lib/pindo/command/deploy/build.rb +70 -4
- data/lib/pindo/command/deploy/cert.rb +68 -67
- data/lib/pindo/command/{utils → dev}/applovin.rb +2 -2
- data/lib/pindo/command/dev/autobuild.rb +19 -7
- data/lib/pindo/command/dev/autoresign.rb +10 -6
- data/lib/pindo/command/dev/build.rb +94 -0
- data/lib/pindo/command/dev.rb +3 -6
- data/lib/pindo/command/ipa/autoresign.rb +4 -1
- data/lib/pindo/command/ipa/import.rb +45 -9
- data/lib/pindo/command/ipa/output.rb +7 -2
- data/lib/pindo/command/lib/update.rb +8 -8
- data/lib/pindo/command/pgyer/resign.rb +21 -19
- data/lib/pindo/command/pgyer/upload.rb +34 -6
- data/lib/pindo/command/utils/renewcert.rb +158 -0
- data/lib/pindo/command/utils.rb +1 -1
- data/lib/pindo/config/pindoconfig.rb +27 -0
- data/lib/pindo/module/appselect.rb +9 -8
- data/lib/pindo/module/cert/certhelper.rb +42 -36
- data/lib/pindo/module/cert/keychainhelper.rb +25 -13
- data/lib/pindo/module/cert/provisioninghelper.rb +1 -1
- data/lib/pindo/module/cert/xcodecerthelper.rb +98 -39
- data/lib/pindo/module/pgyer/pgyerhelper.rb +50 -28
- data/lib/pindo/module/xcode/xcodeappconfig.rb +2 -3
- data/lib/pindo/module/xcode/xcodereshandler.rb +41 -13
- data/lib/pindo/module/xcode/xcodereshelper.rb +2 -3
- data/lib/pindo/options/deployoptions.rb +1 -2
- data/lib/pindo/version.rb +1 -1
- metadata +5 -4
- data/lib/pindo/command/dev/renewcert.rb +0 -142
@@ -3,11 +3,13 @@ require 'open3'
|
|
3
3
|
require 'security'
|
4
4
|
|
5
5
|
module Pindo
|
6
|
-
|
6
|
+
|
7
7
|
module KeychainHelper
|
8
8
|
|
9
9
|
def self.import_file(path, keychain_path, keychain_password: nil, certificate_password: "", skip_set_partition_list: false, output: false)
|
10
|
-
|
10
|
+
# puts path
|
11
|
+
|
12
|
+
# puts "Could not find file '#{path}'" unless File.exist?(path)
|
11
13
|
|
12
14
|
password_part = " -P #{certificate_password.shellescape}"
|
13
15
|
|
@@ -19,22 +21,28 @@ module Pindo
|
|
19
21
|
command << " -T /usr/bin/productsign" # to not be asked for permission when using an installer cert for macOS
|
20
22
|
command << " 1> /dev/null" unless output
|
21
23
|
|
22
|
-
|
23
|
-
|
24
|
-
Open3.popen3(command) do |stdin, stdout, stderr, thrd|
|
25
|
-
UI.command_output(stdout.read.to_s) if output
|
24
|
+
# puts command
|
25
|
+
# sensitive_command = command.gsub(password_part, " -P ********")
|
26
26
|
|
27
|
+
# UI.command(sensitive_command) if output
|
28
|
+
Open3.popen3(command) do |stdin, stdout, stderr, thrd|
|
29
|
+
# UI.command_output(stdout.read.to_s) if output
|
30
|
+
# puts "123"
|
27
31
|
# Set partition list only if success since it can be a time consuming process if a lot of keys are installed
|
28
32
|
if thrd.value.success? && !skip_set_partition_list
|
33
|
+
# puts "安装成功!"
|
29
34
|
keychain_password ||= resolve_keychain_password(keychain_path)
|
30
35
|
set_partition_list(path, keychain_path, keychain_password: keychain_password, output: output)
|
31
36
|
else
|
32
37
|
# Output verbose if file is already installed since not an error otherwise we will show the whole error
|
33
38
|
err = stderr.read.to_s.strip
|
39
|
+
|
34
40
|
if err.include?("SecKeychainItemImport") && err.include?("The specified item already exists in the keychain")
|
35
|
-
# UI.verbose("'
|
41
|
+
# UI.verbose("'}' is already installed on this machine")
|
42
|
+
# puts "证书key已经存在,安装完成!"
|
36
43
|
else
|
37
|
-
|
44
|
+
# puts err
|
45
|
+
# raise Informative, err
|
38
46
|
end
|
39
47
|
end
|
40
48
|
end
|
@@ -64,8 +72,9 @@ module Pindo
|
|
64
72
|
# Helper.show_loading_indicator("Setting key partition list... (this can take a minute if there are a lot of keys installed)")
|
65
73
|
|
66
74
|
# Strip keychain password from command output
|
67
|
-
sensitive_command = command.gsub(password_part, " -k ********")
|
68
|
-
|
75
|
+
# sensitive_command = command.gsub(password_part, " -k ********")
|
76
|
+
# puts command
|
77
|
+
# UI.command(sensitive_command) if output
|
69
78
|
Open3.popen3(command) do |stdin, stdout, stderr, thrd|
|
70
79
|
unless thrd.value.success?
|
71
80
|
err = stderr.read.to_s.strip
|
@@ -73,6 +82,9 @@ module Pindo
|
|
73
82
|
# Inform user when no/wrong password was used as its needed to prevent UI permission popup from Xcode when signing
|
74
83
|
if err.include?("SecKeychainItemSetAccessWithPassword")
|
75
84
|
keychain_name = File.basename(keychain_path, ".*")
|
85
|
+
# puts "password #{keychain_password}"
|
86
|
+
# puts "keychain #{keychain_name}"
|
87
|
+
# puts "security #{server_name(keychain_name)}"
|
76
88
|
Security::InternetPassword.delete(server: server_name(keychain_name))
|
77
89
|
|
78
90
|
# UI.important("")
|
@@ -83,9 +95,9 @@ module Pindo
|
|
83
95
|
# UI.important("Please look at the following docs to see how to set a keychain password:")
|
84
96
|
# UI.important(" - https://docs.fastlane.tools/actions/sync_code_signing")
|
85
97
|
# UI.important(" - https://docs.fastlane.tools/actions/get_certificates")
|
86
|
-
puts "
|
98
|
+
# puts "证书密码错误!"
|
87
99
|
else
|
88
|
-
|
100
|
+
puts err
|
89
101
|
end
|
90
102
|
end
|
91
103
|
end
|
@@ -130,7 +142,7 @@ module Pindo
|
|
130
142
|
|
131
143
|
# server name used for accessing the macOS keychain
|
132
144
|
def self.server_name(keychain_name)
|
133
|
-
["
|
145
|
+
["pindo", "keychain", keychain_name].join("_")
|
134
146
|
end
|
135
147
|
|
136
148
|
private_class_method :server_name
|
@@ -89,7 +89,7 @@ module Pindo
|
|
89
89
|
|
90
90
|
|
91
91
|
destination = File.join(profiles_path, profile_filename(path, keychain_path))
|
92
|
-
puts "Installing provisioning profile... #{destination}"
|
92
|
+
# puts "Installing provisioning profile... #{destination}"
|
93
93
|
|
94
94
|
if path != destination
|
95
95
|
# copy to Xcode provisioning profile directory
|
@@ -1,5 +1,6 @@
|
|
1
1
|
|
2
2
|
require 'fileutils'
|
3
|
+
require 'pindo/base/aeshelper'
|
3
4
|
|
4
5
|
module Pindo
|
5
6
|
|
@@ -69,12 +70,17 @@ module Pindo
|
|
69
70
|
|
70
71
|
new_project_obj.targets.each do |target|
|
71
72
|
|
73
|
+
if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:dynamic_library]) ||
|
74
|
+
target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:static_library]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:bundle])
|
75
|
+
next
|
76
|
+
end
|
72
77
|
provisioning_info = nil
|
73
78
|
|
74
79
|
if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application])
|
75
80
|
bundle_id_map_key = target_map["MainTarget"]
|
76
81
|
provisioning_info = provisioning_info_array.select { |s| s["type"].to_s.eql?(bundle_id_map_key.to_s) }.first
|
77
|
-
|
82
|
+
else
|
83
|
+
|
78
84
|
target_map.each do |k, v|
|
79
85
|
if target.name.to_s.end_with?(k)
|
80
86
|
bundle_id_map_key = v.to_s
|
@@ -83,29 +89,34 @@ module Pindo
|
|
83
89
|
end
|
84
90
|
end
|
85
91
|
|
86
|
-
target.
|
87
|
-
target_atts_obj[target.uuid] = target_atts_obj[target.uuid] || {}
|
88
|
-
target_atts_obj[target.uuid]['DevelopmentTeam'] = team_id_vaule
|
89
|
-
target_atts_obj[target.uuid]['ProvisioningStyle'] = "Manual"
|
90
|
-
config.build_settings['DEVELOPMENT_TEAM'] = team_id_vaule
|
91
|
-
config.build_settings['DEVELOPMENT_TEAM[sdk=iphoneos*]'] = team_id_vaule
|
92
|
-
config.build_settings['CODE_SIGN_STYLE'] = "Manual"
|
93
|
-
|
94
|
-
config.build_settings['CODE_SIGN_IDENTITY'] = "Apple Distribution"
|
95
|
-
config.build_settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = "Apple Distribution"
|
96
|
-
|
97
|
-
if cert_type == "development"
|
98
|
-
config.build_settings['CODE_SIGN_IDENTITY'] = "Apple Development"
|
99
|
-
config.build_settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = "Apple Development"
|
100
|
-
end
|
92
|
+
# puts "=====1 target name: #{target.name.to_s} bundle_id_map_key: #{bundle_id_map_key} provisioning_info: #{provisioning_info}"
|
101
93
|
|
102
|
-
|
103
|
-
|
104
|
-
|
105
|
-
|
106
|
-
|
94
|
+
if !provisioning_info.nil?
|
95
|
+
target.build_configurations.each do |config|
|
96
|
+
target_atts_obj[target.uuid] = target_atts_obj[target.uuid] || {}
|
97
|
+
target_atts_obj[target.uuid]['DevelopmentTeam'] = team_id_vaule
|
98
|
+
target_atts_obj[target.uuid]['ProvisioningStyle'] = "Manual"
|
99
|
+
config.build_settings['DEVELOPMENT_TEAM'] = team_id_vaule
|
100
|
+
config.build_settings['DEVELOPMENT_TEAM[sdk=iphoneos*]'] = team_id_vaule
|
101
|
+
config.build_settings['CODE_SIGN_STYLE'] = "Manual"
|
102
|
+
|
103
|
+
config.build_settings['CODE_SIGN_IDENTITY'] = "Apple Distribution"
|
104
|
+
config.build_settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = "Apple Distribution"
|
105
|
+
|
106
|
+
if cert_type == "development"
|
107
|
+
config.build_settings['CODE_SIGN_IDENTITY'] = "Apple Development"
|
108
|
+
config.build_settings['CODE_SIGN_IDENTITY[sdk=iphoneos*]'] = "Apple Development"
|
109
|
+
end
|
110
|
+
|
111
|
+
if !provisioning_info.nil?
|
112
|
+
config.build_settings['PRODUCT_BUNDLE_IDENTIFIER'] = provisioning_info["bundle_id"]
|
113
|
+
config.build_settings['PROVISIONING_PROFILE_SPECIFIER'] = provisioning_info['profile_name']
|
114
|
+
config.build_settings['PROVISIONING_PROFILE_SPECIFIER[sdk=iphoneos*]'] = provisioning_info['profile_name']
|
115
|
+
|
116
|
+
end
|
107
117
|
end
|
108
118
|
end
|
119
|
+
|
109
120
|
|
110
121
|
end
|
111
122
|
new_project_obj.save
|
@@ -120,6 +131,11 @@ module Pindo
|
|
120
131
|
|
121
132
|
project_obj.targets.each do |target|
|
122
133
|
|
134
|
+
if target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:framework]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:dynamic_library]) ||
|
135
|
+
target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:static_library]) || target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:bundle])
|
136
|
+
next
|
137
|
+
end
|
138
|
+
|
123
139
|
temp_entitlements_file = target.build_configurations.first.build_settings['CODE_SIGN_ENTITLEMENTS']
|
124
140
|
if !temp_entitlements_file.nil? && !temp_entitlements_file.empty?
|
125
141
|
entitlements_plist_path = File.join(new_project_dir, temp_entitlements_file)
|
@@ -127,27 +143,37 @@ module Pindo
|
|
127
143
|
if !File.exist?(entitlements_plist_path)
|
128
144
|
raise Informative, "Target: #{target.name.to_s} 找不到文件 #{entitlements_plist_path}"
|
129
145
|
end
|
130
|
-
end
|
131
146
|
|
132
|
-
|
133
|
-
|
134
|
-
|
135
|
-
|
147
|
+
if !group_id.nil?
|
148
|
+
modify_entitlements_plist(entitlements_plist_path:entitlements_plist_path, group_id:group_id)
|
149
|
+
end
|
150
|
+
|
151
|
+
if target.product_type.to_s.eql?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) then
|
152
|
+
add_swark_entitlement(entitlements_plist_path:entitlements_plist_path, bundle_id_dict:provisioning_info_array)
|
153
|
+
if !icloud_id.nil?
|
154
|
+
modify_entitlements_plist(entitlements_plist_path:entitlements_plist_path, icloud_id:icloud_id)
|
155
|
+
end
|
156
|
+
end
|
157
|
+
|
136
158
|
end
|
137
159
|
|
160
|
+
temp_info = target.build_configurations.first.build_settings['INFOPLIST_FILE']
|
161
|
+
if !temp_info.nil? && !temp_info.empty?
|
162
|
+
info_plist_path = File.join(new_project_dir, temp_info)
|
163
|
+
if !File.exist?(info_plist_path)
|
164
|
+
raise Informative, "Missing Target #{target.name.to_s} Info.plist!!! #{info_plist_path} Modify Info.plist Error !!!"
|
165
|
+
end
|
138
166
|
|
139
|
-
|
140
|
-
|
141
|
-
|
142
|
-
|
143
|
-
|
144
|
-
|
145
|
-
modify_info_plist_icloud(plist_file_name:info_plist_path, icloud_id:nil)
|
167
|
+
if target.product_type.to_s.eql?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) then
|
168
|
+
if !icloud_id.nil?
|
169
|
+
modify_info_plist_icloud(plist_file_name:info_plist_path, icloud_id:icloud_id)
|
170
|
+
else
|
171
|
+
modify_info_plist_icloud(plist_file_name:info_plist_path, icloud_id:nil)
|
172
|
+
end
|
146
173
|
end
|
174
|
+
|
147
175
|
end
|
148
|
-
|
149
|
-
modify_entitlements_plist(entitlements_plist_path:entitlements_plist_path, group_id:group_id)
|
150
|
-
end
|
176
|
+
|
151
177
|
end
|
152
178
|
|
153
179
|
end
|
@@ -200,7 +226,40 @@ module Pindo
|
|
200
226
|
end
|
201
227
|
end
|
202
228
|
|
203
|
-
def create_upload_cert_info(apple_id:nil, cert_type:nil
|
229
|
+
def create_upload_cert_info(apple_id:nil, cert_type:nil)
|
230
|
+
|
231
|
+
cert_dest_dir = File.join(Dir.pwd, "cert")
|
232
|
+
if !File.exist?(cert_dest_dir)
|
233
|
+
FileUtils.mkdir_p(cert_dest_dir)
|
234
|
+
end
|
235
|
+
|
236
|
+
|
237
|
+
cert_git_url = pindo_single_config.deploy_cert_giturl
|
238
|
+
if apple_id.eql?(pindo_single_config.demo_apple_id)
|
239
|
+
cert_git_url = pindo_single_config.dev_cert_giturl
|
240
|
+
end
|
241
|
+
cert_reponame = cert_git_url.split("/").last.chomp(".git")
|
242
|
+
certs_dir = getcode_to_dir(reponame:cert_reponame, remote_url:cert_git_url, path: pindo_single_config.pindo_dir, new_branch:apple_id)
|
243
|
+
|
244
|
+
cert_git_dir = cert_type.downcase
|
245
|
+
if !cert_type.downcase.include?("development")
|
246
|
+
cert_git_dir = "distribution"
|
247
|
+
end
|
248
|
+
|
249
|
+
keys = Dir[File.join(certs_dir, "certs", cert_git_dir.to_s, "*.p12")]
|
250
|
+
decrypt_password = AESHelper.fetch_password(keychain_name:cert_git_url)
|
251
|
+
output_dir = Dir.mktmpdir
|
252
|
+
key_path = AESHelper.decrypt_specific_file(src_file: keys.first, password:decrypt_password, output_dir: output_dir)
|
253
|
+
if key_path.nil? || key_path.empty? || !File.exist?(key_path)
|
254
|
+
AESHelper.delete_password(keychain_name:cert_git_url)
|
255
|
+
raise Informative, "证书解析失败,密码错误!"
|
256
|
+
end
|
257
|
+
|
258
|
+
FileUtils.copy(key_path, File.join(cert_dest_dir, "#{cert_type}.p12"))
|
259
|
+
|
260
|
+
end
|
261
|
+
|
262
|
+
def create_upload_provisioning_info(apple_id:nil, cert_type:nil, provisioning_info_array:nil)
|
204
263
|
|
205
264
|
cert_dir = File.join(Dir.pwd, "cert")
|
206
265
|
cert_json_file = File.join(cert_dir, "certs.json")
|
@@ -247,8 +306,8 @@ module Pindo
|
|
247
306
|
|
248
307
|
cert_item["cert_id"] = cert_item["cert_id"] || bundle_id_signing_identity
|
249
308
|
cert_item["password"] = "goodcert1"
|
250
|
-
cert_item["cert_file"] = "#{cert_type}.p12"
|
251
|
-
cert_item["cert_type"] = cert_type
|
309
|
+
cert_item["cert_file"] = "#{cert_type}.p12"
|
310
|
+
cert_item["cert_type"] = cert_type
|
252
311
|
cert_item["cert_provisioning_group"] = cert_item["cert_provisioning_group"] || []
|
253
312
|
|
254
313
|
|
@@ -36,21 +36,27 @@ module Pindo
|
|
36
36
|
def login
|
37
37
|
@pgyer_client = PgyerClient.new
|
38
38
|
if @force_login || !@has_login
|
39
|
-
@has_login = @pgyer_client.do_login(force_login:@force_login)
|
39
|
+
@has_login = @pgyer_client.do_login(force_login:@force_login)
|
40
40
|
@force_login = false
|
41
|
+
else
|
42
|
+
@has_login = @pgyer_client.do_login(force_login:false)
|
41
43
|
end
|
42
44
|
return @has_login
|
43
45
|
end
|
44
46
|
|
45
47
|
def prepare_upload(working_directory:nil, proj_name:nil)
|
46
48
|
upload_proj_name = proj_name
|
49
|
+
if upload_proj_name.nil? || upload_proj_name.empty?
|
50
|
+
upload_proj_name = @proj_name
|
51
|
+
end
|
52
|
+
|
47
53
|
app_info_obj = nil
|
48
54
|
if login
|
49
55
|
|
50
|
-
if !
|
56
|
+
if !upload_proj_name.nil?
|
51
57
|
app_info_obj = PgyerHelper.share_instace.find_app_info_with_obj_list(proj_name:upload_proj_name)
|
52
58
|
end
|
53
|
-
|
59
|
+
|
54
60
|
if !app_info_obj.nil?
|
55
61
|
return app_info_obj
|
56
62
|
end
|
@@ -58,35 +64,35 @@ module Pindo
|
|
58
64
|
proj_name_array = []
|
59
65
|
if File.exist?(File.join(working_directory, "config.json"))
|
60
66
|
config_json = JSON.parse(File.read(File.join(working_directory, "config.json")))
|
61
|
-
proj_name_array << config_json["project_info"]["project_name"]
|
67
|
+
proj_name_array << config_json["project_info"]["project_name"]
|
62
68
|
end
|
63
69
|
|
64
70
|
xcodeproj_file_name = Dir.glob(File.join(Dir.pwd, "/*.xcodeproj")).max_by {|f| File.mtime(f)}
|
65
71
|
upload_proj_name = File.basename(xcodeproj_file_name, ".xcodeproj") if xcodeproj_file_name
|
66
72
|
if !upload_proj_name.nil? && !upload_proj_name.empty?
|
67
|
-
proj_name_array << upload_proj_name
|
73
|
+
proj_name_array << upload_proj_name
|
68
74
|
end
|
69
|
-
|
75
|
+
|
70
76
|
puts
|
71
77
|
dir_base_name = File.basename(working_directory)
|
72
78
|
unless ["Desktop", "Documents", "Downloads"].include?(dir_base_name)
|
73
79
|
proj_name_array << dir_base_name
|
74
80
|
end
|
75
|
-
|
81
|
+
|
76
82
|
proj_name_array << "自定义输入Pyger上的App代号"
|
77
83
|
|
78
84
|
if proj_name_array.size > 1
|
79
85
|
cli = HighLine.new
|
80
86
|
upload_proj_name = cli.choose do |menu|
|
81
|
-
menu.prompt = "
|
87
|
+
menu.prompt = "请选择Pgyer上的App代号:"
|
82
88
|
menu.choices(*proj_name_array)
|
83
89
|
end
|
84
90
|
if upload_proj_name.include?("自定义输入")
|
85
|
-
upload_proj_name = ask('
|
91
|
+
upload_proj_name = ask('请输入Pyger上的App代号(大小写空格忽略):') || nil
|
86
92
|
upload_proj_name = upload_proj_name.strip
|
87
93
|
end
|
88
94
|
else
|
89
|
-
upload_proj_name = ask('
|
95
|
+
upload_proj_name = ask('请输入Pyger上的App代号(大小写空格忽略):') || nil
|
90
96
|
upload_proj_name = upload_proj_name.strip
|
91
97
|
end
|
92
98
|
|
@@ -94,15 +100,18 @@ module Pindo
|
|
94
100
|
app_info_obj = PgyerHelper.share_instace.find_app_info_with_obj_list(proj_name:upload_proj_name)
|
95
101
|
|
96
102
|
if app_info_obj.nil?
|
97
|
-
upload_proj_name = ask('
|
103
|
+
upload_proj_name = ask('没有找到结果,请重新输入Pyger上的App代号(大小写空格忽略):') || nil
|
98
104
|
upload_proj_name = upload_proj_name.strip
|
99
105
|
app_info_obj = PgyerHelper.share_instace.find_app_info_with_obj_list(proj_name:upload_proj_name)
|
100
106
|
end
|
101
107
|
|
102
108
|
if app_info_obj.nil?
|
103
|
-
raise Informative, "#{upload_proj_name}
|
109
|
+
raise Informative, "#{upload_proj_name} 名称错误, 请输入正确的App代号,Pgyer网站没有该App!!!"
|
104
110
|
end
|
111
|
+
else
|
112
|
+
raise Informative, "请先登录Pgyer网站"
|
105
113
|
end
|
114
|
+
@proj_name = upload_proj_name
|
106
115
|
app_info_obj
|
107
116
|
end
|
108
117
|
|
@@ -110,20 +119,28 @@ module Pindo
|
|
110
119
|
|
111
120
|
args_ipa_file_dir = File.expand_path(File::dirname(ipa_file_upload))
|
112
121
|
ipa_file_upload=File.join(args_ipa_file_dir, File.basename(ipa_file_upload))
|
113
|
-
|
114
122
|
current_project_dir = Dir.pwd
|
115
|
-
puts "current_project_dir : #{current_project_dir}"
|
116
|
-
puts description
|
117
|
-
puts File.exist?(File.join(current_project_dir, ".git"))
|
118
123
|
if description.nil? && File.exist?(File.join(current_project_dir, ".git"))
|
119
|
-
|
120
|
-
|
121
|
-
|
124
|
+
description = git!(%W(-C #{current_project_dir} show -s --format=commit::%H)).strip
|
125
|
+
xcodeproj_file_name = Dir.glob(File.join(current_project_dir, "/*.xcodeproj")).max_by {|f| File.mtime(f)}
|
126
|
+
if !xcodeproj_file_name.nil? && !xcodeproj_file_name.empty? && File.exist?(xcodeproj_file_name)
|
127
|
+
project_obj = Xcodeproj::Project.open(xcodeproj_file_name)
|
128
|
+
main_target = project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
|
129
|
+
provisioning_profile_name = main_target.build_configurations.first.build_settings['PROVISIONING_PROFILE_SPECIFIER'].downcase.split(" ")
|
130
|
+
if provisioning_profile_name.include?("adhoc")
|
131
|
+
description = git!(%W(-C #{current_project_dir} show -s --format=commit::%H)).strip
|
132
|
+
elsif provisioning_profile_name.include?("development")
|
133
|
+
if File.exist?(File.join(current_project_dir, ".release_info"))
|
134
|
+
description = File.read(File.join(current_project_dir, ".release_info"))
|
135
|
+
else
|
136
|
+
description = git!(%W(-C #{current_project_dir} show -s --format=%h::%s)).strip
|
137
|
+
end
|
138
|
+
elsif provisioning_profile_name.include?("appstore")
|
139
|
+
description = "提交包重签名"
|
140
|
+
end
|
122
141
|
end
|
123
142
|
end
|
124
143
|
|
125
|
-
puts "description : #{description}"
|
126
|
-
|
127
144
|
addtach_file = nil
|
128
145
|
if ipa_file_upload.include?(File.join(current_project_dir, "build")) && File.exist?(File.join(current_project_dir, "VMData"))
|
129
146
|
|
@@ -150,7 +167,8 @@ module Pindo
|
|
150
167
|
|
151
168
|
puts
|
152
169
|
puts "上传项目: #{app_info_obj["appName"]}"
|
153
|
-
|
170
|
+
print "上传备注: "
|
171
|
+
puts description
|
154
172
|
|
155
173
|
|
156
174
|
aws_client = AWSS3Client.new
|
@@ -206,9 +224,12 @@ module Pindo
|
|
206
224
|
end
|
207
225
|
|
208
226
|
|
209
|
-
def send_apptest_wechat_msg(msg_data:nil)
|
227
|
+
def send_apptest_wechat_msg(msg_data:nil, wechat_url:nil)
|
210
228
|
|
211
|
-
wechat_msg_url =
|
229
|
+
wechat_msg_url = wechat_url
|
230
|
+
if wechat_msg_url.nil? || wechat_msg_url.empty?
|
231
|
+
wechat_msg_url = get_user_local_wechat_url()
|
232
|
+
end
|
212
233
|
|
213
234
|
if !wechat_msg_url.nil? && wechat_msg_url.length >1
|
214
235
|
|
@@ -264,7 +285,7 @@ module Pindo
|
|
264
285
|
req.headers['Content-Type'] = 'application/json'
|
265
286
|
req.body = body_data.to_json
|
266
287
|
end
|
267
|
-
|
288
|
+
|
268
289
|
|
269
290
|
body_data = {
|
270
291
|
msgtype:"text",
|
@@ -387,7 +408,7 @@ module Pindo
|
|
387
408
|
Funlog.instance.fancyinfo_error("拉取app信息列表失败!")
|
388
409
|
raise Informative, "Pgyer网络数据异常!!!"
|
389
410
|
end
|
390
|
-
|
411
|
+
|
391
412
|
|
392
413
|
return app_info_list
|
393
414
|
end
|
@@ -397,6 +418,7 @@ module Pindo
|
|
397
418
|
Funlog.instance.fancyinfo_start("正在拉取app上传记录...")
|
398
419
|
|
399
420
|
appId = app_info_obj["appId"]
|
421
|
+
# puts "appId #{appId}"
|
400
422
|
version_data = @pgyer_client.get_app_version_list_req(appId:appId) || {}
|
401
423
|
|
402
424
|
if version_data["data"].nil? || version_data["data"].size <=0
|
@@ -424,7 +446,7 @@ module Pindo
|
|
424
446
|
app_incId_index = ask('请选择上面的Build号:')
|
425
447
|
|
426
448
|
end
|
427
|
-
|
449
|
+
|
428
450
|
Funlog.instance.fancyinfo_success("拉取app上传记录完成!")
|
429
451
|
|
430
452
|
version_item_obj = nil
|
@@ -508,7 +530,7 @@ module Pindo
|
|
508
530
|
return true
|
509
531
|
else
|
510
532
|
Funlog.instance.fancyinfo_error("重签名失败!")
|
511
|
-
return false
|
533
|
+
return false
|
512
534
|
end
|
513
535
|
|
514
536
|
end
|
@@ -7,8 +7,7 @@ module Pindo
|
|
7
7
|
module XcodeAppConfig
|
8
8
|
|
9
9
|
def auto_increase_buildnumber(app_config_file:nil)
|
10
|
-
|
11
|
-
if !File.exist?(app_config_file)
|
10
|
+
if File.exist?(app_config_file)
|
12
11
|
config_json = JSON.parse(File.read(app_config_file))
|
13
12
|
app_version = config_json['app_info']['app_version']
|
14
13
|
app_build_version = config_json['app_info']['app_build_version']
|
@@ -26,7 +25,7 @@ module Pindo
|
|
26
25
|
app_build_version = app_build_version_array.join(".")
|
27
26
|
|
28
27
|
config_json['app_info']['app_build_version'] = app_build_version
|
29
|
-
File.open(
|
28
|
+
File.open(app_config_file, "w") do |file|
|
30
29
|
file.write(JSON.pretty_generate(config_json))
|
31
30
|
file.close
|
32
31
|
end
|
@@ -72,20 +72,36 @@ module Pindo
|
|
72
72
|
|
73
73
|
def initialize(proj_fullname:nil)
|
74
74
|
@proj_fullname = proj_fullname
|
75
|
-
@project_obj = Xcodeproj::Project.open(proj_fullname)
|
75
|
+
@project_obj = Xcodeproj::Project.open(proj_fullname)
|
76
76
|
end
|
77
77
|
|
78
78
|
def get_xcodeproj_icon_path
|
79
|
+
|
80
|
+
icon_path = nil
|
79
81
|
select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
|
80
|
-
|
81
|
-
|
82
|
+
if !select_target.nil?
|
83
|
+
file_refs = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") } || []
|
84
|
+
file_refs.each do |file_ref|
|
85
|
+
icon_path = File.join(file_ref.real_path,"AppIcon.appiconset")
|
86
|
+
if File.exist?(icon_path)
|
87
|
+
break
|
88
|
+
else
|
89
|
+
next
|
90
|
+
end
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
if icon_path.nil? || icon_path.empty? || !File.exist?(icon_path)
|
95
|
+
raise Informative, "没有找到Xcode icon 目录"
|
96
|
+
end
|
97
|
+
|
82
98
|
return icon_path
|
83
99
|
end
|
84
100
|
|
85
101
|
def install_icon_res(new_icon_dir:nil)
|
86
102
|
icon_path = get_xcodeproj_icon_path
|
87
103
|
begin
|
88
|
-
FileUtils.rm_rf(icon_path)
|
104
|
+
FileUtils.rm_rf(icon_path)
|
89
105
|
FileUtils.mkdir_p(icon_path)
|
90
106
|
rescue StandardError => e
|
91
107
|
end
|
@@ -109,17 +125,29 @@ module Pindo
|
|
109
125
|
def get_xcodeproj_imessage_icon_path
|
110
126
|
icon_path = nil
|
111
127
|
select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:messages_extension]) }.first
|
112
|
-
if select_target.nil?
|
113
|
-
|
114
|
-
|
128
|
+
if !select_target.nil?
|
129
|
+
file_refs = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") } || []
|
130
|
+
file_refs.each do |file_ref|
|
131
|
+
icon_path = File.join(file_ref.real_path,"iMessage App Icon.stickersiconset")
|
132
|
+
if File.exist?(icon_path)
|
133
|
+
break
|
134
|
+
else
|
135
|
+
next
|
136
|
+
end
|
137
|
+
end
|
138
|
+
|
139
|
+
if icon_path.nil? || icon_path.empty? || !File.exist?(icon_path)
|
140
|
+
raise Informative, "没有找到Xcode iMessage icon 目录"
|
141
|
+
end
|
115
142
|
end
|
143
|
+
|
116
144
|
return icon_path
|
117
145
|
end
|
118
146
|
|
119
147
|
def install_imessage_icon_res(new_icon_dir:nil)
|
120
148
|
icon_path = get_xcodeproj_imessage_icon_path
|
121
149
|
begin
|
122
|
-
FileUtils.rm_rf(icon_path)
|
150
|
+
FileUtils.rm_rf(icon_path)
|
123
151
|
FileUtils.mkdir_p(icon_path)
|
124
152
|
rescue StandardError => e
|
125
153
|
end
|
@@ -147,7 +175,7 @@ module Pindo
|
|
147
175
|
launchimg_path = nil
|
148
176
|
select_target = @project_obj.targets.select { |target| target.product_type.include?(Xcodeproj::Constants::PRODUCT_TYPE_UTI[:application]) }.first
|
149
177
|
file_ref = select_target.resources_build_phase.files_references.select { |file| file.display_name.include?("Assets.xcassets") }.first
|
150
|
-
|
178
|
+
|
151
179
|
assets_path = file_ref.real_path
|
152
180
|
if File.exist?(File.join(assets_path, "LaunchImage.imageset"))
|
153
181
|
launchimg_path = File.join(assets_path, "LaunchImage.imageset")
|
@@ -167,9 +195,9 @@ module Pindo
|
|
167
195
|
end
|
168
196
|
|
169
197
|
project_origin_launchimg = Dir.glob(File.join(xcodeproj_launchimg_path, "/*.png")).max_by {|f| File.mtime(f)}
|
170
|
-
|
198
|
+
|
171
199
|
if project_origin_launchimg.nil? || !File.exist?(project_origin_launchimg)
|
172
|
-
return
|
200
|
+
return
|
173
201
|
end
|
174
202
|
|
175
203
|
if File.exist?(project_origin_launchimg) && !File.exist?(launchimg_file)
|
@@ -177,7 +205,7 @@ module Pindo
|
|
177
205
|
end
|
178
206
|
|
179
207
|
begin
|
180
|
-
FileUtils.rm_rf(xcodeproj_launchimg_path)
|
208
|
+
FileUtils.rm_rf(xcodeproj_launchimg_path)
|
181
209
|
FileUtils.mkdir_p(xcodeproj_launchimg_path)
|
182
210
|
rescue StandardError => e
|
183
211
|
end
|
@@ -190,7 +218,7 @@ module Pindo
|
|
190
218
|
File.open(File.join(xcodeproj_launchimg_path, "Contents.json"), "w") do |f|
|
191
219
|
f.write(JSON.pretty_generate(launch_json))
|
192
220
|
end
|
193
|
-
|
221
|
+
|
194
222
|
end
|
195
223
|
|
196
224
|
end
|
@@ -63,7 +63,7 @@ module Pindo
|
|
63
63
|
'sips',
|
64
64
|
'--matchTo', '/System/Library/ColorSync/Profiles/sRGB Profile.icc',
|
65
65
|
'-z', width.to_s, height.to_s,
|
66
|
-
|
66
|
+
icon_ori_name,
|
67
67
|
'--out', File.join(new_icon_dir, image_name)
|
68
68
|
]
|
69
69
|
Executable.capture_command('sips', command, capture: :out)
|
@@ -83,7 +83,6 @@ module Pindo
|
|
83
83
|
create_icon(icon_name: icon_name, new_icon_dir: new_icon_dir, xcode_icon_json: XcodoeResConst.xcode_ios_icon_json)
|
84
84
|
icon_dir = File.dirname(icon_name)
|
85
85
|
imessage_icon = File.join(icon_dir, "icon1024_768.png")
|
86
|
-
|
87
86
|
new_imessage_icon_dir = File.join(new_icon_dir, "imessage")
|
88
87
|
|
89
88
|
if File.exist?(imessage_icon)
|
@@ -92,7 +91,7 @@ module Pindo
|
|
92
91
|
rescue => e
|
93
92
|
puts e
|
94
93
|
end
|
95
|
-
create_imessage_icon(icon_name:
|
94
|
+
create_imessage_icon(icon_name: icon_name, image_icon_name:imessage_icon, new_icon_dir: new_imessage_icon_dir, xcode_icon_json: XcodoeResConst.xcode_ios_imessage_icon_json)
|
96
95
|
end
|
97
96
|
end
|
98
97
|
|