fastlane-plugin-apprepo 0.1.0 → 0.2.0

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.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/.coveralls.yml +2 -0
  3. data/.gitignore +0 -0
  4. data/.rspec +3 -0
  5. data/.rubocop.yml +4 -0
  6. data/Gemfile +7 -1
  7. data/README.md +9 -2
  8. data/assets/RepofileDefault +34 -0
  9. data/assets/apprepo.png +0 -0
  10. data/assets/circle.key +27 -0
  11. data/assets/fastlane.png +0 -0
  12. data/assets/manifest.png +0 -0
  13. data/circle.yml +11 -9
  14. data/coverage/.last_run.json +5 -0
  15. data/coverage/.resultset.json +1244 -0
  16. data/coverage/.resultset.json.lock +0 -0
  17. data/fastlane-plugin-apprepo.gemspec +6 -2
  18. data/fastlane/Appfile +1 -0
  19. data/fastlane/Fastfile +42 -0
  20. data/fastlane/Pluginfile +1 -0
  21. data/fastlane/Repofile +33 -0
  22. data/greeter.rb +6 -0
  23. data/lib/fastlane/plugin/apprepo.rb +26 -7
  24. data/lib/fastlane/plugin/apprepo/actions/apprepo_action.rb +106 -92
  25. data/lib/fastlane/plugin/apprepo/actions/download_manifest.rb +40 -0
  26. data/lib/fastlane/plugin/apprepo/actions/init.rb +46 -0
  27. data/lib/fastlane/plugin/apprepo/actions/rubocop.rb +29 -0
  28. data/lib/fastlane/plugin/apprepo/actions/run.rb +69 -0
  29. data/lib/fastlane/plugin/apprepo/actions/submit.rb +41 -0
  30. data/lib/fastlane/plugin/apprepo/analyser.rb +35 -0
  31. data/lib/fastlane/plugin/apprepo/command.rb +17 -0
  32. data/lib/fastlane/plugin/apprepo/commands_generator.rb +121 -0
  33. data/lib/fastlane/plugin/apprepo/detect_values.rb +29 -0
  34. data/lib/fastlane/plugin/apprepo/helper/analyser.rb +35 -0
  35. data/lib/fastlane/plugin/apprepo/helper/commands_generator.rb +121 -0
  36. data/lib/fastlane/plugin/apprepo/helper/detect_values.rb +29 -0
  37. data/lib/fastlane/plugin/apprepo/helper/loader.rb +15 -0
  38. data/lib/fastlane/plugin/apprepo/helper/manifest.rb +44 -0
  39. data/lib/fastlane/plugin/apprepo/helper/options.rb +120 -0
  40. data/lib/fastlane/plugin/apprepo/helper/runner.rb +68 -0
  41. data/lib/fastlane/plugin/apprepo/helper/setup.rb +49 -0
  42. data/lib/fastlane/plugin/apprepo/helper/uploader.rb +301 -0
  43. data/lib/fastlane/plugin/apprepo/loader.rb +15 -0
  44. data/lib/fastlane/plugin/apprepo/manifest.rb +44 -0
  45. data/lib/fastlane/plugin/apprepo/options.rb +120 -0
  46. data/lib/fastlane/plugin/apprepo/runner.rb +68 -0
  47. data/lib/fastlane/plugin/apprepo/setup.rb +49 -0
  48. data/lib/fastlane/plugin/apprepo/uploader.rb +301 -0
  49. data/lib/fastlane/plugin/apprepo/version.rb +4 -3
  50. data/manifest.json +10 -0
  51. data/sampleapp.ipa +1 -0
  52. data/test +0 -0
  53. metadata +46 -2
