fastlane 2.157.4 → 2.162.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.
- checksums.yaml +4 -4
- data/README.md +80 -80
- data/cert/lib/cert/options.rb +28 -1
- data/cert/lib/cert/runner.rb +50 -33
- data/deliver/lib/deliver/app_screenshot_iterator.rb +4 -4
- data/deliver/lib/deliver/options.rb +17 -1
- data/deliver/lib/deliver/runner.rb +36 -7
- data/deliver/lib/deliver/upload_metadata.rb +37 -6
- data/deliver/lib/deliver/upload_price_tier.rb +7 -2
- data/deliver/lib/deliver/upload_screenshots.rb +25 -8
- data/{pilot/lib/pilot/.manager.rb.swp → fastlane/lib/fastlane/.erb_template_helper.rb.swp} +0 -0
- data/fastlane/lib/fastlane/actions/{.ensure_git_status_clean.rb.swp → .git_commit.rb.swp} +0 -0
- data/fastlane/lib/fastlane/actions/actions_helper.rb +20 -1
- data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +6 -1
- data/fastlane/lib/fastlane/actions/clean_build_artifacts.rb +1 -0
- data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +2 -2
- data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/create_app_online.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +3 -2
- data/fastlane/lib/fastlane/actions/docs/run_tests.md +2 -2
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +3 -3
- data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +2 -2
- data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +2 -2
- data/fastlane/lib/fastlane/actions/download_dsyms.rb +32 -7
- data/fastlane/lib/fastlane/actions/ensure_git_status_clean.rb +13 -2
- data/fastlane/lib/fastlane/helper/git_helper.rb +2 -0
- data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +6 -4
- data/fastlane/lib/fastlane/swift_fastlane_function.rb +1 -1
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Actions.swift +2 -1
- data/fastlane/swift/Appfile.swift +2 -4
- data/fastlane/swift/ArgumentProcessor.swift +2 -6
- data/fastlane/swift/ControlCommand.swift +2 -5
- data/fastlane/swift/Deliverfile.swift +5 -2
- data/fastlane/swift/DeliverfileProtocol.swift +15 -4
- data/fastlane/swift/Fastfile.swift +5 -1
- data/fastlane/swift/Fastlane.swift +2333 -2240
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +5 -5
- data/fastlane/swift/Gymfile.swift +5 -2
- data/fastlane/swift/GymfileProtocol.swift +6 -3
- data/fastlane/swift/LaneFileProtocol.swift +42 -29
- data/fastlane/swift/MainProcess.swift +77 -0
- data/fastlane/swift/Matchfile.swift +5 -2
- data/fastlane/swift/MatchfileProtocol.swift +21 -6
- data/fastlane/swift/Plugins.swift +2 -1
- data/fastlane/swift/Precheckfile.swift +5 -2
- data/fastlane/swift/PrecheckfileProtocol.swift +18 -3
- data/fastlane/swift/RubyCommand.swift +2 -6
- data/fastlane/swift/RubyCommandable.swift +2 -6
- data/fastlane/swift/Runner.swift +5 -9
- data/fastlane/swift/RunnerArgument.swift +2 -6
- data/fastlane/swift/Scanfile.swift +5 -2
- data/fastlane/swift/ScanfileProtocol.swift +6 -3
- data/fastlane/swift/Screengrabfile.swift +5 -2
- data/fastlane/swift/ScreengrabfileProtocol.swift +6 -3
- data/fastlane/swift/Snapshotfile.swift +5 -2
- data/fastlane/swift/SnapshotfileProtocol.swift +6 -3
- data/fastlane/swift/SocketClient.swift +3 -7
- data/fastlane/swift/SocketClientDelegateProtocol.swift +2 -6
- data/fastlane/swift/SocketResponse.swift +2 -6
- data/fastlane/swift/formatting/Brewfile.lock.json +18 -10
- data/fastlane/swift/main.swift +4 -8
- data/fastlane/swift/upgrade_manifest.json +1 -1
- data/fastlane_core/lib/fastlane_core/analytics/analytics_session.rb +6 -7
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +2 -2
- data/frameit/lib/frameit/editor.rb +1 -0
- data/match/lib/match/generator.rb +6 -1
- data/match/lib/match/importer.rb +44 -8
- data/match/lib/match/migrate.rb +13 -2
- data/match/lib/match/nuke.rb +65 -22
- data/match/lib/match/options.rb +27 -2
- data/match/lib/match/runner.rb +38 -10
- data/match/lib/match/spaceship_ensure.rb +27 -21
- data/match/lib/match/storage/google_cloud_storage.rb +20 -3
- data/match/lib/match/storage/s3_storage.rb +19 -3
- data/pilot/lib/pilot/options.rb +2 -2
- data/precheck/lib/precheck/options.rb +25 -0
- data/precheck/lib/precheck/rule_processor.rb +94 -60
- data/precheck/lib/precheck/runner.rb +26 -5
- data/sigh/lib/sigh/options.rb +21 -0
- data/sigh/lib/sigh/runner.rb +80 -38
- data/snapshot/lib/assets/SnapshotHelper.swift +17 -2
- data/spaceship/README.md +1 -1
- data/spaceship/lib/spaceship/{connect_api/.DS_Store → .DS_Store} +0 -0
- data/spaceship/lib/spaceship/client.rb +2 -1
- data/spaceship/lib/spaceship/connect_api.rb +1 -0
- data/spaceship/lib/spaceship/connect_api/api_client.rb +3 -3
- data/spaceship/lib/spaceship/connect_api/client.rb +38 -15
- data/{fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp → spaceship/lib/spaceship/connect_api/models/.app_store_version_submission.rb.swp} +0 -0
- data/spaceship/lib/spaceship/connect_api/models/app.rb +17 -9
- data/spaceship/lib/spaceship/connect_api/models/app_info.rb +1 -0
- data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +3 -1
- data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +2 -2
- data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +3 -5
- data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +3 -5
- data/spaceship/lib/spaceship/connect_api/models/app_store_version_phased_release.rb +21 -0
- data/spaceship/lib/spaceship/connect_api/models/beta_tester.rb +2 -1
- data/spaceship/lib/spaceship/connect_api/models/certificate.rb +42 -0
- data/spaceship/lib/spaceship/connect_api/models/profile.rb +7 -1
- data/spaceship/lib/spaceship/connect_api/models/user_invitation.rb +59 -0
- data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +28 -2
- data/spaceship/lib/spaceship/connect_api/spaceship.rb +3 -2
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +13 -0
- data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +29 -9
- data/spaceship/lib/spaceship/connect_api/users/users.rb +40 -0
- data/spaceship/lib/spaceship/helper/net_http_generic_request.rb +11 -5
- metadata +24 -25
- data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
data/match/lib/match/migrate.rb
CHANGED
@@ -42,9 +42,14 @@ module Match
|
|
42
42
|
# while on Git we recommend using the git branch instead. As there is
|
43
43
|
# no concept of branches in Google Cloud Storage (omg thanks), we use
|
44
44
|
# the team id properly
|
45
|
-
spaceship = SpaceshipEnsure.new(params[:username], params[:team_id], params[:team_name])
|
45
|
+
spaceship = SpaceshipEnsure.new(params[:username], params[:team_id], params[:team_name], api_token(params))
|
46
46
|
team_id = spaceship.team_id
|
47
|
-
|
47
|
+
|
48
|
+
if team_id.to_s.empty?
|
49
|
+
UI.user_error!("The `team_id` option is required. fastlane cannot automatically determine portal team id via the App Store Connect API (yet)")
|
50
|
+
else
|
51
|
+
UI.message("Detected team ID '#{team_id}' to use for Google Cloud Storage...")
|
52
|
+
end
|
48
53
|
|
49
54
|
files_to_commit = []
|
50
55
|
Dir.chdir(git_storage.working_directory) do
|
@@ -85,6 +90,12 @@ module Match
|
|
85
90
|
UI.input("Please make sure to read the above and confirm with enter")
|
86
91
|
end
|
87
92
|
|
93
|
+
def api_token(params)
|
94
|
+
@api_token ||= Spaceship::ConnectAPI::Token.create(params[:api_key]) if params[:api_key]
|
95
|
+
@api_token ||= Spaceship::ConnectAPI::Token.from_json_file(params[:api_key_path]) if params[:api_key_path]
|
96
|
+
return @api_token
|
97
|
+
end
|
98
|
+
|
88
99
|
def ensure_parameters_are_valid(params)
|
89
100
|
if params[:readonly]
|
90
101
|
UI.user_error!("`fastlane match migrate` doesn't work in `readonly` mode")
|
data/match/lib/match/nuke.rb
CHANGED
@@ -44,7 +44,7 @@ module Match
|
|
44
44
|
s3_access_key: params[:s3_access_key].to_s,
|
45
45
|
s3_secret_access_key: params[:s3_secret_access_key].to_s,
|
46
46
|
s3_bucket: params[:s3_bucket].to_s,
|
47
|
-
team_id: params[:team_id] || Spaceship.client.
|
47
|
+
team_id: params[:team_id] || Spaceship::ConnectAPI.client.portal_team_id
|
48
48
|
})
|
49
49
|
self.storage.download
|
50
50
|
|
@@ -97,10 +97,14 @@ module Match
|
|
97
97
|
end
|
98
98
|
|
99
99
|
def spaceship_login
|
100
|
-
|
101
|
-
|
100
|
+
if api_token
|
101
|
+
UI.message("Creating authorization token for App Store Connect API")
|
102
|
+
Spaceship::ConnectAPI.token = api_token
|
103
|
+
else
|
104
|
+
Spaceship::ConnectAPI.login(params[:username], use_portal: true, use_tunes: false, portal_team_id: params[:team_id], team_name: params[:team_name])
|
105
|
+
end
|
102
106
|
|
103
|
-
if Spaceship.client.in_house? && (type == "distribution" || type == "enterprise")
|
107
|
+
if Spaceship::ConnectAPI.client.in_house? && (type == "distribution" || type == "enterprise")
|
104
108
|
UI.error("---")
|
105
109
|
UI.error("⚠️ Warning: This seems to be an Enterprise account!")
|
106
110
|
UI.error("By nuking your account's distribution, all your apps deployed via ad-hoc will stop working!") if type == "distribution"
|
@@ -111,6 +115,12 @@ module Match
|
|
111
115
|
end
|
112
116
|
end
|
113
117
|
|
118
|
+
def api_token
|
119
|
+
@api_token ||= Spaceship::ConnectAPI::Token.create(params[:api_key]) if params[:api_key]
|
120
|
+
@api_token ||= Spaceship::ConnectAPI::Token.from_json_file(params[:api_key_path]) if params[:api_key_path]
|
121
|
+
return @api_token
|
122
|
+
end
|
123
|
+
|
114
124
|
# Collect all the certs/profiles
|
115
125
|
def prepare_list
|
116
126
|
UI.message("Fetching certificates and profiles...")
|
@@ -125,8 +135,10 @@ module Match
|
|
125
135
|
# Get all iOS and macOS profile
|
126
136
|
self.profiles = []
|
127
137
|
prov_types.each do |prov_type|
|
128
|
-
|
129
|
-
|
138
|
+
types = profile_types(prov_type)
|
139
|
+
# Filtering on 'profileType' seems to be undocumented as of 2020-07-30
|
140
|
+
# but works on both web session and official API
|
141
|
+
self.profiles += Spaceship::ConnectAPI::Profile.all(filter: { profileType: types.join(",") })
|
130
142
|
end
|
131
143
|
|
132
144
|
# Gets the main and additional cert types
|
@@ -138,7 +150,7 @@ module Match
|
|
138
150
|
self.certs = []
|
139
151
|
self.certs += cert_types.map do |ct|
|
140
152
|
certificate_type(ct).flat_map do |cert|
|
141
|
-
|
153
|
+
Spaceship::ConnectAPI::Certificate.all(filter: { certificateType: cert })
|
142
154
|
end
|
143
155
|
end.flatten
|
144
156
|
|
@@ -165,7 +177,7 @@ module Match
|
|
165
177
|
puts("")
|
166
178
|
if self.certs.count > 0
|
167
179
|
rows = self.certs.collect do |cert|
|
168
|
-
cert_expiration = cert.
|
180
|
+
cert_expiration = cert.expiration_date.nil? ? "Unknown" : Time.parse(cert.expiration_date).strftime("%Y-%m-%d")
|
169
181
|
[cert.name, cert.id, cert.class.to_s.split("::").last, cert_expiration]
|
170
182
|
end
|
171
183
|
puts(Terminal::Table.new({
|
@@ -178,11 +190,11 @@ module Match
|
|
178
190
|
|
179
191
|
if self.profiles.count > 0
|
180
192
|
rows = self.profiles.collect do |p|
|
181
|
-
status = p.
|
193
|
+
status = p.valid? ? p.profile_state.green : p.profile_state.red
|
182
194
|
|
183
195
|
# Expires is sometimes nil
|
184
|
-
expires = p.
|
185
|
-
[p.name, p.id, status, p.
|
196
|
+
expires = p.expiration_date ? Time.parse(p.expiration_date).strftime("%Y-%m-%d") : nil
|
197
|
+
[p.name, p.id, status, p.profile_type, expires]
|
186
198
|
end
|
187
199
|
puts(Terminal::Table.new({
|
188
200
|
title: "Provisioning Profiles that are going to be revoked".green,
|
@@ -227,7 +239,7 @@ module Match
|
|
227
239
|
self.certs.each do |cert|
|
228
240
|
UI.message("Revoking certificate '#{cert.name}' (#{cert.id})...")
|
229
241
|
begin
|
230
|
-
cert.
|
242
|
+
cert.delete!
|
231
243
|
rescue => ex
|
232
244
|
UI.message(ex.to_s)
|
233
245
|
end
|
@@ -274,31 +286,62 @@ module Match
|
|
274
286
|
def certificate_type(type)
|
275
287
|
case type.to_sym
|
276
288
|
when :mac_installer_distribution
|
277
|
-
return [
|
289
|
+
return [
|
290
|
+
Spaceship::ConnectAPI::Certificate::CertificateType::MAC_INSTALLER_DISTRIBUTION
|
291
|
+
]
|
278
292
|
when :distribution
|
279
|
-
return [
|
293
|
+
return [
|
294
|
+
Spaceship::ConnectAPI::Certificate::CertificateType::MAC_APP_DISTRIBUTION,
|
295
|
+
Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DISTRIBUTION,
|
296
|
+
Spaceship::ConnectAPI::Certificate::CertificateType::DISTRIBUTION
|
297
|
+
]
|
280
298
|
when :development
|
281
|
-
return [
|
299
|
+
return [
|
300
|
+
Spaceship::ConnectAPI::Certificate::CertificateType::MAC_APP_DEVELOPMENT,
|
301
|
+
Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DEVELOPMENT,
|
302
|
+
Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPMENT
|
303
|
+
]
|
282
304
|
when :enterprise
|
283
|
-
return [
|
305
|
+
return [
|
306
|
+
Spaceship::ConnectAPI::Certificate::CertificateType::IOS_DISTRIBUTION
|
307
|
+
]
|
284
308
|
else
|
285
309
|
raise "Unknown type '#{type}'"
|
286
310
|
end
|
287
311
|
end
|
288
312
|
|
289
313
|
# The kind of provisioning profile we're interested in
|
290
|
-
def
|
314
|
+
def profile_types(prov_type)
|
291
315
|
case prov_type.to_sym
|
292
316
|
when :appstore
|
293
|
-
return
|
317
|
+
return [
|
318
|
+
Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_STORE,
|
319
|
+
Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_STORE,
|
320
|
+
Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_STORE,
|
321
|
+
Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_STORE
|
322
|
+
]
|
294
323
|
when :development
|
295
|
-
return
|
324
|
+
return [
|
325
|
+
Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_DEVELOPMENT,
|
326
|
+
Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DEVELOPMENT,
|
327
|
+
Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_DEVELOPMENT,
|
328
|
+
Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DEVELOPMENT
|
329
|
+
]
|
296
330
|
when :enterprise
|
297
|
-
return
|
331
|
+
return [
|
332
|
+
Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_INHOUSE,
|
333
|
+
Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_INHOUSE
|
334
|
+
]
|
298
335
|
when :adhoc
|
299
|
-
return
|
336
|
+
return [
|
337
|
+
Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_ADHOC,
|
338
|
+
Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_ADHOC
|
339
|
+
]
|
300
340
|
when :developer_id
|
301
|
-
return
|
341
|
+
return [
|
342
|
+
Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DIRECT,
|
343
|
+
Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DIRECT
|
344
|
+
]
|
302
345
|
else
|
303
346
|
raise "Unknown provisioning type '#{prov_type}'"
|
304
347
|
end
|
data/match/lib/match/options.rb
CHANGED
@@ -62,7 +62,6 @@ module Match
|
|
62
62
|
type: Boolean,
|
63
63
|
default_value: false),
|
64
64
|
|
65
|
-
# app
|
66
65
|
FastlaneCore::ConfigItem.new(key: :app_identifier,
|
67
66
|
short_option: "-a",
|
68
67
|
env_name: "MATCH_APP_IDENTIFIER",
|
@@ -72,10 +71,30 @@ module Match
|
|
72
71
|
code_gen_sensitive: true,
|
73
72
|
default_value: CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier),
|
74
73
|
default_value_dynamic: true),
|
74
|
+
|
75
|
+
# App Store Connect API
|
76
|
+
FastlaneCore::ConfigItem.new(key: :api_key_path,
|
77
|
+
env_name: "SIGH_API_KEY_PATH",
|
78
|
+
description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
|
79
|
+
optional: true,
|
80
|
+
conflicting_options: [:api_key],
|
81
|
+
verify_block: proc do |value|
|
82
|
+
UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
|
83
|
+
end),
|
84
|
+
FastlaneCore::ConfigItem.new(key: :api_key,
|
85
|
+
env_name: "SIGH_API_KEY",
|
86
|
+
description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
|
87
|
+
type: Hash,
|
88
|
+
optional: true,
|
89
|
+
sensitive: true,
|
90
|
+
conflicting_options: [:api_key_path]),
|
91
|
+
|
92
|
+
# Apple ID
|
75
93
|
FastlaneCore::ConfigItem.new(key: :username,
|
76
94
|
short_option: "-u",
|
77
95
|
env_name: "MATCH_USERNAME",
|
78
96
|
description: "Your Apple ID Username",
|
97
|
+
optional: true,
|
79
98
|
default_value: user,
|
80
99
|
default_value_dynamic: true),
|
81
100
|
FastlaneCore::ConfigItem.new(key: :team_id,
|
@@ -147,7 +166,7 @@ module Match
|
|
147
166
|
FastlaneCore::ConfigItem.new(key: :git_bearer_authorization,
|
148
167
|
env_name: "MATCH_GIT_BEARER_AUTHORIZATION",
|
149
168
|
sensitive: true,
|
150
|
-
description: "Use a bearer authorization header to access the git repo (e.g.: access to an Azure
|
169
|
+
description: "Use a bearer authorization header to access the git repo (e.g.: access to an Azure DevOps repository), usually a string in Base64",
|
151
170
|
conflicting_options: [:git_basic_authorization, :git_private_key],
|
152
171
|
optional: true,
|
153
172
|
default_value: nil),
|
@@ -268,6 +287,12 @@ module Match
|
|
268
287
|
env_name: "MATCH_OUTPUT_PATH",
|
269
288
|
description: "Path in which to export certificates, key and profile",
|
270
289
|
optional: true),
|
290
|
+
FastlaneCore::ConfigItem.new(key: :skip_set_partition_list,
|
291
|
+
short_option: "-P",
|
292
|
+
env_name: "MATCH_SKIP_SET_PARTITION_LIST",
|
293
|
+
description: "Skips setting the partition list (which can sometimes take a long time). Setting the partition list is usually needed to prevent Xcode from prompting to allow a cert to be used for signing",
|
294
|
+
type: Boolean,
|
295
|
+
default_value: false),
|
271
296
|
|
272
297
|
# other
|
273
298
|
FastlaneCore::ConfigItem.new(key: :verbose,
|
data/match/lib/match/runner.rb
CHANGED
@@ -55,7 +55,9 @@ module Match
|
|
55
55
|
readonly: params[:readonly],
|
56
56
|
username: params[:readonly] ? nil : params[:username], # only pass username if not readonly
|
57
57
|
team_id: params[:team_id],
|
58
|
-
team_name: params[:team_name]
|
58
|
+
team_name: params[:team_name],
|
59
|
+
api_key_path: params[:api_key_path],
|
60
|
+
api_key: params[:api_key]
|
59
61
|
})
|
60
62
|
storage.download
|
61
63
|
|
@@ -67,7 +69,7 @@ module Match
|
|
67
69
|
encryption.decrypt_files if encryption
|
68
70
|
|
69
71
|
unless params[:readonly]
|
70
|
-
self.spaceship = SpaceshipEnsure.new(params[:username], params[:team_id], params[:team_name])
|
72
|
+
self.spaceship = SpaceshipEnsure.new(params[:username], params[:team_id], params[:team_name], api_token(params))
|
71
73
|
if params[:type] == "enterprise" && !Spaceship.client.in_house?
|
72
74
|
UI.user_error!("You defined the profile type 'enterprise', but your Apple account doesn't support In-House profiles")
|
73
75
|
end
|
@@ -100,7 +102,7 @@ module Match
|
|
100
102
|
end
|
101
103
|
|
102
104
|
cert_ids << cert_id
|
103
|
-
spaceship.certificates_exists(username: params[:username], certificate_ids: cert_ids
|
105
|
+
spaceship.certificates_exists(username: params[:username], certificate_ids: cert_ids) if spaceship
|
104
106
|
|
105
107
|
# Provisioning Profiles
|
106
108
|
unless params[:skip_provisioning_profiles]
|
@@ -136,6 +138,12 @@ module Match
|
|
136
138
|
end
|
137
139
|
# rubocop:enable Metrics/PerceivedComplexity
|
138
140
|
|
141
|
+
def api_token(params)
|
142
|
+
@api_token ||= Spaceship::ConnectAPI::Token.create(params[:api_key]) if params[:api_key]
|
143
|
+
@api_token ||= Spaceship::ConnectAPI::Token.from_json_file(params[:api_key_path]) if params[:api_key_path]
|
144
|
+
return @api_token
|
145
|
+
end
|
146
|
+
|
139
147
|
# Used when creating a new certificate or profile
|
140
148
|
def prefixed_working_directory
|
141
149
|
return self.storage.prefixed_working_directory
|
@@ -316,23 +324,43 @@ module Match
|
|
316
324
|
|
317
325
|
parsed = FastlaneCore::ProvisioningProfile.parse(profile, keychain_path)
|
318
326
|
uuid = parsed["UUID"]
|
319
|
-
|
327
|
+
|
328
|
+
all_profiles = Spaceship::ConnectAPI::Profile.all(includes: "devices")
|
329
|
+
portal_profile = all_profiles.detect { |i| i.uuid == uuid }
|
320
330
|
|
321
331
|
if portal_profile
|
322
|
-
profile_device_count = portal_profile.
|
332
|
+
profile_device_count = portal_profile.fetch_all_devices.count
|
323
333
|
|
324
|
-
|
334
|
+
device_classes =
|
325
335
|
case platform
|
326
336
|
when :ios
|
327
|
-
|
337
|
+
[
|
338
|
+
Spaceship::ConnectAPI::Device::DeviceClass::IPAD,
|
339
|
+
Spaceship::ConnectAPI::Device::DeviceClass::IPHONE,
|
340
|
+
Spaceship::ConnectAPI::Device::DeviceClass::IPOD,
|
341
|
+
Spaceship::ConnectAPI::Device::DeviceClass::APPLE_WATCH
|
342
|
+
]
|
328
343
|
when :tvos
|
329
|
-
|
344
|
+
[
|
345
|
+
Spaceship::ConnectAPI::Device::DeviceClass::APPLE_TV
|
346
|
+
]
|
330
347
|
when :mac, :catalyst
|
331
|
-
|
348
|
+
[
|
349
|
+
Spaceship::ConnectAPI::Device::DeviceClass::MAC
|
350
|
+
]
|
332
351
|
else
|
333
|
-
|
352
|
+
[]
|
334
353
|
end
|
335
354
|
|
355
|
+
devices = Spaceship::ConnectAPI::Device.all
|
356
|
+
unless device_classes.empty?
|
357
|
+
devices = devices.select do |device|
|
358
|
+
device_classes.include?(device.device_class)
|
359
|
+
end
|
360
|
+
end
|
361
|
+
|
362
|
+
portal_device_count = devices.size
|
363
|
+
|
336
364
|
return portal_device_count != profile_device_count
|
337
365
|
end
|
338
366
|
return false
|
@@ -4,28 +4,38 @@ require_relative 'module'
|
|
4
4
|
module Match
|
5
5
|
# Ensures the certificate and profiles are also available on App Store Connect
|
6
6
|
class SpaceshipEnsure
|
7
|
-
|
8
|
-
# We'll try to manually fetch the password
|
9
|
-
# to tell the user that a password is optional
|
10
|
-
require 'credentials_manager/account_manager'
|
7
|
+
attr_accessor :team_id
|
11
8
|
|
12
|
-
|
9
|
+
def initialize(user, team_id, team_name, api_token)
|
10
|
+
UI.message("Verifying that the certificate and profile are still valid on the Dev Portal...")
|
13
11
|
|
14
|
-
if
|
15
|
-
UI.
|
16
|
-
|
17
|
-
|
18
|
-
|
19
|
-
|
12
|
+
if api_token
|
13
|
+
UI.message("Creating authorization token for App Store Connect API")
|
14
|
+
Spaceship::ConnectAPI.token = api_token
|
15
|
+
self.team_id = team_id
|
16
|
+
else
|
17
|
+
# We'll try to manually fetch the password
|
18
|
+
# to tell the user that a password is optional
|
19
|
+
require 'credentials_manager/account_manager'
|
20
20
|
|
21
|
-
|
22
|
-
|
23
|
-
|
21
|
+
keychain_entry = CredentialsManager::AccountManager.new(user: user)
|
22
|
+
|
23
|
+
if keychain_entry.password(ask_if_missing: false).to_s.length == 0
|
24
|
+
UI.important("You can also run `fastlane match` in readonly mode to not require any access to the")
|
25
|
+
UI.important("Developer Portal. This way you only share the keys and credentials")
|
26
|
+
UI.command("fastlane match --readonly")
|
27
|
+
UI.important("More information https://docs.fastlane.tools/actions/match/#access-control")
|
28
|
+
end
|
29
|
+
|
30
|
+
# Prompts select team if multiple teams and none specified
|
31
|
+
Spaceship::ConnectAPI.login(user, use_portal: true, use_tunes: false, portal_team_id: team_id, team_name: team_name)
|
32
|
+
self.team_id = Spaceship::ConnectAPI.client.portal_team_id
|
33
|
+
end
|
24
34
|
end
|
25
35
|
|
26
36
|
# The team ID of the currently logged in team
|
27
37
|
def team_id
|
28
|
-
return
|
38
|
+
return @team_id
|
29
39
|
end
|
30
40
|
|
31
41
|
def bundle_identifier_exists(username: nil, app_identifier: nil, platform: nil)
|
@@ -45,12 +55,8 @@ module Match
|
|
45
55
|
UI.user_error!("Couldn't find bundle identifier '#{app_identifier}' for the user '#{username}'")
|
46
56
|
end
|
47
57
|
|
48
|
-
def certificates_exists(username: nil, certificate_ids: []
|
49
|
-
|
50
|
-
platform = :macos.to_s
|
51
|
-
end
|
52
|
-
|
53
|
-
Spaceship.certificate.all(mac: platform == "macos").each do |cert|
|
58
|
+
def certificates_exists(username: nil, certificate_ids: [])
|
59
|
+
Spaceship::ConnectAPI::Certificate.all.each do |cert|
|
54
60
|
certificate_ids.delete(cert.id)
|
55
61
|
end
|
56
62
|
return if certificate_ids.empty?
|
@@ -23,6 +23,8 @@ module Match
|
|
23
23
|
attr_reader :username
|
24
24
|
attr_reader :team_id
|
25
25
|
attr_reader :team_name
|
26
|
+
attr_reader :api_key_path
|
27
|
+
attr_reader :api_key
|
26
28
|
|
27
29
|
# Managed values
|
28
30
|
attr_accessor :gc_storage
|
@@ -44,7 +46,9 @@ module Match
|
|
44
46
|
readonly: params[:readonly],
|
45
47
|
username: params[:username],
|
46
48
|
team_id: params[:team_id],
|
47
|
-
team_name: params[:team_name]
|
49
|
+
team_name: params[:team_name],
|
50
|
+
api_key_path: params[:api_key_path],
|
51
|
+
api_key: params[:api_key]
|
48
52
|
)
|
49
53
|
end
|
50
54
|
|
@@ -56,7 +60,9 @@ module Match
|
|
56
60
|
readonly: nil,
|
57
61
|
username: nil,
|
58
62
|
team_id: nil,
|
59
|
-
team_name: nil
|
63
|
+
team_name: nil,
|
64
|
+
api_key_path: nil,
|
65
|
+
api_key: nil)
|
60
66
|
@type = type if type
|
61
67
|
@platform = platform if platform
|
62
68
|
@google_cloud_project_id = google_cloud_project_id if google_cloud_project_id
|
@@ -67,6 +73,9 @@ module Match
|
|
67
73
|
@team_id = team_id
|
68
74
|
@team_name = team_name
|
69
75
|
|
76
|
+
@api_key_path = api_key_path
|
77
|
+
@api_key = api_key
|
78
|
+
|
70
79
|
@google_cloud_keys_file = ensure_keys_file_exists(google_cloud_keys_file, google_cloud_project_id)
|
71
80
|
|
72
81
|
if self.google_cloud_keys_file.to_s.length > 0
|
@@ -106,11 +115,19 @@ module Match
|
|
106
115
|
# see `prefixed_working_directory` comments for more details
|
107
116
|
return self.team_id
|
108
117
|
else
|
109
|
-
|
118
|
+
UI.user_error!("The `team_id` option is required. fastlane cannot automatically determine portal team id via the App Store Connect API (yet)") if self.team_id.to_s.empty?
|
119
|
+
|
120
|
+
spaceship = SpaceshipEnsure.new(self.username, self.team_id, self.team_name, self.api_token)
|
110
121
|
return spaceship.team_id
|
111
122
|
end
|
112
123
|
end
|
113
124
|
|
125
|
+
def api_token
|
126
|
+
api_token ||= Spaceship::ConnectAPI::Token.create(self.api_key) if self.api_key
|
127
|
+
api_token ||= Spaceship::ConnectAPI::Token.from_json_file(self.api_key_path) if self.api_key_path
|
128
|
+
return api_token
|
129
|
+
end
|
130
|
+
|
114
131
|
def prefixed_working_directory
|
115
132
|
# We fall back to "*", which means certificates and profiles
|
116
133
|
# from all teams that use this bucket would be installed. This is not ideal, but
|