fastlane 1.16.0 → 1.17.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 64d13313e93649ee90caa553d9e61ae6759c22db
4
- data.tar.gz: 2cfbb113190bb42dd7f401f651652243a0b909a4
3
+ metadata.gz: 9959b0da34326315d18cd09fb1b797e1a520ef81
4
+ data.tar.gz: 7a3b437b3e752e3bbac7f4c8fad4b487e2e94ae7
5
5
  SHA512:
6
- metadata.gz: 09dcc32c05045d06865f2fc569fd6611ec21cf8b9640acdf665a54706ca610ea84fd0e2818b3e5fa29a460d373dee3f49c008957aa738de0ce92f3c1f71638d5
7
- data.tar.gz: e2d19739f74a77f5cbfe5688a634ab04fd0908803650dae3d8234f20416b6dc6a54b0e1901bb7cf3b6b1f33a069ed88c101ce552ad2d0100ae355a4513d3a0b4
6
+ metadata.gz: 0fb6fa250d1ec52e73976fc37a7cfa3106cf29c52b393a1dccf8fe2500b1d5d7cc46efb1de935928a36ead0962dbfeab99fd0972ca13c0b08da988deefca6d0a
7
+ data.tar.gz: c2ee2872282500c11e4a32da4998d333a2626fb0b8219a6b215f6af0dfc34beec200786630c69d917ba9ec73ef172555308b8b58ec6a8262e300bf62488297ac
@@ -12,14 +12,20 @@ module Fastlane
12
12
  begin
13
13
  FastlaneCore::UpdateChecker.start_looking_for_update('gym') unless Helper.is_test?
14
14
 
15
- values[:provisioning_profile_path] ||= Actions.lane_context[Actions::SharedValues::SIGH_PROFILE_PATH] || ENV["SIGH_PROFILE_PATH"]
16
- path = File.expand_path(Gym::Manager.new.work(values))
17
- dsym_path = path.gsub(".ipa", ".app.dSYM.zip")
15
+ if values[:provisioning_profile_path].to_s.length == 0
16
+ sigh_path = Actions.lane_context[Actions::SharedValues::SIGH_PROFILE_PATH] || ENV["SIGH_PROFILE_PATH"]
17
+ values[:provisioning_profile_path] = File.expand_path(sigh_path) if sigh_path
18
+ end
19
+
20
+ absolute_ipa_path = File.expand_path(Gym::Manager.new.work(values))
21
+ absolute_dsym_path = absolute_ipa_path.gsub(".ipa", ".app.dSYM.zip")
18
22
 
19
- Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] = path # absolute path
20
- Actions.lane_context[SharedValues::DSYM_OUTPUT_PATH] = dsym_path if File.exist?(dsym_path)
23
+ Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] = absolute_ipa_path
24
+ Actions.lane_context[SharedValues::DSYM_OUTPUT_PATH] = absolute_dsym_path if File.exist?(absolute_dsym_path)
25
+ ENV[SharedValues::IPA_OUTPUT_PATH.to_s] = absolute_ipa_path # for deliver
26
+ ENV[SharedValues::DSYM_OUTPUT_PATH.to_s] = absolute_dsym_path if File.exist?(absolute_dsym_path)
21
27
 
22
- return path
28
+ return absolute_ipa_path
23
29
  ensure
24
30
  FastlaneCore::UpdateChecker.show_update_status('gym', Gym::VERSION)
25
31
  end
@@ -10,19 +10,17 @@ module Fastlane
10
10
  end
11
11
 
12
12
  def self.run(params)
13
- require 'cupertino/provisioning_portal'
14
- require 'csv'
13
+ require 'spaceship'
15
14
 
16
- devices = params[:devices]
17
- devices_file = params[:devices_file]
18
- team_id = params[:team_id]
19
- username = params[:username]
15
+ devices = params[:devices]
16
+
17
+ credentials = CredentialsManager::PasswordManager.shared_manager(params[:username])
18
+ Spaceship::Portal.login(credentials.username, credentials.password)
20
19
 
21
20
  if devices
22
21
  device_objs = devices.map do |k, v|
23
22
  raise "Passed invalid UDID: #{v} for device: #{k}".red unless UDID_REGEXP =~ v
24
-
25
- Cupertino::ProvisioningPortal::Device.new(k, v)
23
+ Spaceship::Device.create!(name: k, udid: v)
26
24
  end
27
25
  elsif devices_file
28
26
  devices_file = CSV.read(File.expand_path(File.join(devices_file)), col_sep: "\t")