@@ -0,0 +1,15 @@
1
+ require 'fastlane_core/languages'
2
+
3
+ module Fastlane
4
+ module Apprepo
5
+ # Responsible for loading language folders
6
+ module Loader
7
+ def self.language_folders(root)
8
+ Dir.glob(File.join(root, '*')).select do |path|
9
+ all = ALL_LANGUAGES.include?(File.basename(path).downcase)
10
+ File.directory?(path) && all
11
+ end.sort
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,44 @@
1
+ require 'json'
2
+
3
+ module Fastlane
4
+ module Apprepo
5
+ # Responsible for parsing and providing manifest.json
6
+ class Manifest
7
+ #
8
+ # Translated internal key names from Fastlane to Apprepo
9
+ #
10
+
11
+ attr_accessor :appcode # Apprepo Internal Code
12
+ attr_accessor :filename # IPA file name
13
+ attr_accessor :bundle_identifier # app_identifier
14
+ attr_accessor :bundle_version # app_version
15
+ attr_accessor :title # app_name
16
+ attr_accessor :subtitle # app_description
17
+ attr_accessor :notify # will send push notification / slack
18
+
19
+ def initialize(appcode)
20
+ self.appcode = appcode
21
+ UI.message('Initializing requires APPCODE. ' + self.appcode)
22
+ end
23
+
24
+ def parse_json(json)
25
+ # TODO: load values from JSON
26
+ end
27
+
28
+ # Provide JSON serialized data
29
+ def manifest_as_json
30
+ structure = {
31
+ appcode: appcode,
32
+ filename: filename,
33
+ bundle_identifier: bundle_identifier,
34
+ bundle_version: bundle_version,
35
+ title: title,
36
+ subtitle: subtitle,
37
+ notify: notify
38
+ }
39
+
40
+ fputs structure
41
+ end
42
+ end
43
+ end
44
+ end
@@ -0,0 +1,120 @@
1
+ require 'fastlane_core'
2
+
3
+ module Fastlane
4
+ module Apprepo
5
+ # Provides available options for the commands generator
6
+ class Options
7
+ # rubocop:disable Metrics/AbcSize
8
+ def self.available_options
9
+ [
10
+ FastlaneCore::ConfigItem.new(key: :ipa,
11
+ short_option: '-i',
12
+ optional: true,
13
+ env_name: 'Apprepo_IPA_PATH',
14
+ description: 'Path to your ipa file',
15
+ default_value: Dir['*.ipa'].first,
16
+ verify_block: proc do |value|
17
+ UI.user_error!("Could not find ipa file at path '#{value}'") unless File.exist?(value)
18
+ UI.user_error!("'#{value}' doesn't seem to be an ipa file") unless value.end_with?('.ipa')
19
+ end),
20
+ FastlaneCore::ConfigItem.new(key: :app_identifier,
21
+ short_option: '-b',
22
+ optional: false,
23
+ env_name: 'Apprepo_APP_ID',
24
+ description: 'Your bundle identifier',
25
+ default_value: ''),
26
+ FastlaneCore::ConfigItem.new(key: :app_code,
27
+ short_option: '-c',
28
+ optional: true,
29
+ env_name: 'Apprepo_APPCODE',
30
+ description: 'APPCODE value for Apprepo'),
31
+ FastlaneCore::ConfigItem.new(key: :repo_url,
32
+ short_option: '-r',
33
+ optional: false,
34
+ env_name: 'Apprepo_URL',
35
+ description: 'URL of your Apprepo server'),
36
+ FastlaneCore::ConfigItem.new(key: :repo_user,
37
+ short_option: '-u',
38
+ optional: false,
39
+ env_name: 'Apprepo_USER',
40
+ description: 'USER of your Apprepo server'),
41
+ FastlaneCore::ConfigItem.new(key: :repo_password,
42
+ short_option: '-p',
43
+ optional: true,
44
+ env_name: 'Apprepo_PASSWORD',
45
+ description: 'PASSWORD for your Apprepo server (not for production)',
46
+ conflicting_options: [:repo_key],
47
+ conflict_block: proc do |value|
48
+ UI.user_error!("You can't use 'password' and '#{value.key}' options in one run.")
49
+ end),
50
+ FastlaneCore::ConfigItem.new(key: :repo_key,
51
+ short_option: '-k',
52
+ optional: false,
53
+ env_name: 'Apprepo_KEY',
54
+ description: 'RSA key for your Apprepo server',
55
+ conflicting_options: [:repo_password],
56
+ conflict_block: proc do |value|
57
+ UI.user_error!("You can't use 'repo_key' and '#{value.key}' options in one run.")
58
+ end),
59
+ FastlaneCore::ConfigItem.new(key: :repo_description,
60
+ short_option: '-d',
61
+ optional: true,
62
+ description: 'Long detailed description for your Apprepo server',
63
+ default_value: ''),
64
+ FastlaneCore::ConfigItem.new(key: :repo_summary,
65
+ short_option: '-s',
66
+ optional: true,
67
+ description: 'Short description for your Apprepo server',
68
+ default_value: ''),
69
+ FastlaneCore::ConfigItem.new(key: :manifest_path,
70
+ short_option: '-m',
71
+ description: 'Path to the folder containing the metadata files',
72
+ optional: true),
73
+ FastlaneCore::ConfigItem.new(key: :repo_title,
74
+ short_option: '-a',
75
+ description: 'Title of the app',
76
+ optional: false),
77
+ FastlaneCore::ConfigItem.new(key: :appcode,
78
+ short_option: '-o',
79
+ description: 'Name of the app on Apprepo',
80
+ optional: false),
81
+ FastlaneCore::ConfigItem.new(key: :skip_binary_upload,
82
+ description: 'Skip uploading an ipa or to Apprepo',
83
+ is_string: false,
84
+ default_value: false),
85
+ FastlaneCore::ConfigItem.new(key: :app_version,
86
+ short_option: '-z',
87
+ description: 'The version that should be edited or created',
88
+ optional: true),
89
+ FastlaneCore::ConfigItem.new(key: :skip_manifest,
90
+ description: "Don't upload the metadata (e.g. title, description), this will still upload screenshots",
91
+ is_string: false,
92
+ default_value: false),
93
+ FastlaneCore::ConfigItem.new(key: :notify,
94
+ description: 'Notify Apprepo users on update',
95
+ is_string: false,
96
+ default_value: false),
97
+ FastlaneCore::ConfigItem.new(key: :build_number,
98
+ short_option: '-n',
99
+ description: 'If set the given build number (already uploaded to iTC) will be used instead of the current built one',
100
+ optional: true,
101
+ conflicting_options: [:ipa],
102
+ conflict_block: proc do |value|
103
+ UI.user_error!("You can't use 'build_number' and '#{value.key}' options in one run.")
104
+ end),
105
+
106
+ # App Metadata
107
+ # Non Localised
108
+ FastlaneCore::ConfigItem.new(key: :app_icon,
109
+ description: 'Metadata: The path to the app icon',
110
+ optional: true,
111
+ short_option: '-l',
112
+ verify_block: proc do |value|
113
+ UI.user_error!("Could not find png file at path '#{value}'") unless File.exist?(value)
114
+ UI.user_error!("'#{value}' doesn't seem to be a png file") unless value.end_with?('.png')
115
+ end)
116
+ ]
117
+ end
118
+ end
119
+ end
120
+ end
@@ -0,0 +1,68 @@
1
+ require_relative 'uploader'
2
+
3
+ module Fastlane
4
+ module Apprepo
5
+ # Responsible for running
6
+ class Runner
7
+ attr_accessor :options
8
+
9
+ def initialize(options)
10
+ self.options = options
11
+ Apprepo::DetectValues.new.run!(self.options)
12
+ FastlaneCore::PrintTable.print_values(config: options, hide_keys: [:repo_password], mask_keys: [:repo_key], title: "Apprepo-sftp #{Apprepo::VERSION} Summary")
13
+ end
14
+
15
+ # rubocop:disable Metrics/AbcSize
16
+ # rubocop:disable Metrics/CyclomaticComplexity
17
+ def run
18
+ UI.success('Apprepo SFTP Uploader running...')
19
+ verify_version unless options[:app_version].to_s.empty?
20
+ has_binary = options[:ipa]
21
+ if !options[:skip_binary_upload] && !options[:build_number] && has_binary
22
+ upload_binary
23
+ end
24
+ UI.success('Finished the upload to Apprepo.')
25
+ notify unless options[:notify].nil?
26
+ end
27
+
28
+ # Make sure the version on Apprepo matches the one in the ipa
29
+ # If not, the new version will automatically be created
30
+ def verify_version
31
+ app_version = options[:app_version]
32
+ msg = "TODO: Test if Apprepo matches '#{app_version}' from the IPA..."
33
+ UI.message(msg)
34
+
35
+ # changed = options[:app].ensure_version!(app_version)
36
+ # if changed
37
+ # UI.success("Successfully set the version to '#{app_version}'")
38
+ # else
39
+ # UI.success("'#{app_version}' is the latest version on Apprepo")
40
+ # end
41
+ end
42
+
43
+ def download_manifest
44
+ if options[:manifest_path]
45
+ uploader = Apprepo::Uploader.new(options)
46
+ result = uploader.download_manifest_only
47
+ msg = 'Metadata download failed. Check out the error above.'
48
+ UI.user_error!(msg) unless result
49
+ end
50
+ end
51
+
52
+ # Upload the binary to Apprepo
53
+ def upload_binary
54
+ if options[:ipa]
55
+ uploader = Apprepo::Uploader.new(options)
56
+ result = uploader.upload
57
+ msg = 'Binary upload failed. Check out the error above.'
58
+ UI.user_error!(msg) unless result
59
+ end
60
+ end
61
+
62
+ def notify
63
+ # should be in metadata
64
+ UI.command_output('TODO: Missing implementation for Apprepo Push Notifier')
65
+ end
66
+ end
67
+ end
68
+ end
@@ -0,0 +1,49 @@
1
+ module Fastlane
2
+ module Apprepo
3
+ # Responsible for setting up the Repofile configuration
4
+ class Setup
5
+ def setup_Apprepo(file_path, data, _Apprepo_path, _options)
6
+ UI.message('[Apprepo:Setup] Setting up...')
7
+ File.write(file_path, data)
8
+
9
+ # TODO: implement later
10
+ download_manifest(Apprepo_path, options)
11
+
12
+ UI.success("NOT! created new Repofile at path '#{file_path}'")
13
+ end
14
+
15
+ # This method takes care of creating a new 'Apprepo' folder with metadata
16
+ # and screenshots folders
17
+ def generate_Apprepo_file(_Apprepo_path, options)
18
+ # v = options[:app].latest_version
19
+ # generate_Apprepo_file(v, File.join(Apprepo_path, 'manifest.json'))
20
+
21
+ # Generate the final Repofile here
22
+ gem_path = Helper.gem_path('Apprepo')
23
+ Apprepo = File.read("#{gem_path}/../assets/RepofileDefault")
24
+ Apprepo.gsub!('[[APP_IDENTIFIER]]', options[:app].bundle_id)
25
+ Apprepo.gsub!('[[Apprepo_IPA_PATH]]', options[:app].file_path)
26
+ Apprepo.gsub!('[[APP_VERSION]]', options[:app].version)
27
+ Apprepo.gsub!('[[APP_NAME]]', options[:app].name)
28
+ # Apprepo (was deliver)
29
+ end
30
+
31
+ def download_manifest(Apprepo_path, _options)
32
+ path = File.join(Apprepo_path, 'metadata')
33
+ FileUtils.mkdir_p(path)
34
+ UI.success("TODO: DOWNLOAD MANIFEST'")
35
+ Apprepo::Uploader.new(options).download_manifest_only
36
+ end
37
+
38
+ def run(options)
39
+ UI.message('[Apprepo:Setup] Running...')
40
+ containing = (File.directory?('fastlane') ? 'fastlane' : '.')
41
+ file_path = File.join(containing, 'Repofile')
42
+ data = generate_Apprepo_file(containing, options)
43
+ setup_Apprepo(file_path, data, containing, options)
44
+ end
45
+ end
46
+ end
47
+
48
+ # @setup = new Apprepo::Setup
49
+ end
@@ -0,0 +1,301 @@
1
+ #!/usr/bin/env ruby
2
+
3
+ require 'rubygems'
4
+ require 'json'
5
+ require 'net/ssh'
6
+ require 'net/sftp'
7
+ require 'fastlane_core'
8
+ require 'fastlane_core/languages'
9
+
10
+ require_relative 'options'
11
+
12
+ module Fastlane
13
+ module Apprepo
14
+ # rubocop:disable Metrics/ClassLength
15
+
16
+ # Responsible for performing the SFTP operation
17
+ class Uploader
18
+ attr_accessor :options
19
+
20
+ #
21
+ # These want to be an input parameters:
22
+ #
23
+
24
+ attr_accessor :host
25
+ attr_accessor :user
26
+ attr_accessor :password
27
+ attr_accessor :rsa_keypath
28
+ attr_accessor :ipa_path
29
+ attr_accessor :manifest_path
30
+ attr_accessor :appcode
31
+
32
+ # rubocop:disable Metrics/AbcSize
33
+ # rubocop:disable Metrics/MethodLength
34
+ def initialize(options)
35
+ self.options = options unless options.nil?
36
+ self.host = options[:repo_url] # 'repo.teacloud.net'
37
+ self.user = options[:repo_user]
38
+ self.password = options[:repo_password]
39
+ self.rsa_keypath = options[:repo_key] # '../assets/circle.key'
40
+ self.ipa_path = options[:ipa] # '../sampleapp.ipa'
41
+ self.manifest_path = options[:manifest_path] # '../assets/example_manifest.json'
42
+ self.appcode = options[:appcode]
43
+
44
+ # Apprepo::Uploader.new.run!
45
+ # FastlaneCore::PrintTable.print_values(config: nil , hide_keys: [:app],
46
+ # mask_keys: ['app_review_information.demo_password'],
47
+ # title: "deliver #{Apprepo::VERSION} Summary") # options
48
+ end
49
+
50
+ #
51
+ # Upload IPA & manifest
52
+ #
53
+
54
+ # rubocop:disable Metrics/AbcSize
55
+ # rubocop:disable Metrics/MethodLength
56
+ def upload
57
+ # Login & Upload IPA with metadata using RSA key or username/password
58
+ FastlaneCore::UI.message('upload...')
59
+
60
+ if host.nil? || user.nil?
61
+ FastlaneCore::UI.user_error('repo_url, repo_user and repo_pasdword or repo_key must be set on upload')
62
+ return false
63
+ end
64
+
65
+ if rsa_keypath
66
+ rsa_key = load_rsa_key(rsa_keypath)
67
+ if rsa_key.nil?
68
+ FastlaneCore::UI.user_error('Failed to load RSA key... ' + options[:rsa_keypath])
69
+ end
70
+ end
71
+
72
+ success = false
73
+ if !rsa_key.nil?
74
+ FastlaneCore::UI.message('Logging in with RSA key...')
75
+ Net::SSH.start(host, user, key_data: rsa_key, keys_only: true) do |ssh|
76
+ FastlaneCore::UI.message('Uploading IPA & Manifest...')
77
+ success = ssh_sftp_upload(ssh, ipa_path, manifest_path)
78
+ end
79
+ else
80
+ FastlaneCore::UI.message('Logging in with username/password...')
81
+ Net::SSH.start(host, user, password: password) do |ssh|
82
+ FastlaneCore::UI.message('Uploading IPA & Manifest...')
83
+ success = ssh_sftp_upload(ssh, ipa_path, manifest_path)
84
+ end
85
+ end
86
+ success
87
+ end
88
+
89
+ #
90
+ # Download metadata only
91
+ #
92
+
93
+ # rubocop:disable Metrics/AbcSize
94
+ # rubocop:disable Metrics/MethodLength
95
+ def download_manifest_only
96
+ FastlaneCore::UI.message('download_manifest_only...')
97
+ rsa_key = load_rsa_key(rsa_keypath)
98
+ success = true
99
+ if !rsa_key.nil?
100
+ FastlaneCore::UI.message('Logging in with RSA key for download...')
101
+ Net::SSH.start(host, user, key_data: rsa_key, keys_only: true) do |ssh|
102
+ FastlaneCore::UI.message('Uploading UPA & Manifest...')
103
+ success = ssh_sftp_download(ssh, manifest_path)
104
+ end
105
+ else
106
+ FastlaneCore::UI.message('Logging in for download...')
107
+ Net::SSH.start(host, user, password: password) do |ssh|
108
+ FastlaneCore::UI.message('Uploading UPA & Manifest...')
109
+ success = ssh_sftp_download(ssh, manifest_path)
110
+ end
111
+ end
112
+ success
113
+ end
114
+
115
+ private
116
+
117
+ def ssh_sftp_download(ssh, _manifest_path)
118
+ ssh.sftp.connect do |sftp|
119
+ FastlaneCore::UI.message('Fetching remote manifest...')
120
+ manifest = download_manifest(sftp)
121
+ puts '********************************************************'
122
+ puts JSON.pretty_generate(manifest)
123
+ puts '********************************************************'
124
+ FastlaneCore::UI.success('Successfully fetched manifest')
125
+ FastlaneCore::UI.command_output('TODO: Processing manifest not implemented.')
126
+ end
127
+ end
128
+
129
+ def ssh_sftp_upload(ssh, local_ipa_path, manifest_path)
130
+ ssh.sftp.connect do |sftp|
131
+ break unless check_ipa(local_ipa_path)
132
+ check_appcode(sftp, appcode)
133
+ path = remote_path(appcode)
134
+ manifest = download_manifest(sftp)
135
+ puts JSON.pretty_generate(manifest) unless manifest.nil?
136
+ bump_ipa(sftp, local_ipa_path, appcode)
137
+ remote_ipa_path = get_remote_ipa_path(local_ipa_path, appcode)
138
+ upload_ipa(sftp, local_ipa_path, remote_ipa_path)
139
+ upload_manifest(sftp, manifest_path, remote_manifest_path(appcode))
140
+ # Lists the entries in a directory for verification
141
+ sftp.dir.foreach(path) do |entry|
142
+ FastlaneCore::UI.message(entry.longname)
143
+ end
144
+ end
145
+ end
146
+
147
+ # Check IPA existence locally
148
+ #
149
+ # @param local_ipa_path
150
+ def check_ipa(local_ipa_path)
151
+ if File.exist?(local_ipa_path)
152
+ FastlaneCore::UI.important('IPA found at ' + local_ipa_path)
153
+ return true
154
+ else
155
+ FastlaneCore::UI.verbose('IPA at given path does not exist yet.')
156
+ return false
157
+ end
158
+ end
159
+
160
+ # Private methods - Remote Operations
161
+
162
+ # Checks/creates remote APPCODE directory
163
+ # @param sftp
164
+ # @param [String] appcode
165
+ def check_appcode(sftp, appcode)
166
+ path = remote_path(appcode)
167
+ FastlaneCore::UI.message('Checking APPCODE')
168
+ remote_mkdir(sftp, path)
169
+ end
170
+
171
+ # Checks/renames remote IPA
172
+ #
173
+ # @params sftp
174
+ # @params [String] local_ipa_path
175
+ def bump_ipa(sftp, local, appcode)
176
+ remote = get_remote_ipa_path(local, appcode)
177
+ FastlaneCore::UI.message('Checking remote IPA')
178
+ begin
179
+ sftp.stat!(remote) do |response|
180
+ if response.ok?
181
+ begin
182
+ sftp.rename!(remote, remote + '.bak')
183
+ rescue
184
+ begin
185
+ sftp.remove(remote + '.bak') # may fail if not existent
186
+ FastlaneCore::UI.message('Removed ' + remote + '.bak')
187
+ rescue
188
+ sftp.rename!(remote, remote + '.bak')
189
+ FastlaneCore::UI.message('Bumped to ' + remote + '.bak')
190
+ end
191
+ end
192
+ end
193
+ end
194
+ rescue
195
+ FastlaneCore::UI.message('No previous IPA found.')
196
+ end
197
+ end
198
+
199
+ # Downloads remote manifest, self.appcode required by options.
200
+ #
201
+ # @param sftp
202
+ # @param [String] remote_path
203
+ # @returns [JSON] json or nil
204
+ def download_manifest(sftp)
205
+ FastlaneCore::UI.message('Checking remote Manifest')
206
+ json = nil
207
+ remote_manifest_path = remote_manifest_path(appcode)
208
+ begin
209
+ sftp.stat!(remote_manifest_path) do |response|
210
+ if response.ok?
211
+ FastlaneCore::UI.success('Loading remote manifest:')
212
+ manifest = sftp.download!(remote_manifest_path)
213
+ json = JSON.parse(manifest)
214
+ end
215
+ end
216
+ rescue
217
+ FastlaneCore::UI.message('No previous Manifest found')
218
+ end
219
+ json
220
+ end
221
+
222
+ # Upload current IPA
223
+ #
224
+ # @param sftp
225
+ # @param [String] local_ipa_path
226
+ # @param [String] remote_ipa_path
227
+ def upload_ipa(sftp, local_ipa_path, remote_ipa_path)
228
+ msg = "[Uploading IPA] #{local_ipa_path} to #{remote_ipa_path}"
229
+ FastlaneCore::UI.message(msg)
230
+ result = sftp.upload!(local_ipa_path, remote_ipa_path) do |event, _uploader, *_args|
231
+ case event
232
+ when :open then
233
+ putc '.'
234
+ when :put then
235
+ putc '.'
236
+ $stdout.flush
237
+ when :close then
238
+ puts "\n"
239
+ when :finish then
240
+ FastlaneCore::UI.success('IPA upload successful')
241
+ end
242
+ end
243
+ end
244
+
245
+ # Upload current manifest.json
246
+ #
247
+ # @param sftp
248
+ # @param [String] manifest_path
249
+ # @param [String] remote_manifest_path
250
+ def upload_manifest(sftp, local_path, remote_path)
251
+ msg = '[Uploading Manifest] ' + local_path + ' to ' + remote_path
252
+ FastlaneCore::UI.message(msg)
253
+ result = sftp.upload!(local_path, remote_path) do |event, _uploader, *_args|
254
+ case event
255
+ when :finish then
256
+ FastlaneCore::UI.success('Manifest upload successful')
257
+ end
258
+ end
259
+ end
260
+
261
+ def get_remote_ipa_path(local_ipa_path, appcode)
262
+ remote_path(appcode) + File.basename(local_ipa_path)
263
+ end
264
+
265
+ def remote_path(appcode)
266
+ generate_remote_path + appcode + '/'
267
+ end
268
+
269
+ def remote_manifest_path(appcode)
270
+ remote_manifest_path = remote_path(appcode) + 'manifest.json'
271
+ end
272
+
273
+ def generate_remote_path
274
+ '/home/' + user + '/repo/apps/'
275
+ end
276
+
277
+ def remote_mkdir(sftp, remote_path)
278
+ sftp.mkdir remote_path
279
+ rescue Net::SFTP::StatusException => e
280
+ raise if e.code != 11
281
+ msg = "Remote dir #{remote_path} exists."
282
+ FastlaneCore::UI.message(msg)
283
+ end
284
+
285
+ # Private methods - Local Operations
286
+
287
+ def load_rsa_key(rsa_keypath)
288
+ File.open(rsa_keypath, 'r') do |file|
289
+ rsa_key = nil
290
+ rsa_key = [file.read]
291
+ if !rsa_key.nil?
292
+ FastlaneCore::UI.success('Successfully loaded RSA key...')
293
+ else
294
+ FastlaneCore::UI.user_error!('Failed to load RSA key...')
295
+ end
296
+ rsa_key
297
+ end
298
+ end
299
+ end
300
+ end
301
+ end