pindo 4.7.0 → 4.7.2
Sign up to get free protection for your applications and to get access to all the features.
- 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
|
|