@@ -33,31 +31,13 @@ module Fastlane
33
31
  raise 'Invalid device line, please provide a file according to the Apple Sample UDID file (https://devimages.apple.com.edgekey.net/downloads/devices/Multiple-Upload-Samples.zip)'.red unless device.count == 2
34
32
  raise "Passed invalid UDID: #{device[0]} for device: #{device[1]}".red unless UDID_REGEXP =~ device[0]
35
33
 
36
- Cupertino::ProvisioningPortal::Device.new(device[1], device[0])
34
+ Spaceship::Device.create!(name: device[1], udid: device[0])
37
35
  end
38
36
  else
39
37
  raise 'You must pass either a valid `devices` or `devices_file`. Please check the readme.'.red
40
38
  end
41
39
 
42
- credentials = CredentialsManager::PasswordManager.shared_manager(username)
43
-
44
- agent = Cupertino::ProvisioningPortal::Agent.new
45
- agent.username = credentials.username
46
- agent.password = credentials.password
47
- agent.team_id = team_id if team_id
48
-
49
- Helper.log.info "Fetching list of currently registered devices..."
50
- existing_devices = agent.list_devices
51
- new_devices = device_objs.select{ |device| !existing_devices.map(&:udid).include?(device.udid) } # calculate the diff based on the UDID
52
-
53
- if new_devices.count > 0
54
- Helper.log.info "Adding new devices..."
55
- agent.add_devices(*new_devices) rescue raise 'Could not add devices. Please ensure you have passed the correct username/password combination, as well as a valid team_id if a member of multiple teams.'.red
56
-
57
- Helper.log.info "Successfully registered #{new_devices.count} new devices. Total devices now registered: #{existing_devices.count + new_devices.count}!".green
58
- else
59
- Helper.log.info "Device list up to date, all #{device_objs.count} devices are already registered. Total devices registed: #{existing_devices.count}.".green
60
- end
40
+ Helper.log.info "Successfully registered new devices.".green
61
41
  end
62
42
 
63
43
  def self.description
@@ -83,8 +63,8 @@ module Fastlane
83
63
  description: "optional: Your team ID",
84
64
  optional: true),
85
65
  FastlaneCore::ConfigItem.new(key: :username,
86
- env_name: "CUPERTINO_USERNAME",
87
- description: "optional: Your Apple ID ",
66
+ env_name: "DELIVER_USER",
67
+ description: "Optional: Your Apple ID",
88
68
  default_value: CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)),
89
69
  ]
90
70
  end
@@ -10,7 +10,7 @@ module Fastlane
10
10
 
11
11
  Helper.log.info "Setting Team ID to '#{team}' for all build steps"
12
12
 
13
- [:CERT_TEAM_ID, :SIGH_TEAM_ID, :PEM_TEAM_ID, :PRODUCE_TEAM_ID, :SIGH_TEAM_ID, :CUPERTINO_TEAM_ID, :FASTLANE_TEAM_ID].each do |current|
13
+ [:CERT_TEAM_ID, :SIGH_TEAM_ID, :PEM_TEAM_ID, :PRODUCE_TEAM_ID, :SIGH_TEAM_ID, :FASTLANE_TEAM_ID].each do |current|
14
14
  ENV[current.to_s] = team
15
15
  end
16
16
  end
