fastlane 2.170.0 → 2.175.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +74 -74
- data/cert/lib/cert/options.rb +2 -2
- data/deliver/lib/deliver/app_screenshot.rb +5 -7
- data/deliver/lib/deliver/app_screenshot_validator.rb +108 -0
- data/deliver/lib/deliver/commands_generator.rb +1 -1
- data/deliver/lib/deliver/loader.rb +13 -29
- data/deliver/lib/deliver/options.rb +2 -2
- data/deliver/lib/deliver/setup.rb +8 -3
- data/deliver/lib/deliver/upload_metadata.rb +2 -0
- data/deliver/lib/deliver/upload_screenshots.rb +2 -1
- data/fastlane/lib/fastlane/actions/adb.rb +1 -1
- data/fastlane/lib/fastlane/actions/add_git_tag.rb +12 -3
- data/fastlane/lib/fastlane/actions/app_store_build_number.rb +2 -2
- data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +1 -0
- data/fastlane/lib/fastlane/actions/appetize.rb +13 -1
- data/fastlane/lib/fastlane/actions/artifactory.rb +36 -3
- data/fastlane/lib/fastlane/actions/build_and_upload_to_appetize.rb +10 -2
- data/fastlane/lib/fastlane/actions/build_app.rb +3 -1
- data/fastlane/lib/fastlane/actions/carthage.rb +22 -0
- data/fastlane/lib/fastlane/actions/cocoapods.rb +15 -1
- data/fastlane/lib/fastlane/actions/create_pull_request.rb +16 -1
- data/fastlane/lib/fastlane/actions/create_xcframework.rb +118 -0
- data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +8 -2
- data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +5 -1
- data/fastlane/lib/fastlane/actions/download_app_privacy_details_from_app_store.rb +142 -0
- data/fastlane/lib/fastlane/actions/download_dsyms.rb +5 -16
- data/fastlane/lib/fastlane/actions/git_commit.rb +7 -3
- data/fastlane/lib/fastlane/actions/github_api.rb +14 -3
- data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +2 -2
- data/fastlane/lib/fastlane/actions/nexus_upload.rb +1 -0
- data/fastlane/lib/fastlane/actions/pod_push.rb +9 -0
- data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +9 -1
- data/fastlane/lib/fastlane/actions/register_device.rb +3 -3
- data/fastlane/lib/fastlane/actions/register_devices.rb +4 -3
- data/fastlane/lib/fastlane/actions/set_changelog.rb +2 -2
- data/fastlane/lib/fastlane/actions/set_github_release.rb +21 -8
- data/fastlane/lib/fastlane/actions/slack.rb +4 -5
- data/fastlane/lib/fastlane/actions/spm.rb +2 -2
- data/fastlane/lib/fastlane/actions/swiftlint.rb +4 -4
- data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +1 -1
- data/fastlane/lib/fastlane/actions/upload_app_privacy_details_to_app_store.rb +4 -2
- data/fastlane/lib/fastlane/cli_tools_distributor.rb +3 -0
- data/fastlane/lib/fastlane/documentation/actions_list.rb +2 -2
- data/fastlane/lib/fastlane/helper/adb_helper.rb +1 -1
- data/fastlane/lib/fastlane/helper/gem_helper.rb +2 -2
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Actions.swift +1 -1
- data/fastlane/swift/Appfile.swift +1 -1
- data/fastlane/swift/ArgumentProcessor.swift +1 -1
- data/fastlane/swift/ControlCommand.swift +1 -1
- data/fastlane/swift/Deliverfile.swift +2 -2
- data/fastlane/swift/DeliverfileProtocol.swift +2 -2
- data/fastlane/swift/Fastlane.swift +213 -38
- data/fastlane/swift/Gymfile.swift +2 -2
- data/fastlane/swift/GymfileProtocol.swift +11 -3
- data/fastlane/swift/LaneFileProtocol.swift +1 -1
- data/fastlane/swift/MainProcess.swift +1 -1
- data/fastlane/swift/Matchfile.swift +2 -2
- data/fastlane/swift/MatchfileProtocol.swift +2 -2
- data/fastlane/swift/Plugins.swift +1 -1
- data/fastlane/swift/Precheckfile.swift +2 -2
- data/fastlane/swift/PrecheckfileProtocol.swift +6 -2
- data/fastlane/swift/RubyCommand.swift +1 -1
- data/fastlane/swift/RubyCommandable.swift +1 -1
- data/fastlane/swift/Runner.swift +2 -2
- data/fastlane/swift/RunnerArgument.swift +1 -1
- data/fastlane/swift/Scanfile.swift +2 -2
- data/fastlane/swift/ScanfileProtocol.swift +14 -2
- data/fastlane/swift/Screengrabfile.swift +2 -2
- data/fastlane/swift/ScreengrabfileProtocol.swift +2 -2
- data/fastlane/swift/Snapshotfile.swift +2 -2
- data/fastlane/swift/SnapshotfileProtocol.swift +15 -3
- data/fastlane/swift/SocketClient.swift +1 -1
- data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
- data/fastlane/swift/SocketResponse.swift +1 -1
- data/fastlane/swift/formatting/Brewfile.lock.json +20 -14
- data/fastlane/swift/main.swift +1 -1
- data/fastlane_core/lib/fastlane_core/command_executor.rb +3 -9
- data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +1 -1
- data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +23 -0
- data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +9 -5
- data/fastlane_core/lib/fastlane_core/helper.rb +28 -7
- data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +41 -16
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +3 -4
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +1 -1
- data/fastlane_core/lib/fastlane_core/project.rb +41 -14
- data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +2 -2
- data/frameit/lib/frameit/device_types.rb +7 -1
- data/gym/lib/gym/error_handler.rb +8 -0
- data/gym/lib/gym/generators/build_command_generator.rb +3 -1
- data/gym/lib/gym/generators/package_command_generator_xcode7.rb +2 -2
- data/gym/lib/gym/options.rb +12 -2
- data/match/lib/match/encryption/openssl.rb +4 -2
- data/match/lib/match/nuke.rb +5 -0
- data/match/lib/match/options.rb +2 -2
- data/match/lib/match/storage/git_storage.rb +14 -10
- data/pilot/lib/pilot/options.rb +2 -2
- data/precheck/lib/precheck/options.rb +8 -3
- data/precheck/lib/precheck/rule_processor.rb +1 -1
- data/precheck/lib/precheck/runner.rb +1 -1
- data/scan/lib/scan/options.rb +15 -0
- data/scan/lib/scan/runner.rb +6 -1
- data/scan/lib/scan/slack_poster.rb +4 -1
- data/scan/lib/scan/test_command_generator.rb +3 -1
- data/screengrab/lib/screengrab/android_environment.rb +2 -2
- data/screengrab/lib/screengrab/runner.rb +2 -0
- data/sigh/lib/sigh/options.rb +2 -2
- data/sigh/lib/sigh/runner.rb +1 -1
- data/snapshot/lib/assets/SnapshotHelper.swift +1 -1
- data/snapshot/lib/snapshot/options.rb +17 -2
- data/snapshot/lib/snapshot/update.rb +1 -1
- data/spaceship/README.md +2 -2
- data/spaceship/lib/spaceship/client.rb +14 -1
- data/spaceship/lib/spaceship/connect_api/api_client.rb +17 -2
- data/spaceship/lib/spaceship/connect_api/models/app.rb +6 -0
- data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +7 -1
- data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +9 -0
- data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +24 -0
- data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +26 -4
- data/spaceship/lib/spaceship/connect_api/models/device.rb +26 -0
- data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +53 -0
- data/spaceship/lib/spaceship/connect_api/response.rb +3 -1
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +12 -0
- data/spaceship/lib/spaceship/connect_api/token.rb +1 -1
- data/spaceship/lib/spaceship/playground.rb +2 -2
- data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
- data/spaceship/lib/spaceship/two_step_or_factor_client.rb +1 -0
- data/spaceship/lib/spaceship/upgrade_2fa_later_client.rb +91 -0
- metadata +51 -21
- data/fastlane/lib/fastlane/actions/.download_dsyms.rb.swp +0 -0
- data/spaceship/lib/spaceship/connect_api/models/.app_data_usage_data_protection.rb.swp +0 -0
@@ -8,7 +8,7 @@ module Snapshot
|
|
8
8
|
def self.find_helper
|
9
9
|
paths = Dir["./**/SnapshotHelper.swift"] + Dir["./**/SnapshotHelperXcode8.swift"]
|
10
10
|
# exclude assets in gym
|
11
|
-
paths.reject { |p| p.include?("snapshot/lib/assets/") }
|
11
|
+
paths.reject { |p| p.include?("snapshot/lib/assets/") || p.include?("DerivedData") }
|
12
12
|
end
|
13
13
|
|
14
14
|
def update(force: false)
|
data/spaceship/README.md
CHANGED
@@ -83,7 +83,7 @@ Using spaceship, the execution time of [_sigh_](https://docs.fastlane.tools/acti
|
|
83
83
|
|
84
84
|
_spaceship_ is part of _fastlane_:
|
85
85
|
|
86
|
-
|
86
|
+
gem install fastlane
|
87
87
|
|
88
88
|
# Usage
|
89
89
|
|
@@ -93,7 +93,7 @@ To try _spaceship_, just run `fastlane spaceship`. It will automatically start t
|
|
93
93
|
|
94
94
|
![assets/docs/Playground.png](assets/docs/Playground.png)
|
95
95
|
|
96
|
-
This requires you to install `pry` using `
|
96
|
+
This requires you to install `pry` using `gem install pry`. `pry` is not installed by default, as most [_fastlane_](https://fastlane.tools) users won't need the `spaceship playground`. You can add the `pry` dependency to your `Gemfile`.
|
97
97
|
|
98
98
|
## Apple Developer Portal API
|
99
99
|
|
@@ -403,6 +403,7 @@ module Spaceship
|
|
403
403
|
# This will also handle 2 step verification and 2 factor authentication
|
404
404
|
#
|
405
405
|
# It is called in `send_login_request` of sub classes (which the method `login`, above, transferred over to via `do_login`)
|
406
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
406
407
|
def send_shared_login_request(user, password)
|
407
408
|
# Check if we have a cached/valid session
|
408
409
|
#
|
@@ -506,9 +507,19 @@ module Spaceship
|
|
506
507
|
# User Credentials are wrong
|
507
508
|
raise InvalidUserCredentialsError.new, "Invalid username and password combination. Used '#{user}' as the username."
|
508
509
|
elsif response.status == 412 && AUTH_TYPES.include?(response.body["authType"])
|
510
|
+
|
511
|
+
if try_upgrade_2fa_later(response)
|
512
|
+
store_cookie
|
513
|
+
fetch_olympus_session
|
514
|
+
return true
|
515
|
+
end
|
516
|
+
|
509
517
|
# Need to acknowledge Apple ID and Privacy statement - https://github.com/fastlane/fastlane/issues/12577
|
510
518
|
# Looking for status of 412 might be enough but might be safer to keep looking only at what is being reported
|
511
|
-
raise AppleIDAndPrivacyAcknowledgementNeeded.new, "Need to acknowledge to Apple's Apple ID and Privacy statement.
|
519
|
+
raise AppleIDAndPrivacyAcknowledgementNeeded.new, "Need to acknowledge to Apple's Apple ID and Privacy statement. " \
|
520
|
+
"Please manually log into https://appleid.apple.com (or https://appstoreconnect.apple.com) to acknowledge the statement. " \
|
521
|
+
"Your account might also be asked to upgrade to 2FA. " \
|
522
|
+
"Set SPACESHIP_SKIP_2FA_UPGRADE=1 for fastlane to automaticaly bypass 2FA upgrade if possible."
|
512
523
|
elsif (response['Set-Cookie'] || "").include?("itctx")
|
513
524
|
raise "Looks like your Apple ID is not enabled for App Store Connect, make sure to be able to login online"
|
514
525
|
else
|
@@ -517,6 +528,7 @@ module Spaceship
|
|
517
528
|
end
|
518
529
|
end
|
519
530
|
end
|
531
|
+
# rubocop:enable Metrics/PerceivedComplexity
|
520
532
|
|
521
533
|
# Get the `itctx` from the new (22nd May 2017) API endpoint "olympus"
|
522
534
|
# Update (29th March 2019) olympus migrates to new appstoreconnect API
|
@@ -925,3 +937,4 @@ module Spaceship
|
|
925
937
|
end
|
926
938
|
|
927
939
|
require 'spaceship/two_step_or_factor_client'
|
940
|
+
require 'spaceship/upgrade_2fa_later_client'
|
@@ -196,7 +196,7 @@ module Spaceship
|
|
196
196
|
|
197
197
|
store_csrf_tokens(response)
|
198
198
|
|
199
|
-
return Spaceship::ConnectAPI::Response.new(body: response.body, status: response.status, client: self)
|
199
|
+
return Spaceship::ConnectAPI::Response.new(body: response.body, status: response.status, headers: response.headers, client: self)
|
200
200
|
end
|
201
201
|
|
202
202
|
def handle_401(response)
|
@@ -247,8 +247,23 @@ module Spaceship
|
|
247
247
|
# ]
|
248
248
|
# }
|
249
249
|
|
250
|
+
# Detail is missing in this response making debugging super hard
|
251
|
+
# {"errors" =>
|
252
|
+
# [
|
253
|
+
# {
|
254
|
+
# "id"=>"80ea6cff-0043-4543-9cd1-3e26b0fce383",
|
255
|
+
# "status"=>"409",
|
256
|
+
# "code"=>"ENTITY_ERROR.RELATIONSHIP.INVALID",
|
257
|
+
# "title"=>"The provided entity includes a relationship with an invalid value",
|
258
|
+
# "source"=>{
|
259
|
+
# "pointer"=>"/data/relationships/primarySubcategoryOne"
|
260
|
+
# }
|
261
|
+
# }
|
262
|
+
# ]
|
263
|
+
# }
|
264
|
+
|
250
265
|
return response.body['errors'].map do |error|
|
251
|
-
messages = [[error['title'], error['detail']].compact.join(" - ")]
|
266
|
+
messages = [[error['title'], error['detail'], error.dig("source", "pointer")].compact.join(" - ")]
|
252
267
|
|
253
268
|
meta = error["meta"] || {}
|
254
269
|
associated_errors = meta["associatedErrors"] || {}
|
@@ -144,6 +144,12 @@ module Spaceship
|
|
144
144
|
end.first
|
145
145
|
end
|
146
146
|
|
147
|
+
def fetch_latest_app_info(client: nil, includes: Spaceship::ConnectAPI::AppInfo::ESSENTIAL_INCLUDES)
|
148
|
+
client ||= Spaceship::ConnectAPI
|
149
|
+
resp = client.get_app_infos(app_id: id, includes: includes)
|
150
|
+
return resp.to_models.first
|
151
|
+
end
|
152
|
+
|
147
153
|
#
|
148
154
|
# Available Territories
|
149
155
|
#
|
@@ -21,6 +21,9 @@ module Spaceship
|
|
21
21
|
attr_accessor :created_date
|
22
22
|
|
23
23
|
attr_accessor :app_store_version_submission
|
24
|
+
attr_accessor :app_store_version_phased_release
|
25
|
+
attr_accessor :app_store_review_detail
|
26
|
+
attr_accessor :app_store_version_localizations
|
24
27
|
|
25
28
|
module AppStoreState
|
26
29
|
READY_FOR_SALE = "READY_FOR_SALE"
|
@@ -58,7 +61,10 @@ module Spaceship
|
|
58
61
|
"createdDate" => "created_date",
|
59
62
|
|
60
63
|
"appStoreVersionSubmission" => "app_store_version_submission",
|
61
|
-
"build" => "build"
|
64
|
+
"build" => "build",
|
65
|
+
"appStoreVersionPhasedRelease" => "app_store_version_phased_release",
|
66
|
+
"appStoreReviewDetail" => "app_store_review_detail",
|
67
|
+
"appStoreVersionLocalizations" => "app_store_version_localizations"
|
62
68
|
})
|
63
69
|
|
64
70
|
ESSENTIAL_INCLUDES = [
|
@@ -38,6 +38,15 @@ module Spaceship
|
|
38
38
|
return client.post_bulk_beta_tester_assignments(beta_group_id: id, beta_testers: beta_testers)
|
39
39
|
end
|
40
40
|
|
41
|
+
def update(client: nil, attributes: nil)
|
42
|
+
return if attributes.empty?
|
43
|
+
|
44
|
+
client ||= Spaceship::ConnectAPI
|
45
|
+
|
46
|
+
attributes = reverse_attr_mapping(attributes)
|
47
|
+
return client.patch_group(group_id: id, attributes: attributes).first
|
48
|
+
end
|
49
|
+
|
41
50
|
def delete!
|
42
51
|
return Spaceship::ConnectAPI.delete_beta_group(group_id: id)
|
43
52
|
end
|
@@ -56,6 +56,30 @@ module Spaceship
|
|
56
56
|
client ||= Spaceship::ConnectAPI
|
57
57
|
return client.get_bundle_id(bundle_id_id: bundle_id_id, includes: includes).first
|
58
58
|
end
|
59
|
+
|
60
|
+
def self.create(client: nil, name: nil, platform: nil, identifier: nil, seed_id: nil)
|
61
|
+
client ||= Spaceship::ConnectAPI
|
62
|
+
resp = client.post_bundle_id(name: name, platform: platform, identifier: identifier, seed_id: seed_id)
|
63
|
+
return resp.to_models.first
|
64
|
+
end
|
65
|
+
|
66
|
+
#
|
67
|
+
# BundleIdsCapabilities
|
68
|
+
#
|
69
|
+
|
70
|
+
def get_capabilities(client: nil, includes: nil)
|
71
|
+
client ||= Spaceship::ConnectAPI
|
72
|
+
resp = client.get_bundle_id_capabilities(bundle_id_id: id, includes: includes)
|
73
|
+
return resp.to_models
|
74
|
+
end
|
75
|
+
|
76
|
+
def create_capability(capability_type, settings: [], client: nil)
|
77
|
+
raise "capability_type is required " if capability_type.nil?
|
78
|
+
|
79
|
+
client ||= Spaceship::ConnectAPI
|
80
|
+
resp = client.post_bundle_id_capability(bundle_id_id: id, capability_type: capability_type, settings: settings)
|
81
|
+
return resp.to_models.first
|
82
|
+
end
|
59
83
|
end
|
60
84
|
end
|
61
85
|
end
|
@@ -41,6 +41,21 @@ module Spaceship
|
|
41
41
|
MARZIPAN = "MARZIPAN" # Catalyst
|
42
42
|
end
|
43
43
|
|
44
|
+
module Settings
|
45
|
+
ICLOUD_VERSION = "ICLOUD_VERSION"
|
46
|
+
DATA_PROTECTION_PERMISSION_LEVEL = "DATA_PROTECTION_PERMISSION_LEVEL"
|
47
|
+
APPLE_ID_AUTH_APP_CONSENT = "APPLE_ID_AUTH_APP_CONSENT"
|
48
|
+
end
|
49
|
+
|
50
|
+
module Options
|
51
|
+
XCODE_5 = "XCODE_5"
|
52
|
+
XCODE_6 = "XCODE_6"
|
53
|
+
COMPLETE_PROTECTION = "COMPLETE_PROTECTION"
|
54
|
+
PROTECTED_UNLESS_OPEN = "PROTECTED_UNLESS_OPEN"
|
55
|
+
PROTECTED_UNTIL_FIRST_USER_AUTH = "PROTECTED_UNTIL_FIRST_USER_AUTH"
|
56
|
+
PRIMARY_APP_CONSENT = "PRIMARY_APP_CONSENT"
|
57
|
+
end
|
58
|
+
|
44
59
|
def self.type
|
45
60
|
return "bundleIdCapabilities"
|
46
61
|
end
|
@@ -59,14 +74,21 @@ module Spaceship
|
|
59
74
|
# API
|
60
75
|
#
|
61
76
|
|
62
|
-
def self.all(client: nil,
|
77
|
+
def self.all(client: nil, bundle_id_id:, limit: nil)
|
78
|
+
client ||= Spaceship::ConnectAPI
|
79
|
+
resp = client.get_bundle_id_capabilities(bundle_id_id: bundle_id_id, limit: limit).all_pages
|
80
|
+
return resp.flat_map(&:to_models)
|
81
|
+
end
|
82
|
+
|
83
|
+
def self.create(client: nil, bundle_id_id:, capability_type:, settings: [])
|
63
84
|
client ||= Spaceship::ConnectAPI
|
64
|
-
|
85
|
+
resp = client.post_bundle_id_capability(bundle_id_id: bundle_id_id, capability_type: capability_type, settings: settings)
|
86
|
+
return resp.to_models.first
|
65
87
|
end
|
66
88
|
|
67
|
-
def
|
89
|
+
def delete!(client: nil, filter: {}, includes: nil, limit: nil, sort: nil)
|
68
90
|
client ||= Spaceship::ConnectAPI
|
69
|
-
|
91
|
+
client.delete_bundle_id_capability(bundle_id_capability_id: id)
|
70
92
|
end
|
71
93
|
end
|
72
94
|
end
|
@@ -54,6 +54,32 @@ module Spaceship
|
|
54
54
|
return resps.flat_map(&:to_models)
|
55
55
|
end
|
56
56
|
|
57
|
+
# @param client [ConnectAPI] ConnectAPI client.
|
58
|
+
# @param platform [String] The platform of the device.
|
59
|
+
# @param include_disabled [Bool] Whether to include disable devices. false by default.
|
60
|
+
# @return (Device) Find a device based on the UDID of the device. nil if no device was found.
|
61
|
+
def self.find_by_udid(device_udid, client: nil, platform: nil, include_disabled: false)
|
62
|
+
self.all(client: client).find do |device|
|
63
|
+
device.udid.casecmp(device_udid) == 0 && (include_disabled ? true : device.enabled?)
|
64
|
+
end
|
65
|
+
end
|
66
|
+
|
67
|
+
# @param client [ConnectAPI] ConnectAPI client.
|
68
|
+
# @param name [String] The name to be assigned to the device, if it needs to be created.
|
69
|
+
# @param platform [String] The platform of the device.
|
70
|
+
# @param include_disabled [Bool] Whether to include disable devices. false by default.
|
71
|
+
# @return (Device) Find a device based on the UDID of the device. If no device was found, nil if no device was found.
|
72
|
+
def self.find_or_create(device_udid, client: nil, name: nil, platform: nil, include_disabled: false)
|
73
|
+
existing = self.find_by_udid(device_udid, client: client, platform: platform)
|
74
|
+
return existing if existing
|
75
|
+
return self.create(client: client, name: name, platform: platform, udid: device_udid)
|
76
|
+
end
|
77
|
+
|
78
|
+
# @param client [ConnectAPI] ConnectAPI client.
|
79
|
+
# @param name [String] The name to be assigned to the device.
|
80
|
+
# @param platform [String] The platform of the device.
|
81
|
+
# @param udid [String] The udid of the device being created.
|
82
|
+
# @return (Device) Find a device based on the UDID of the device. nil if no device was found.
|
57
83
|
def self.create(client: nil, name: nil, platform: nil, udid: nil)
|
58
84
|
client ||= Spaceship::ConnectAPI
|
59
85
|
resp = client.post_device(name: name, platform: platform, udid: udid)
|
@@ -27,6 +27,59 @@ module Spaceship
|
|
27
27
|
provisioning_request_client.get("bundleIds/#{bundle_id_id}", params)
|
28
28
|
end
|
29
29
|
|
30
|
+
def post_bundle_id(name:, platform:, identifier:, seed_id:)
|
31
|
+
attributes = {
|
32
|
+
name: name,
|
33
|
+
platform: platform,
|
34
|
+
identifier: identifier,
|
35
|
+
seedId: seed_id
|
36
|
+
}
|
37
|
+
|
38
|
+
body = {
|
39
|
+
data: {
|
40
|
+
attributes: attributes,
|
41
|
+
type: "bundleIds"
|
42
|
+
}
|
43
|
+
}
|
44
|
+
|
45
|
+
provisioning_request_client.post("bundleIds", body)
|
46
|
+
end
|
47
|
+
|
48
|
+
#
|
49
|
+
# bundleIdCapability
|
50
|
+
#
|
51
|
+
|
52
|
+
def get_bundle_id_capabilities(bundle_id_id:, includes: nil, limit: nil, sort: nil)
|
53
|
+
params = provisioning_request_client.build_params(filter: nil, includes: includes, limit: limit, sort: sort)
|
54
|
+
provisioning_request_client.get("bundleIds/#{bundle_id_id}/bundleIdCapabilities", params)
|
55
|
+
end
|
56
|
+
|
57
|
+
def post_bundle_id_capability(bundle_id_id:, capability_type:, settings: [])
|
58
|
+
body = {
|
59
|
+
data: {
|
60
|
+
attributes: {
|
61
|
+
capabilityType: capability_type,
|
62
|
+
settings: settings
|
63
|
+
},
|
64
|
+
type: "bundleIdCapabilities",
|
65
|
+
relationships: {
|
66
|
+
bundleId: {
|
67
|
+
data: {
|
68
|
+
type: "bundleIds",
|
69
|
+
id: bundle_id_id
|
70
|
+
}
|
71
|
+
}
|
72
|
+
}
|
73
|
+
}
|
74
|
+
}
|
75
|
+
|
76
|
+
provisioning_request_client.post("bundleIdCapabilities", body)
|
77
|
+
end
|
78
|
+
|
79
|
+
def delete_bundle_id_capability(bundle_id_capability_id:)
|
80
|
+
provisioning_request_client.delete("bundleIdCapabilities/#{bundle_id_capability_id}")
|
81
|
+
end
|
82
|
+
|
30
83
|
#
|
31
84
|
# certificates
|
32
85
|
#
|
@@ -6,11 +6,13 @@ module Spaceship
|
|
6
6
|
include Enumerable
|
7
7
|
attr_reader :body
|
8
8
|
attr_reader :status
|
9
|
+
attr_reader :headers
|
9
10
|
attr_reader :client
|
10
11
|
|
11
|
-
def initialize(body: nil, status: nil, client: nil)
|
12
|
+
def initialize(body: nil, status: nil, headers: nil, client: nil)
|
12
13
|
@body = body
|
13
14
|
@status = status
|
15
|
+
@headers = headers
|
14
16
|
@client = client
|
15
17
|
end
|
16
18
|
|
@@ -214,6 +214,18 @@ module Spaceship
|
|
214
214
|
test_flight_request_client.post("betaGroups", body)
|
215
215
|
end
|
216
216
|
|
217
|
+
def patch_group(group_id: nil, attributes: {})
|
218
|
+
body = {
|
219
|
+
data: {
|
220
|
+
attributes: attributes,
|
221
|
+
id: group_id,
|
222
|
+
type: "betaGroups"
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
test_flight_request_client.patch("betaGroups/#{group_id}", body)
|
227
|
+
end
|
228
|
+
|
217
229
|
def delete_beta_group(group_id: nil)
|
218
230
|
raise "group_id is nil" if group_id.nil?
|
219
231
|
|
@@ -40,7 +40,7 @@ module Spaceship
|
|
40
40
|
self.create(json)
|
41
41
|
end
|
42
42
|
|
43
|
-
def self.create(key_id: nil, issuer_id: nil, filepath: nil, key: nil, is_key_content_base64: false, duration: nil, in_house: nil)
|
43
|
+
def self.create(key_id: nil, issuer_id: nil, filepath: nil, key: nil, is_key_content_base64: false, duration: nil, in_house: nil, **)
|
44
44
|
key_id ||= ENV['SPACESHIP_CONNECT_API_KEY_ID']
|
45
45
|
issuer_id ||= ENV['SPACESHIP_CONNECT_API_ISSUER_ID']
|
46
46
|
filepath ||= ENV['SPACESHIP_CONNECT_API_KEY_FILEPATH']
|
@@ -13,8 +13,8 @@ module Spaceship
|
|
13
13
|
rescue Gem::LoadError
|
14
14
|
puts("Could not find gem 'pry'".red)
|
15
15
|
puts("")
|
16
|
-
puts("If you installed spaceship using `
|
17
|
-
puts("
|
16
|
+
puts("If you installed spaceship using `gem install spaceship` run")
|
17
|
+
puts(" gem install pry".yellow)
|
18
18
|
puts("to install the missing gem")
|
19
19
|
puts("")
|
20
20
|
puts("If you use a Gemfile add this to your Gemfile:")
|
@@ -579,10 +579,10 @@ module Spaceship
|
|
579
579
|
}
|
580
580
|
|
581
581
|
r = request(:post) do |req|
|
582
|
-
req.url("https://
|
582
|
+
req.url("https://appstoreconnect.apple.com/analytics/api/v1/data/time-series")
|
583
583
|
req.body = data.to_json
|
584
584
|
req.headers['Content-Type'] = 'application/json'
|
585
|
-
req.headers['X-Requested-By'] = '
|
585
|
+
req.headers['X-Requested-By'] = 'appstoreconnect.apple.com'
|
586
586
|
end
|
587
587
|
|
588
588
|
data = parse_response(r)
|
@@ -4,6 +4,7 @@ require_relative 'tunes/tunes_client'
|
|
4
4
|
module Spaceship
|
5
5
|
class Client
|
6
6
|
def handle_two_step_or_factor(response)
|
7
|
+
raise "2FA can only be performed in interactive mode" if ENV["SPACESHIP_ONLY_ALLOW_INTERACTIVE_2FA"] == "true" && ENV["FASTLANE_IS_INTERACTIVE"] == "false"
|
7
8
|
# extract `x-apple-id-session-id` and `scnt` from response, to be used by `update_request_headers`
|
8
9
|
@x_apple_id_session_id = response["x-apple-id-session-id"]
|
9
10
|
@scnt = response["scnt"]
|
@@ -0,0 +1,91 @@
|
|
1
|
+
require_relative 'globals'
|
2
|
+
require_relative 'tunes/tunes_client'
|
3
|
+
|
4
|
+
module Spaceship
|
5
|
+
class Client
|
6
|
+
def try_upgrade_2fa_later(response)
|
7
|
+
if ENV['SPACESHIP_SKIP_2FA_UPGRADE'].nil?
|
8
|
+
return false
|
9
|
+
end
|
10
|
+
|
11
|
+
puts("This account is being prompted to upgrade to 2FA")
|
12
|
+
puts("Attempting to automatically bypass the upgrade until a later date")
|
13
|
+
puts("To disable this, remove SPACESHIP_SKIP_2FA_UPGRADE=1 environment variable")
|
14
|
+
|
15
|
+
# Get URL that requests a repair and gets the widget key
|
16
|
+
widget_key_location = response.headers['location']
|
17
|
+
uri = URI.parse(widget_key_location)
|
18
|
+
params = CGI.parse(uri.query)
|
19
|
+
|
20
|
+
widget_key = params.dig('widgetKey', 0)
|
21
|
+
if widget_key.nil?
|
22
|
+
STDERR.puts("Couldn't find widgetKey to continue with requests")
|
23
|
+
return false
|
24
|
+
end
|
25
|
+
|
26
|
+
# Step 1 - Request repair
|
27
|
+
response_repair = request(:get) do |req|
|
28
|
+
req.url(widget_key_location)
|
29
|
+
end
|
30
|
+
|
31
|
+
# Step 2 - Request repair options
|
32
|
+
response_repair_options = request(:get) do |req|
|
33
|
+
req.url("https://appleid.apple.com/account/manage/repair/options")
|
34
|
+
|
35
|
+
req.headers['scnt'] = response_repair.headers['scnt']
|
36
|
+
req.headers['X-Apple-Id-Session-Id'] = response.headers['X-Apple-Id-Session-Id']
|
37
|
+
req.headers['X-Apple-Session-Token'] = response.headers['X-Apple-Repair-Session-Token']
|
38
|
+
|
39
|
+
req.headers['X-Apple-Skip-Repair-Attributes'] = '[]'
|
40
|
+
req.headers['X-Apple-Widget-Key'] = widget_key
|
41
|
+
|
42
|
+
req.headers['Content-Type'] = 'application/json'
|
43
|
+
req.headers['X-Requested-With'] = 'XMLHttpRequest'
|
44
|
+
req.headers['Accept'] = 'application/json, text/javascript'
|
45
|
+
end
|
46
|
+
|
47
|
+
# Step 3 - Request setup later
|
48
|
+
request(:get) do |req|
|
49
|
+
req.url("https://appleid.apple.com/account/security/upgrade/setuplater")
|
50
|
+
|
51
|
+
req.headers['scnt'] = response_repair_options.headers['scnt']
|
52
|
+
req.headers['X-Apple-Id-Session-Id'] = response.headers['X-Apple-Id-Session-Id']
|
53
|
+
req.headers['X-Apple-Session-Token'] = response_repair_options.headers['x-apple-session-token']
|
54
|
+
req.headers['X-Apple-Skip-Repair-Attributes'] = '[]'
|
55
|
+
req.headers['X-Apple-Widget-Key'] = widget_key
|
56
|
+
|
57
|
+
req.headers['Content-Type'] = 'application/json'
|
58
|
+
req.headers['X-Requested-With'] = 'XMLHttpRequest'
|
59
|
+
req.headers['Accept'] = 'application/json, text/javascript'
|
60
|
+
end
|
61
|
+
|
62
|
+
# Step 4 - Post complete
|
63
|
+
response_repair_complete = request(:post) do |req|
|
64
|
+
req.url("https://idmsa.apple.com/appleauth/auth/repair/complete")
|
65
|
+
|
66
|
+
req.body = ''
|
67
|
+
req.headers['scnt'] = response.headers['scnt']
|
68
|
+
req.headers['X-Apple-Id-Session-Id'] = response.headers['X-Apple-Id-Session-Id']
|
69
|
+
req.headers['X-Apple-Repair-Session-Token'] = response_repair_options.headers['X-Apple-Session-Token']
|
70
|
+
|
71
|
+
req.headers['X-Apple-Widget-Key'] = widget_key
|
72
|
+
|
73
|
+
req.headers['Content-Type'] = 'application/json'
|
74
|
+
req.headers['X-Requested-With'] = 'XMLHttpRequest'
|
75
|
+
req.headers['Accept'] = 'application/json;charset=utf-8'
|
76
|
+
end
|
77
|
+
|
78
|
+
if response_repair_complete.status == 204
|
79
|
+
return true
|
80
|
+
else
|
81
|
+
STDERR.puts("Failed with status code of #{response_repair_complete.status}")
|
82
|
+
return false
|
83
|
+
end
|
84
|
+
rescue => error
|
85
|
+
STDERR.puts(error.backtrace)
|
86
|
+
STDERR.puts("Failed to bypass 2FA upgrade")
|
87
|
+
STDERR.puts("To disable this from trying again, set SPACESHIP_SKIP_UPGRADE_2FA_LATER=1")
|
88
|
+
return false
|
89
|
+
end
|
90
|
+
end
|
91
|
+
end
|