fastlane-plugin-apprepo 0.5.4 → 0.5.5

Sign up to get free protection for your applications and to get access to all the features.
@@ -1,15 +0,0 @@
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
@@ -1,44 +0,0 @@
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
@@ -1,120 +0,0 @@
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
@@ -1,71 +0,0 @@
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
- UI.success('Finished the upload to Apprepo.')
24
- else
25
- UI.success('Binary upload skipped or no binary available.')
26
- end
27
-
28
- notify unless options[:notify].nil?
29
- end
30
-
31
- # Make sure the version on Apprepo matches the one in the ipa
32
- # If not, the new version will automatically be created
33
- def verify_version
34
- app_version = options[:app_version]
35
- msg = "TODO: Test if Apprepo matches '#{app_version}' from the IPA..."
36
- UI.message(msg)
37
-
38
- # changed = options[:app].ensure_version!(app_version)
39
- # if changed
40
- # UI.success("Successfully set the version to '#{app_version}'")
41
- # else
42
- # UI.success("'#{app_version}' is the latest version on Apprepo")
43
- # end
44
- end
45
-
46
- def download_manifest
47
- if options[:manifest_path]
48
- uploader = Apprepo::Uploader.new(options)
49
- result = uploader.download_manifest_only
50
- msg = 'Metadata download failed. Check out the error above.'
51
- UI.user_error!(msg) unless result
52
- end
53
- end
54
-
55
- # Upload the binary to Apprepo
56
- def upload_binary
57
- if options[:ipa]
58
- uploader = Apprepo::Uploader.new(options)
59
- result = uploader.upload
60
- msg = 'Binary upload failed. Check out the error above.'
61
- UI.user_error!(msg) unless result
62
- end
63
- end
64
-
65
- def notify
66
- # should be in metadata
67
- # UI.command_output('TODO: Missing implementation for Apprepo Push Notifier')
68
- end
69
- end
70
- end
71
- end
@@ -1,49 +0,0 @@
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
@@ -1,306 +0,0 @@
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 :port
26
- attr_accessor :user
27
- attr_accessor :password
28
- attr_accessor :rsa_keypath
29
- attr_accessor :ipa_path
30
- attr_accessor :manifest_path
31
- attr_accessor :appcode
32
-
33
- # rubocop:disable Metrics/AbcSize
34
- # rubocop:disable Metrics/MethodLength
35
- def initialize(options)
36
- self.options = options unless options.nil?
37
- self.host = options[:repo_url]
38
- self.port = options[:repo_port]
39
- self.user = options[:repo_user]
40
- self.password = options[:repo_password]
41
- self.rsa_keypath = options[:repo_key] # '../assets/circle.key'
42
- self.ipa_path = options[:ipa] # '../sampleapp.ipa'
43
- self.manifest_path = options[:manifest_path] # '../assets/example_manifest.json'
44
- self.appcode = options[:appcode]
45
-
46
- # Apprepo::Uploader.new.run!
47
- # FastlaneCore::PrintTable.print_values(config: nil , hide_keys: [:app],
48
- # mask_keys: ['app_review_information.demo_password'],
49
- # title: "deliver #{Apprepo::VERSION} Summary") # options
50
- end
51
-
52
- #
53
- # Upload IPA & manifest
54
- #
55
-
56
- # rubocop:disable Metrics/AbcSize
57
- # rubocop:disable Metrics/MethodLength
58
- def upload
59
- # Login & Upload IPA with metadata using RSA key or username/password
60
- FastlaneCore::UI.message('upload...')
61
-
62
- if host.nil? || user.nil?
63
- FastlaneCore::UI.user_error('repo_url, repo_port, repo_user and repo_password or repo_key must be set on upload')
64
- return false
65
- end
66
-
67
- if rsa_keypath
68
- rsa_key = load_rsa_key(rsa_keypath)
69
- if rsa_key.nil?
70
- FastlaneCore::UI.user_error('Failed to load RSA key... ' + options[:rsa_keypath])
71
- end
72
- end
73
-
74
- success = false
75
- if !rsa_key.nil?
76
- FastlaneCore::UI.message('Logging in with RSA key...')
77
- Net::SSH.start(host, user, port: port, key_data: rsa_key, keys_only: true) do |ssh|
78
- FastlaneCore::UI.message('Uploading IPA & Manifest...')
79
- success = ssh_sftp_upload(ssh, ipa_path, manifest_path)
80
- end
81
- else
82
- FastlaneCore::UI.message('Logging in with username/password...')
83
- Net::SSH.start(host, user, port: port, password: password) do |ssh|
84
- FastlaneCore::UI.message('Uploading IPA & Manifest...')
85
- success = ssh_sftp_upload(ssh, ipa_path, manifest_path)
86
- end
87
- end
88
- success
89
- end
90
-
91
- #
92
- # Download metadata only
93
- #
94
-
95
- # rubocop:disable Metrics/AbcSize
96
- # rubocop:disable Metrics/MethodLength
97
- def download_manifest_only
98
- FastlaneCore::UI.message('download_manifest_only...')
99
- rsa_key = load_rsa_key(rsa_keypath)
100
- success = true
101
- if !rsa_key.nil?
102
- FastlaneCore::UI.message('Logging in with RSA key for download...')
103
- Net::SSH.start(host, user, port: port, key_data: rsa_key, keys_only: true) do |ssh|
104
- FastlaneCore::UI.message('Uploading UPA & Manifest...')
105
- success = ssh_sftp_download(ssh, manifest_path)
106
- end
107
- else
108
- FastlaneCore::UI.message('Logging in for download...')
109
- Net::SSH.start(host, user, port: port, password: password) do |ssh|
110
- FastlaneCore::UI.message('Uploading UPA & Manifest...')
111
- success = ssh_sftp_download(ssh, manifest_path)
112
- end
113
- end
114
- success
115
- end
116
-
117
- private
118
-
119
- def ssh_sftp_download(ssh, _manifest_path)
120
- ssh.sftp.connect do |sftp|
121
- FastlaneCore::UI.message('Fetching remote manifest...')
122
- manifest = download_manifest(sftp)
123
- puts '********************************************************'
124
- puts JSON.pretty_generate(manifest)
125
- puts '********************************************************'
126
- FastlaneCore::UI.success('Successfully fetched manifest')
127
- FastlaneCore::UI.command_output('TODO: Processing manifest not implemented.')
128
- end
129
- end
130
-
131
- def ssh_sftp_upload(ssh, local_ipa_path, manifest_path)
132
- ssh.sftp.connect do |sftp|
133
- break unless check_ipa(local_ipa_path)
134
- check_appcode(sftp, appcode)
135
- path = remote_path(appcode)
136
- manifest = download_manifest(sftp)
137
- puts JSON.pretty_generate(manifest) unless manifest.nil?
138
- bump_ipa(sftp, local_ipa_path, appcode)
139
- remote_ipa_path = get_remote_ipa_path(local_ipa_path, appcode)
140
- FastlaneCore::UI.command_output('Uploading IPA...')
141
- upload_ipa(sftp, local_ipa_path, remote_ipa_path)
142
- FastlaneCore::UI.command_output('Uploading manifest...')
143
- upload_manifest(sftp, manifest_path, remote_manifest_path(appcode))
144
- FastlaneCore::UI.command_output('Verification...')
145
- # Lists the entries in a directory for verification
146
- sftp.dir.foreach(path) do |entry|
147
- FastlaneCore::UI.message(entry.longname)
148
- end
149
- end
150
- end
151
-
152
- # Check IPA existence locally
153
- #
154
- # @param local_ipa_path
155
- def check_ipa(local_ipa_path)
156
- if File.exist?(local_ipa_path)
157
- FastlaneCore::UI.important('IPA found at ' + local_ipa_path)
158
- return true
159
- else
160
- FastlaneCore::UI.verbose('IPA at given path does not exist yet.')
161
- return false
162
- end
163
- end
164
-
165
- # Private methods - Remote Operations
166
-
167
- # Checks/creates remote APPCODE directory
168
- # @param sftp
169
- # @param [String] appcode
170
- def check_appcode(sftp, appcode)
171
- path = remote_path(appcode)
172
- FastlaneCore::UI.message('Checking APPCODE')
173
- remote_mkdir(sftp, path)
174
- end
175
-
176
- # Checks/renames remote IPA
177
- #
178
- # @params sftp
179
- # @params [String] local_ipa_path
180
- def bump_ipa(sftp, local, appcode)
181
- remote = get_remote_ipa_path(local, appcode)
182
- FastlaneCore::UI.message('Checking remote IPA')
183
- begin
184
- sftp.stat!(remote) do |response|
185
- if response.ok?
186
- begin
187
- sftp.rename!(remote, remote + '.bak')
188
- rescue
189
- begin
190
- sftp.remove(remote + '.bak') # may fail if not existent
191
- FastlaneCore::UI.message('Removed ' + remote + '.bak')
192
- rescue
193
- sftp.rename!(remote, remote + '.bak')
194
- FastlaneCore::UI.message('Bumped to ' + remote + '.bak')
195
- end
196
- end
197
- end
198
- end
199
- rescue
200
- FastlaneCore::UI.message('No previous IPA found.')
201
- end
202
- end
203
-
204
- # Downloads remote manifest, self.appcode required by options.
205
- #
206
- # @param sftp
207
- # @param [String] remote_path
208
- # @returns [JSON] json or nil
209
- def download_manifest(sftp)
210
- FastlaneCore::UI.message('Checking remote Manifest')
211
- json = nil
212
- remote_manifest_path = remote_manifest_path(appcode)
213
- begin
214
- sftp.stat!(remote_manifest_path) do |response|
215
- if response.ok?
216
- FastlaneCore::UI.success('Loading remote manifest:')
217
- manifest = sftp.download!(remote_manifest_path)
218
- json = JSON.parse(manifest)
219
- end
220
- end
221
- rescue
222
- FastlaneCore::UI.message('No previous Manifest found')
223
- end
224
- json
225
- end
226
-
227
- # Upload current IPA
228
- #
229
- # @param sftp
230
- # @param [String] local_ipa_path
231
- # @param [String] remote_ipa_path
232
- def upload_ipa(sftp, local_ipa_path, remote_ipa_path)
233
- msg = "[Uploading IPA] #{local_ipa_path} to #{remote_ipa_path}"
234
- FastlaneCore::UI.message(msg)
235
- result = sftp.upload!(local_ipa_path, remote_ipa_path) do |event, _uploader, *_args|
236
- case event
237
- when :open then
238
- putc '.'
239
- when :put then
240
- putc '.'
241
- $stdout.flush
242
- when :close then
243
- puts "\n"
244
- when :finish then
245
- FastlaneCore::UI.success('IPA upload successful')
246
- end
247
- end
248
- end
249
-
250
- # Upload current manifest.json
251
- #
252
- # @param sftp
253
- # @param [String] manifest_path
254
- # @param [String] remote_manifest_path
255
- def upload_manifest(sftp, local_path, remote_path)
256
- msg = '[Uploading Manifest] ' + local_path + ' to ' + remote_path
257
- FastlaneCore::UI.message(msg)
258
- result = sftp.upload!(local_path, remote_path) do |event, _uploader, *_args|
259
- case event
260
- when :finish then
261
- FastlaneCore::UI.success('Manifest upload successful')
262
- end
263
- end
264
- end
265
-
266
- def get_remote_ipa_path(local_ipa_path, appcode)
267
- remote_path(appcode) + File.basename(local_ipa_path)
268
- end
269
-
270
- def remote_path(appcode)
271
- generate_remote_path + appcode + '/'
272
- end
273
-
274
- def remote_manifest_path(appcode)
275
- remote_path(appcode) + 'manifest.json'
276
- end
277
-
278
- def generate_remote_path
279
- '/home/' + user + '/repo/apps/'
280
- end
281
-
282
- def remote_mkdir(sftp, remote_path)
283
- sftp.mkdir remote_path
284
- rescue Net::SFTP::StatusException => e
285
- raise if e.code != 11
286
- msg = "Remote dir #{remote_path} exists."
287
- FastlaneCore::UI.message(msg)
288
- end
289
-
290
- # Private methods - Local Operations
291
-
292
- def load_rsa_key(rsa_keypath)
293
- File.open(rsa_keypath, 'r') do |file|
294
- rsa_key = nil
295
- rsa_key = [file.read]
296
- if !rsa_key.nil?
297
- FastlaneCore::UI.success('Successfully loaded RSA key...')
298
- else
299
- FastlaneCore::UI.user_error!('Failed to load RSA key...')
300
- end
301
- rsa_key
302
- end
303
- end
304
- end
305
- end
306
- end