@@ -0,0 +1,299 @@
1
+ module Fastlane
2
+ module Actions
3
+ module SharedValues
4
+ XCODE_SERVER_GET_ASSETS_PATH = :XCODE_SERVER_GET_ASSETS_PATH
5
+ XCODE_SERVER_GET_ASSETS_ARCHIVE_PATH = :XCODE_SERVER_GET_ASSETS_ARCHIVE_PATH
6
+ end
7
+
8
+ class XcodeServerGetAssetsAction < Action
9
+
10
+ require 'excon'
11
+ require 'json'
12
+ require 'fileutils'
13
+
14
+ def self.run(params)
15
+
16
+ host = params[:host]
17
+ bot_name = params[:bot_name]
18
+ integration_number_override = params[:integration_number]
19
+ target_folder = params[:target_folder]
20
+ keep_all_assets = params[:keep_all_assets]
21
+ username = params[:username]
22
+ password = params[:password]
23
+ trust_self_signed_certs = params[:trust_self_signed_certs]
24
+
25
+ # setup (not)trusting self signed certificates.
26
+ # it's normal to have a self signed certificate on your Xcode Server
27
+ Excon.defaults[:ssl_verify_peer] = !trust_self_signed_certs # for self-signed certificates
28
+
29
+ # create Xcode Server config
30
+ xcs = XcodeServer.new(host, username, password)
31
+ bots = xcs.fetch_all_bots
32
+
33
+ Helper.log.info "Fetched #{bots.count} Bots from Xcode Server at #{host}.".yellow
34
+
35
+ # pull out names
36
+ bot_names = bots.map { |bot| bot['name'] }
37
+
38
+ # match the bot name with a found bot, otherwise fail
39
+ found_bots = bots.select { |bot| bot['name'] == bot_name }
40
+ raise "Failed to find a Bot with name #{bot_name} on server #{host}, only available Bots: #{bot_names}".red if found_bots.count == 0
41
+
42
+ bot = found_bots[0]
43
+
44
+ Helper.log.info "Found Bot with name #{bot_name} with id #{bot['_id']}.".green
45
+
46
+ # we have our bot, get finished integrations, sorted from newest to oldest
47
+ integrations = xcs.fetch_integrations(bot['_id']).select { |i| i['currentStep'] == 'completed' }
48
+ raise "Failed to find any completed integration for Bot \"#{bot_name}\"".red if (integrations || []).count == 0
49
+
50
+ # if no integration number is specified, pick the newest one (this is sorted from newest to oldest)
51
+ if integration_number_override
52
+ integration = integrations.select { |i| i['number'] == integration_number_override }.first
53
+ raise "Specified integration number #{integration_number_override} does not exist.".red unless integration
54
+ else
55
+ integration = integrations.first
56
+ end
57
+
58
+ # consider: only taking the last successful one? or allow failing tests? warnings?
59
+
60
+ Helper.log.info "Using integration #{integration['number']}.".yellow
61
+
62
+ # fetch assets for this integration
63
+ assets_path = xcs.fetch_assets(integration['_id'], target_folder, self)
64
+ raise "Failed to fetch assets for integration #{integration['number']}." unless assets_path
65
+
66
+ asset_entries = Dir.entries(assets_path).map { |i| File.join(assets_path, i) }
67
+
68
+ Helper.log.info "Successfully downloaded #{asset_entries.count} assets to file #{assets_path}!".green
69
+
70
+ # now find the archive and unzip it
71
+ zipped_archive_path = asset_entries.select { |i| i.end_with?('xcarchive.zip') }.first
72
+
73
+ if zipped_archive_path
74
+
75
+ Helper.log.info "Found an archive in the assets folder...".yellow
76
+
77
+ archive_file_path = File.basename(zipped_archive_path, File.extname(zipped_archive_path))
78
+ archive_dir_path = File.dirname(zipped_archive_path)
79
+ archive_path = File.join(archive_dir_path, archive_file_path)
80
+ if File.exists?(archive_path)
81
+ # we already have the archive, skip
82
+ Helper.log.info "Archive #{archive_path} already exists, not unzipping again...".yellow
83
+ else
84
+ # unzip the archive
85
+ sh "unzip -q \"#{zipped_archive_path}\" -d \"#{archive_dir_path}\""
86
+ end
87
+
88
+ # reload asset entries to also contain the xcarchive file
89
+ asset_entries = Dir.entries(assets_path).map { |i| File.join(assets_path, i) }
90
+
91
+ # optionally delete everything except for the archive
92
+ if !keep_all_assets
93
+ files_to_delete = asset_entries.select do |i|
94
+ File.extname(i) != '.xcarchive' && ![".", ".."].include?(File.basename(i))
95
+ end
96
+
97
+ files_to_delete.each do |i|
98
+ FileUtils.rm_rf(i)
99
+ end
100
+ end
101
+
102
+ Actions.lane_context[SharedValues::XCODE_SERVER_GET_ASSETS_ARCHIVE_PATH] = archive_path
103
+ end
104
+
105
+ Actions.lane_context[SharedValues::XCODE_SERVER_GET_ASSETS_PATH] = assets_path
106
+
107
+ return assets_path
108
+ end
109
+
110
+ class XcodeServer
111
+
112
+ def initialize(host, username, password)
113
+ @host = host.start_with?('https://') ? host : "https://#{host}"
114
+ @username = username
115
+ @password = password
116
+ end
117
+
118
+ def fetch_all_bots
119
+ response = get_endpoint('/bots')
120
+ raise "You are unauthorized to access data on #{@host}, please check that you're passing in a correct username and password.".red if response.status == 401
121
+ raise "Failed to fetch Bots from Xcode Server at #{@host}, response: #{response.status}: #{response.body}.".red if response.status != 200
122
+ bots = JSON.parse(response.body)['results']
123
+ end
124
+
125
+ def fetch_integrations(bot_id)
126
+ response = get_endpoint("/bots/#{bot_id}/integrations?limit=10")
127
+ raise "Failed to fetch Integrations for Bot #{bot_id} from Xcode Server at #{@host}, response: #{response.status}: #{response.body}".red if response.status != 200
128
+ integrations = JSON.parse(response.body)['results']
129
+ end
130
+
131
+ def fetch_assets(integration_id, target_folder, action)
132
+
133
+ # create a temp folder and a file, stream the download into it
134
+ Dir.mktmpdir do |dir|
135
+
136
+ temp_file = File.join(dir, "tmp_download.#{rand(1000000)}")
137
+ f = open(temp_file, 'w')
138
+ streamer = lambda do |chunk, remaining_bytes, total_bytes|
139
+ if remaining_bytes && total_bytes
140
+ Helper.log.info "Downloading: #{100 - (100 * remaining_bytes.to_f / total_bytes.to_f).to_i}%".yellow
141
+ else
142
+ Helper.log.error "#{chunk}".red
143
+ end
144
+ f.write(chunk)
145
+ end
146
+
147
+ response = self.get_endpoint("/integrations/#{integration_id}/assets", streamer)
148
+ f.close()
149
+
150
+ raise "Integration doesn't have any assets (it probably never ran).".red if response.status == 500
151
+ raise "Failed to fetch Assets zip for Integration #{integration_id} from Xcode Server at #{@host}, response: #{response.status}: #{response.body}".red if response.status != 200
152
+
153
+ # unzip it, it's a .tar.gz file
154
+ out_folder = File.join(dir, "out_#{rand(1000000)}")
155
+ FileUtils.mkdir_p(out_folder)
156
+
157
+ action.sh "cd \"#{out_folder}\"; cat \"#{temp_file}\" | gzip -d | tar -x"
158
+
159
+ # then pull the real name from headers
160
+ asset_filename = response.headers['Content-Disposition'].split(';')[1].split('=')[1].gsub('"', '')
161
+ asset_foldername = asset_filename.split('.')[0]
162
+
163
+ # rename the folder in out_folder to asset_foldername
164
+ found_folder = Dir.entries(out_folder).select { |item| item != '.' && item != '..' }[0]
165
+
166
+ raise "Internal error, couldn't find unzipped folder".red if found_folder.nil?
167
+
168
+ unzipped_folder_temp_name = File.join(out_folder, found_folder)
169
+ unzipped_folder = File.join(out_folder, asset_foldername)
170
+
171
+ # rename to destination name
172
+ FileUtils.mv(unzipped_folder_temp_name, unzipped_folder)
173
+
174
+ target_folder = File.absolute_path(target_folder)
175
+
176
+ # create target folder if it doesn't exist
177
+ FileUtils.mkdir_p(target_folder)
178
+
179
+ # and move+rename it to the destination place
180
+ FileUtils.cp_r(unzipped_folder, target_folder)
181
+ out = File.join(target_folder, asset_foldername)
182
+ return out
183
+ end
184
+ return nil
185
+ end
186
+
187
+ def headers
188
+ require 'base64'
189
+ headers = {
190
+ 'User-Agent' => 'fastlane-xcode_server_get_assets', # XCS wants user agent. for some API calls. not for others. sigh.
191
+ 'X-XCSAPIVersion' => 1 # XCS API version with this API, Xcode needs this otherwise it explodes in a 500 error fire. Currently Xcode 7 Beta 5 is on Version 5.
192
+ }
193
+
194
+ if @username && @password
195
+ userpass = "#{@username}:#{@password}"
196
+ headers['Authorization'] = "Basic #{Base64.strict_encode64(userpass)}"
197
+ end
198
+
199
+ return headers
200
+ end
201
+
202
+ def get_endpoint(endpoint, response_block=nil)
203
+ url = url_for_endpoint(endpoint)
204
+ headers = self.headers || {}
205
+
206
+ if response_block
207
+ response = Excon.get(url, :response_block => response_block, :headers => headers)
208
+ else
209
+ response = Excon.get(url, :headers => headers)
210
+ end
211
+
212
+ return response
213
+ end
214
+
215
+ private
216
+
217
+ def url_for_endpoint(endpoint)
218
+ "#{@host}:20343/api#{endpoint}"
219
+ end
220
+ end
221
+
222
+ #####################################################
223
+ # @!group Documentation
224
+ #####################################################
225
+
226
+ def self.description
227
+ "Downloads Xcode Bot assets like the `.xcarchive` and logs"
228
+ end
229
+
230
+ def self.details
231
+ "This action downloads assets from your Xcode Server Bot (works with Xcode Server
232
+ using Xcode 6 and 7. By default this action downloads all assets, unzips them and
233
+ deletes everything except for the `.xcarchive`. If you'd like to keep all downloaded
234
+ assets, pass `:keep_all_assets: true`. This action returns the path to the downloaded
235
+ assets folder and puts into shared values the paths to the asset folder and to the `.xcarchive` inside it"
236
+ end
237
+
238
+ def self.available_options
239
+ [
240
+ FastlaneCore::ConfigItem.new(key: :host,
241
+ env_name: "FL_XCODE_SERVER_GET_ASSETS_HOST",
242
+ description: "IP Address/Hostname of Xcode Server",
243
+ optional: false),
244
+ FastlaneCore::ConfigItem.new(key: :bot_name,
245
+ env_name: "FL_XCODE_SERVER_GET_ASSETS_BOT_NAME",
246
+ description: "Name of the Bot to pull assets from",
247
+ optional: false),
248
+ FastlaneCore::ConfigItem.new(key: :integration_number,
249
+ env_name: "FL_XCODE_SERVER_GET_ASSETS_INTEGRATION_NUMBER",
250
+ description: "Optionally you can override which integration's assets should be downloaded. If not provided, the latest integration is used",
251
+ is_string: false,
252
+ optional: true),
253
+ FastlaneCore::ConfigItem.new(key: :username,
254
+ env_name: "FL_XCODE_SERVER_GET_ASSETS_USERNAME",
255
+ description: "Username for your Xcode Server",
256
+ optional: true,
257
+ default_value: ""),
258
+ FastlaneCore::ConfigItem.new(key: :password,
259
+ env_name: "FL_XCODE_SERVER_GET_ASSETS_PASSWORD",
260
+ description: "Password for your Xcode Server",
261
+ optional: true,
262
+ default_value: ""),
263
+ FastlaneCore::ConfigItem.new(key: :target_folder,
264
+ env_name: "FL_XCODE_SERVER_GET_ASSETS_TARGET_FOLDER",
265
+ description: "Relative path to a folder into which to download assets",
266
+ optional: true,
267
+ default_value: './xcs_assets'),
268
+ FastlaneCore::ConfigItem.new(key: :keep_all_assets,
269
+ env_name: "FL_XCODE_SERVER_GET_ASSETS_KEEP_ALL_ASSETS",
270
+ description: "Whether to keep all assets or let the script delete everything except for the .xcarchive",
271
+ optional: true,
272
+ is_string: false,
273
+ default_value: false),
274
+ FastlaneCore::ConfigItem.new(key: :trust_self_signed_certs,
275
+ env_name: "FL_XCODE_SERVER_GET_ASSETS_TRUST_SELF_SIGNED_CERTS",
276
+ description: "Whether to trust self-signed certs on your Xcode Server",
277
+ optional: true,
278
+ is_string: false,
279
+ default_value: true)
280
+ ]
281
+ end
282
+
283
+ def self.output
284
+ [
285
+ ['XCODE_SERVER_GET_ASSETS_PATH', 'Absolute path to the downloaded assets folder'],
286
+ ['XCODE_SERVER_GET_ASSETS_ARCHIVE_PATH', 'Absolute path to the downloaded xcarchive file']
287
+ ]
288
+ end
289
+
290
+ def self.authors
291
+ ["czechboy0"]
292
+ end
293
+
294
+ def self.is_supported?(platform)
295
+ true
296
+ end
297
+ end
298
+ end
299
+ end
@@ -19,6 +19,10 @@ module Fastlane
19
19
  raise "lane name must not contain any spaces".red if name.to_s.include?" "
