pindo 4.7.0 → 4.7.1

Sign up to get free protection for your applications and to get access to all the features.
@@ -39,6 +39,10 @@ module Pindo
39
39
  @args_send_flag = argv.flag?('send', false)
40
40
  @args_proj_name = argv.option('proj')
41
41
 
42
+ if @args_send_flag
43
+ @args_upload_flag = true
44
+ end
45
+
42
46
  super
43
47
  @additional_args = argv.remainder!
44
48
  end
@@ -58,7 +62,7 @@ module Pindo
58
62
  end
59
63
 
60
64
  app_info_obj = nil
61
- if @args_upload_flag || @args_send_flag
65
+ if @args_upload_flag
62
66
  proj_name = @args_proj_name
63
67
  app_info_obj = PgyerHelper.share_instace.prepare_upload(working_directory:Dir.pwd, proj_name:proj_name)
64
68
  end
@@ -120,7 +124,18 @@ module Pindo
120
124
  ipa_file_upload = Dir.glob(build_path).max_by {|f| File.mtime(f)}
121
125
 
122
126
  if !ipa_file_upload.nil? && !app_info_obj.nil?
123
- result_data = PgyerHelper.share_instace.start_upload(app_info_obj:app_info_obj, ipa_file_upload:ipa_file_upload, description:nil)
127
+ description = nil
128
+ if File.exist?(File.join(pindo_new_project_dir, ".release_info"))
129
+ description = File.read(File.join(pindo_new_project_dir, ".release_info"))
130
+ else
131
+ if File.exist?(File.join(pindo_new_project_dir, ".git"))
132
+ description = git!(%W(-C #{pindo_new_project_dir} show -s --format='%h %s')).strip
133
+ unless !description.nil? && description.length > 10
134
+ description = nil
135
+ end
136
+ end
137
+ end
138
+ result_data = PgyerHelper.share_instace.start_upload(app_info_obj:app_info_obj, ipa_file_upload:ipa_file_upload, description:description)
124
139
  if !result_data.nil? && !result_data["data"].nil? && !result_data["data"]["id"].nil?
125
140
  msg_data = PgyerHelper.share_instace.make_msg_data(app_info_obj:app_info_obj, app_version_info_obj:result_data["data"])
126
141
  PgyerHelper.share_instace.print_app_version_info(msg_data:msg_data)
@@ -45,6 +45,10 @@ module Pindo
45
45
  @args_send_flag = argv.flag?('send', false)
46
46
  @args_proj_name = argv.option('proj')
47
47
 
48
+ if @args_send_flag
49
+ @args_upload_flag = true
50
+ end
51
+
48
52
  super
49
53
  @additional_args = argv.remainder!
50
54
  end
@@ -0,0 +1,94 @@
1
+ require 'highline/import'
2
+ require 'fileutils'
3
+ require 'json'
4
+ require 'xcodeproj'
5
+ require 'gym'
6
+
7
+ module Pindo
8
+ class Command
9
+ class Dev < Command
10
+ class Build < Dev
11
+
12
+
13
+ self.summary = '编译工程,并支持上传ipa到测试网站'
14
+
15
+ self.description = <<-DESC
16
+ 编译工程. 用法:在工程目录下执行 pindo dev build --upload
17
+ DESC
18
+
19
+ self.arguments = [
20
+
21
+ ]
22
+
23
+
24
+ def self.options
25
+ [
26
+ ['--proj', '指定上传到pgyer对应的项目名称(大小写空格忽略),用法:pindo ipa autobuild --proj=aichatv4'],
27
+ ['--upload', '是否上传编译后的ipa, 用法:pindo ipa autobuild --upload'],
28
+ ['--send', '上传到之后是否发送测试信息,用法:pindo ipa autobuild --send'],
29
+ ].concat(super)
30
+ end
31
+
32
+ def initialize(argv)
33
+
34
+ @args_upload_flag = argv.flag?('upload', false)
35
+ @args_send_flag = argv.flag?('send', false)
36
+ @args_proj_name = argv.option('proj')
37
+
38
+ if @args_send_flag
39
+ @args_upload_flag = true
40
+ end
41
+
42
+ super
43
+ @additional_args = argv.remainder!
44
+ end
45
+
46
+ def run
47
+
48
+
49
+ app_info_obj = nil
50
+ if @args_upload_flag
51
+ proj_name = @args_proj_name
52
+ app_info_obj = PgyerHelper.share_instace.prepare_upload(working_directory:Dir.pwd, proj_name:proj_name)
53
+ end
54
+
55
+ args_temp = []
56
+ Pindo::Command::Deploy::Build::run(args_temp)
57
+
58
+
59
+ pindo_new_project_dir = Dir.pwd
60
+ build_path = File.join(pindo_new_project_dir, "build", "*.ipa")
61
+ ipa_file_upload = Dir.glob(build_path).max_by {|f| File.mtime(f)}
62
+
63
+ if !ipa_file_upload.nil? && !app_info_obj.nil?
64
+
65
+ description = nil
66
+ if File.exist?(File.join(pindo_new_project_dir, ".release_info"))
67
+ description = File.read(File.join(pindo_new_project_dir, ".release_info"))
68
+ else
69
+ if File.exist?(File.join(pindo_new_project_dir, ".git"))
70
+ description = git!(%W(-C #{pindo_new_project_dir} show -s --format='%h %s')).strip
71
+ unless !description.nil? && description.length > 10
72
+ description = nil
73
+ end
74
+ end
75
+ end
76
+ result_data = PgyerHelper.share_instace.start_upload(app_info_obj:app_info_obj, ipa_file_upload:ipa_file_upload, description:description)
77
+ if !result_data.nil? && !result_data["data"].nil? && !result_data["data"]["id"].nil?
78
+ msg_data = PgyerHelper.share_instace.make_msg_data(app_info_obj:app_info_obj, app_version_info_obj:result_data["data"])
79
+ PgyerHelper.share_instace.print_app_version_info(msg_data:msg_data)
80
+ if @args_send_flag
81
+ PgyerHelper.share_instace.send_apptest_wechat_msg(msg_data:msg_data)
82
+ end
83
+ end
84
+ end
85
+
86
+ system "open #{project_dir}"
87
+
88
+ end
89
+
90
+
91
+ end
92
+ end
93
+ end
94
+ end
@@ -8,6 +8,7 @@ require 'pindo/command/dev/pub'
8
8
  require 'pindo/command/dev/debug'
9
9
  require 'pindo/command/dev/autoresign'
10
10
  require 'pindo/command/dev/autobuild'
11
+ require 'pindo/command/dev/build'
11
12
  # require 'pindo/command/dev/renewcert'
12
13
  # require 'pindo/command/dev/pgyercert'
13
14
  # require 'pindo/command/dev/createbuild'
@@ -46,6 +46,10 @@ module Pindo
46
46
  @args_send_flag = argv.flag?('send', false)
47
47
  @args_proj_name = argv.option('proj')
48
48
 
49
+ if @args_send_flag
50
+ @args_upload_flag = true
51
+ end
52
+
49
53
  super
50
54
  @additional_args = argv.remainder!
51
55
  end
@@ -175,7 +175,7 @@ module Pindo
175
175
  end
176
176
  end
177
177
 
178
- if pods_array.include?("FancyAD")
178
+ if pods_array.include?("FancyAD") || pods_array.include?("AppLovinSDK")
179
179
  puts
180
180
  puts "Run Applovin Script ..."
181
181
  Dir.chdir(pindo_new_project_dir)
@@ -45,6 +45,11 @@ module Pindo
45
45
  @args_send_flag = argv.flag?('send', false)
46
46
  @args_increase_flag = argv.flag?('increase', false)
47
47
 
48
+
49
+ if @args_send_flag
50
+ @args_upload_flag = true
51
+ end
52
+
48
53
  super
49
54
  end
50
55
 
@@ -53,22 +53,22 @@ module Pindo
53
53
 
54
54
  private_source = sources.select { |s| s.git? && s.url.to_s.eql?(pod_index_url)}.first
55
55
  if !private_source.nil?
56
-
57
- puts "地址:#{private_source.url}"
58
- puts "目录:#{private_source.repo}"
56
+
57
+ puts "私有Pod地址:#{pod_index_url}"
58
+ puts "私有Pod目录:~/.cocoapods"
59
59
  getcode_to_dir(reponame:File.basename(private_source.repo), remote_url: pod_index_url, path:repos_path)
60
60
  else
61
- puts "地址:#{pod_index_url}"
62
- puts "目录:~/.cocoapods"
61
+ puts "私有Pod地址:#{pod_index_url}"
62
+ puts "私有Pod目录:~/.cocoapods"
63
63
  repository_name = pod_index_url.split("/").last.chomp(".git")
64
64
  getcode_to_dir(reponame:repository_name, remote_url: pod_index_url, path:repos_path)
65
65
  end
66
-
66
+
67
67
 
68
68
  if @args_install_flag
69
69
  begin
70
- if File.exist?("#{working_dir}/Podfile")
71
- Pod::Command::Install::run(['--clean-install'])
70
+ if File.exist?("#{working_dir}/Podfile")
71
+ Pod::Command::Install::run(['--clean-install'])
72
72
  end
73
73
  rescue => e
74
74
  puts e.message
@@ -281,6 +281,14 @@ module Pindo
281
281
  return url
282
282
  end
283
283
 
284
+ def cert_key_password
285
+ cert_key_password = ''
286
+ if !@pindo_user_config_json.nil? && !@pindo_user_config_json["develop_accout_info"].nil?
287
+ cert_key_password = @pindo_user_config_json["develop_accout_info"]["cert_key_password"]
288
+ end
289
+ return cert_key_password
290
+ end
291
+
284
292
  def deploy_cert_giturl
285
293
  url = ''
286
294
  if !@pindo_user_config_json.nil? && !@pindo_user_config_json["develop_accout_info"].nil?
@@ -288,6 +296,16 @@ module Pindo
288
296
  end
289
297
  return url
290
298
  end
299
+
300
+ def deploy_cert_decrypt_password
301
+ pass = ''
302
+ if !@pindo_user_config_json.nil? && !@pindo_user_config_json["develop_accout_info"].nil?
303
+ pass = @pindo_user_config_json["develop_accout_info"]["deploy_cert_decrypt_password"]
304
+ end
305
+ return pass
306
+ end
307
+
308
+
291
309
 
292
310
  def dev_cert_giturl
293
311
  url = ''
@@ -297,6 +315,15 @@ module Pindo
297
315
  return url
298
316
  end
299
317
 
318
+
319
+ def dev_cert_decrypt_password
320
+ pass = ''
321
+ if !@pindo_user_config_json.nil? && !@pindo_user_config_json["develop_accout_info"].nil?
322
+ pass = @pindo_user_config_json["develop_accout_info"]["dev_cert_decrypt_password"]
323
+ end
324
+ return pass
325
+ end
326
+
300
327
  def demo_apple_id
301
328
  url = ''
302
329
  if !@pindo_user_config_json.nil? && !@pindo_user_config_json["develop_accout_info"].nil?
@@ -45,7 +45,6 @@ module Pindo
45
45
 
46
46
  def all_tool_bundleid
47
47
  setting_file = File.join(pindo_single_config.pindo_env_configdir,'bundleid_config.json')
48
- puts setting_file
49
48
  setting_json = load_setting(setting_file:setting_file)
50
49
  sub_json = []
51
50
  if !setting_json.nil? && !setting_json['all_tool_bundleid'].nil?
@@ -86,10 +85,10 @@ module Pindo
86
85
  puts "具体参考文档: https://tower.im/teams/851356/repository_documents/714/"
87
86
  puts ""
88
87
  puts "App Type:"
89
-
88
+ puts
90
89
  cli.choose do |menu| # you can also use constants like :blue
91
- menu.header = "选用哪个bundle id?"
92
- menu.prompt = "请选择使用的bundle id,请输入选项(1/2/3...):"
90
+ menu.header = "可用的Bundle Id如下:"
91
+ menu.prompt = "请选择使用的Bundle Id,请输入选项(1/2/3...):"
93
92
  menu.index_suffix = ") "
94
93
  if !sub_setting_json.nil?
95
94
  sub_setting_json.each do |key, items|
@@ -115,9 +114,10 @@ module Pindo
115
114
 
116
115
  cli = HighLine.new
117
116
  menu_choice="None"
117
+ puts
118
118
  cli.choose do |menu| # you can also use constants like :blue
119
- menu.header = "选用哪个bundle id?"
120
- menu.prompt = "请选择使用的bundle id,请输入选项(1/2/3...):"
119
+ menu.header = "可用的Bundle Id如下:"
120
+ menu.prompt = "请选择使用的Bundle Id,请输入选项(1/2/3...):"
121
121
  if !all_bundleid.nil? && all_bundleid.length > 0
122
122
  for bunld_id in all_bundleid do
123
123
  menu.choice(bunld_id) do |details|
@@ -140,10 +140,11 @@ module Pindo
140
140
 
141
141
  cli = HighLine.new
142
142
  menu_choice="None"
143
+ puts
143
144
  cli.choose do |menu| # you can also use constants like :blue
144
145
 
145
- menu.header = "选用哪个bundle id?"
146
- menu.prompt = "请选择使用的bundle id,请输入选项(1/2/3...):"
146
+ menu.header = "可用的Bundle Id如下:"
147
+ menu.prompt = "请选择使用的Bundle Id,请输入选项(1/2/3...):"
147
148
  if !all_bundleid.nil? && all_bundleid.length > 0
148
149
  for bunld_id in all_bundleid do
149
150
  menu.choice(bunld_id) do |details|
@@ -9,11 +9,7 @@ require 'pindo/module/cert/provisioninghelper'
9
9
  module Pindo
10
10
 
11
11
  module CertHelper
12
-
13
- def server_name(keychain_name)
14
- ["match", keychain_name].join("_")
15
- end
16
-
12
+
17
13
  def get_cert_info(cer_certificate)
18
14
  # can receive a certificate path or the file data
19
15
  begin
@@ -65,7 +61,7 @@ module Pindo
65
61
  (/darwin/ =~ RUBY_PLATFORM) != nil
66
62
  end
67
63
 
68
- def install_certs(certs_dir:nil, cert_type:nil)
64
+ def install_certs(cert_url:nil, certs_dir:nil, cert_type:nil)
69
65
 
70
66
 
71
67
  if !cert_type.downcase.include?("development")
@@ -79,45 +75,59 @@ module Pindo
79
75
  raise Informative, "No certificates found in #{certs_dir}"
80
76
  else
81
77
  output_dir = Dir.mktmpdir
82
- decrypt_password = "Gxtest#1"
83
-
78
+
79
+ decrypt_password = AESHelper.fetch_password(keychain_name:cert_url)
84
80
  Funlog.instance.fancyinfo_start("正在安装证书...")
85
81
 
86
82
  cert_path = AESHelper.decrypt_specific_file(src_file: certs.first, password:decrypt_password, output_dir: output_dir)
83
+ unless cert_path.nil? || File.exist?(cert_path)
84
+ AESHelper.delete_password(keychain_name:cert_url)
85
+ raise Informative, "证书解析失败,密码错误!"
86
+ end
87
+
87
88
  key_path = AESHelper.decrypt_specific_file(src_file: keys.first, password:decrypt_password, output_dir: output_dir)
89
+ unless key_path.nil? || File.exist?(key_path)
90
+ AESHelper.delete_password(keychain_name:cert_url)
91
+ raise Informative, "证书解析失败,密码错误!"
92
+ end
88
93
 
89
94
  unless is_cert_valid?(cert_path)
90
- raise Informative, "Your certificate '#{File.basename(cert_path)}' is not valid, please check end date and renew it if necessary"
95
+ raise Informative, "证书已经过期,请重新生产新证书!"
91
96
  end
92
97
 
98
+
93
99
  if isMac?
94
100
 
95
101
  keychain_name = "login.keychain"
96
-
97
102
  if FastlaneCore::CertChecker.installed?(cert_path, in_keychain: nil)
98
103
  Funlog.instance.fancyinfo_success("证书#{File.basename(cert_path)}已安装,无需重复安装!")
99
104
  else
100
- cert_password = "goodcert1"
105
+
106
+ cert_password = Pindoconfig.instance.cert_key_password
101
107
  keychain = 'login.keychain'
102
108
  keychain_path = FastlaneCore::Helper.keychain_path(keychain)
103
109
 
104
- KeychainHelper.import_file(cert_path, keychain_path, keychain_password: cert_password, certificate_password: "", skip_set_partition_list: false, output: false)
105
- KeychainHelper.import_file(key_path, keychain_path, keychain_password: cert_password, certificate_password: "", skip_set_partition_list: false, output: false)
110
+ KeychainHelper.import_file(cert_path, keychain_path, keychain_password: cert_password, certificate_password:'' )
111
+ KeychainHelper.import_file(key_path, keychain_path, keychain_password: cert_password, certificate_password: '')
106
112
 
107
113
 
108
114
  Funlog.instance.fancyinfo_success("证书'#{File.basename(cert_path)}'安装完成!")
109
115
  end
110
116
  else
111
- puts "非Mac电脑不支持安装证书."
117
+ Funlog.instance.fancyinfo_error("非Mac电脑不支持安装证书!")
112
118
  end
113
119
 
114
120
  end
115
121
 
116
- def install_provisionfiles(certs_dir:nil, bundle_id_map:nil, cert_type:nil)
122
+ def install_provisionfiles(cert_url:nil, certs_dir:nil, bundle_id_map:nil, cert_type:nil)
123
+
124
+
125
+ Funlog.instance.fancyinfo_start("正在安装Provisioning Profiles文件...")
126
+
117
127
 
118
128
  if cert_type.downcase.include?("development")
119
129
  cert_type = "Development"
120
- elsif cert_type.downcase.include?("Adhoc")
130
+ elsif cert_type.downcase.include?("adhoc")
121
131
  cert_type = "Adhoc"
122
132
  else
123
133
  cert_type = "AppStore"
@@ -133,13 +143,12 @@ module Pindo
133
143
 
134
144
  bundle_id_map.each do |type, bundle_id_temp|
135
145
  profile_filename = File.join(certs_dir, "profiles", cert_type.downcase.to_s,[cert_type.to_s, bundle_id_temp].join('_') + '.mobileprovision')
136
-
137
146
  unless File.exist?(profile_filename)
138
147
  un_exist_files << profile_filename
139
148
  next
140
149
  end
141
- puts "正在安装 #{profile_filename}..."
142
- decrypt_password = "Gxtest#1"
150
+ # puts "正在安装 #{bundle_id_temp}..."
151
+ decrypt_password = AESHelper.fetch_password(keychain_name:cert_url)
143
152
  output_dir = Dir.mktmpdir
144
153
  file_decrypt = AESHelper.decrypt_specific_file(src_file: profile_filename, password:decrypt_password, output_dir: output_dir)
145
154
  destpath = Provisioninghelper.install(file_decrypt)
@@ -151,17 +160,19 @@ module Pindo
151
160
  provisioning_info['profile_name'] = parsed_data['Name']
152
161
  provisioning_info['profile_path'] = destpath
153
162
 
163
+
154
164
  cert_info = get_cert_info(parsed_data["DeveloperCertificates"].first.string).to_h
155
165
  provisioning_info['signing_identity'] = cert_info["Common Name"]
156
166
  provisioning_info['team_id'] = parsed_data["TeamIdentifier"].first
157
167
 
158
- puts JSON.pretty_generate(provisioning_info)
168
+ # puts JSON.pretty_generate(provisioning_info)
159
169
  provisioning_info_array << provisioning_info
160
170
  end
161
171
 
162
-
172
+ Funlog.instance.fancyinfo_success("Provisioning Profiles文件安装完成!")
163
173
 
164
174
  if un_exist_files.size > 0
175
+ Funlog.instance.fancyinfo_error("证书Provisioning Profiles文件不存在!")
165
176
  raise Informative, "The following profiles do not exist: #{un_exist_files.join(', ')}"
166
177
  end
167
178
 
@@ -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
- puts "Could not find file '#{path}'" unless File.exist?(path)
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
- sensitive_command = command.gsub(password_part, " -P ********")
23
- UI.command(sensitive_command) if output
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("'#{File.basename(path)}' is already installed on this machine")
41
+ # UI.verbose("'}' is already installed on this machine")
42
+ # puts "证书key已经存在,安装完成!"
36
43
  else
37
- raise Informative, err
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
- UI.command(sensitive_command) if output
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
- raise Informative, err
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
- ["fastlane", "keychain", keychain_name].join("_")
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