20
20
  raise "lane name must start with :".red unless name.kind_of?Symbol
21
21
 
22
+ if self.class.black_list.include?(name.to_s)
23
+ Helper.log.error "Lane Name '#{name}' can not be one of the followings: #{self.class.black_list}".red
24
+ raise "Name '#{name}' is already taken"
25
+ end
22
26
 
23
27
  self.platform = platform
24
28
  self.name = name
@@ -36,5 +40,11 @@ module Fastlane
36
40
  def pretty_name
37
41
  [platform, name].reject(&:nil?).join(' ')
38
42
  end
43
+
44
+ class << self
45
+ def black_list
46
+ %w{run init new_action lanes list docs action actions help}
47
+ end
48
+ end
39
49
  end
40
50
  end
@@ -1,3 +1,3 @@
1
1
  module Fastlane
2
- VERSION = '1.16.0'
2
+ VERSION = '1.17.0'
3
3
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 1.16.0
4
+ version: 1.17.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Felix Krause
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2015-08-11 00:00:00.000000000 Z
11
+ date: 2015-08-13 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: nokogiri
@@ -94,20 +94,6 @@ dependencies:
94
94
  - - "~>"
95
95
  - !ruby/object:Gem::Version
96
96
  version: '0.1'
97
- - !ruby/object:Gem::Dependency
98
- name: cupertino
99
- requirement: !ruby/object:Gem::Requirement
100
- requirements:
101
- - - ">="
102
- - !ruby/object:Gem::Version
103
- version: 1.3.3
104
- type: :runtime
105
- prerelease: false
106
- version_requirements: !ruby/object:Gem::Requirement
107
- requirements:
108
- - - ">="
109
- - !ruby/object:Gem::Version
110
- version: 1.3.3
111
97
  - !ruby/object:Gem::Dependency
112
98
  name: terminal-notifier
113
99
  requirement: !ruby/object:Gem::Requirement
@@ -168,30 +154,44 @@ dependencies:
168
154
  name: fastlane_core
169
155
  requirement: !ruby/object:Gem::Requirement
170
156
  requirements:
171
- - - "~>"
157
+ - - ">="
172
158
  - !ruby/object:Gem::Version
173
159
  version: 0.13.0
174
160
  type: :runtime
175
161
  prerelease: false
176
162
  version_requirements: !ruby/object:Gem::Requirement
177
163
  requirements:
178
- - - "~>"
164
+ - - ">="
179
165
  - !ruby/object:Gem::Version
180
166
  version: 0.13.0
167
+ - !ruby/object:Gem::Dependency
168
+ name: credentials_manager
169
+ requirement: !ruby/object:Gem::Requirement
170
+ requirements:
171
+ - - ">="
172
+ - !ruby/object:Gem::Version
173
+ version: 0.7.3
174
+ type: :runtime
175
+ prerelease: false
176
+ version_requirements: !ruby/object:Gem::Requirement
177
+ requirements:
178
+ - - ">="
179
+ - !ruby/object:Gem::Version
180
+ version: 0.7.3
181
181
  - !ruby/object:Gem::Dependency
182
182
  name: spaceship
183
183
  requirement: !ruby/object:Gem::Requirement
184
184
  requirements:
185
- - - "~>"
185
+ - - ">="
186
186
  - !ruby/object:Gem::Version
187
- version: 0.4.0
187
+ version: 0.5.0
188
188
  type: :runtime
189
189
  prerelease: false
190
190
  version_requirements: !ruby/object:Gem::Requirement
191
191
  requirements:
192
- - - "~>"
192
+ - - ">="
193
193
  - !ruby/object:Gem::Version
194
- version: 0.4.0
194
+ version: 0.5.0
195
195
  - !ruby/object:Gem::Dependency
196
196
  name: deliver
197
197
  requirement: !ruby/object:Gem::Requirement
@@ -296,14 +296,14 @@ dependencies:
296
296
  requirements:
297
297
  - - ">="
298
298
  - !ruby/object:Gem::Version
299
- version: 0.1.0
299
+ version: 0.2.0
300
300
  type: :runtime
301
301
  prerelease: false
302
302
  version_requirements: !ruby/object:Gem::Requirement
303
303
  requirements:
304
304
  - - ">="
305
305
  - !ruby/object:Gem::Version
306
- version: 0.1.0
306
+ version: 0.2.0
307
307
  - !ruby/object:Gem::Dependency
308
308
  name: bundler
309
309
  requirement: !ruby/object:Gem::Requirement
@@ -514,6 +514,7 @@ files:
514
514
  - lib/fastlane/actions/update_project_code_signing.rb
515
515
  - lib/fastlane/actions/update_project_provisioning.rb
516
516
  - lib/fastlane/actions/xcode_select.rb
517
+ - lib/fastlane/actions/xcode_server_get_assets.rb
517
518
  - lib/fastlane/actions/xcodebuild.rb
518
519
  - lib/fastlane/actions/xctool.rb
519
520
  - lib/fastlane/actions_list.rb