fastlane 2.102.0 → 2.103.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/credentials_manager/lib/credentials_manager/account_manager.rb +9 -4
- data/deliver/lib/assets/DeliverfileDefault.swift +10 -0
- data/deliver/lib/assets/summary.html.erb +3 -3
- data/deliver/lib/deliver/html_generator.rb +9 -0
- data/deliver/lib/deliver/options.rb +56 -35
- data/deliver/lib/deliver/setup.rb +1 -2
- data/deliver/lib/deliver/submit_for_review.rb +2 -2
- data/deliver/lib/deliver/upload_metadata.rb +1 -1
- data/fastlane/lib/fastlane/action.rb +1 -0
- data/fastlane/lib/fastlane/actions/actions_helper.rb +11 -1
- data/fastlane/lib/fastlane/actions/app_store_build_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/changelog_from_git_commits.rb +11 -3
- data/fastlane/lib/fastlane/actions/check_app_store_metadata.rb +1 -1
- data/fastlane/lib/fastlane/actions/create_app_online.rb +1 -1
- data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +15 -1
- data/fastlane/lib/fastlane/actions/docs/create_app_online.md +21 -0
- data/fastlane/lib/fastlane/actions/download_dsyms.rb +1 -1
- data/fastlane/lib/fastlane/actions/gradle.rb +4 -0
- data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/set_changelog.rb +1 -1
- data/fastlane/lib/fastlane/documentation/markdown_docs_generator.rb +2 -0
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +1 -0
- data/fastlane/lib/fastlane/setup/setup_ios.rb +7 -5
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/DeliverfileProtocol.swift +13 -13
- data/fastlane/swift/Fastlane.swift +45 -43
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane_core/lib/fastlane_core/command_executor.rb +9 -14
- data/fastlane_core/lib/fastlane_core/fastlane_pty.rb +12 -3
- data/fastlane_core/lib/fastlane_core/helper.rb +22 -10
- data/fastlane_core/lib/fastlane_core/ipa_upload_package_builder.rb +1 -1
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +22 -15
- data/pilot/lib/pilot/build_manager.rb +1 -1
- data/pilot/lib/pilot/tester_importer.rb +2 -2
- data/precheck/lib/precheck/rules/unreachable_urls_rule.rb +3 -3
- data/produce/lib/produce/cloud_container.rb +82 -0
- data/produce/lib/produce/commands_generator.rb +34 -0
- data/produce/lib/produce/itunes_connect.rb +1 -1
- data/snapshot/lib/snapshot/commands_generator.rb +0 -2
- data/snapshot/lib/snapshot/reports_generator.rb +8 -3
- data/snapshot/lib/snapshot/runner.rb +9 -0
- data/spaceship/README.md +2 -2
- data/spaceship/lib/spaceship/client.rb +6 -2
- data/spaceship/lib/spaceship/errors.rb +3 -0
- data/spaceship/lib/spaceship/portal/app.rb +22 -1
- data/spaceship/lib/spaceship/portal/cloud_container.rb +74 -0
- data/spaceship/lib/spaceship/portal/portal.rb +1 -0
- data/spaceship/lib/spaceship/portal/portal_client.rb +45 -4
- data/spaceship/lib/spaceship/portal/spaceship.rb +9 -0
- data/spaceship/lib/spaceship/test_flight/client.rb +1 -1
- data/spaceship/lib/spaceship/tunes/app_ratings.rb +2 -2
- data/spaceship/lib/spaceship/tunes/app_submission.rb +9 -3
- data/spaceship/lib/spaceship/tunes/app_version.rb +1 -1
- data/spaceship/lib/spaceship/tunes/application.rb +4 -4
- data/spaceship/lib/spaceship/tunes/tunes_client.rb +13 -2
- data/supply/lib/supply/client.rb +0 -1
- metadata +22 -20
@@ -78,16 +78,21 @@ module Snapshot
|
|
78
78
|
'iPhone 6 Plus' => "iPhone 6 Plus (5.5-Inch)",
|
79
79
|
'iPhone 6s' => "iPhone 6s (4.7-Inch)",
|
80
80
|
'iPhone 6' => "iPhone 6 (4.7-Inch)",
|
81
|
-
'iPhone 5s' => "iPhone
|
81
|
+
'iPhone 5s' => "iPhone 5s (4-Inch)",
|
82
|
+
'iPhone 5' => "iPhone 5 (4-Inch)",
|
82
83
|
'iPhone SE' => "iPhone SE",
|
83
|
-
'iPhone 4s' => "iPhone
|
84
|
-
'iPad
|
84
|
+
'iPhone 4s' => "iPhone 4s (3.5-Inch)",
|
85
|
+
'iPad 2' => 'iPad 2',
|
85
86
|
'iPad Air 2' => 'iPad Air 2',
|
87
|
+
'iPad Air' => 'iPad Air',
|
86
88
|
'iPad (5th generation)' => 'iPad (5th generation)',
|
87
89
|
'iPad Pro (9.7-inch)' => 'iPad Pro (9.7-inch)',
|
90
|
+
'iPad Pro (9.7 inch)' => 'iPad Pro (9.7-inch)', # iOS 10.3.1 simulator
|
88
91
|
'iPad Pro (10.5-inch)' => 'iPad Pro (10.5-inch)',
|
89
92
|
'iPad Pro (12.9-inch) (2nd generation)' => 'iPad Pro (12.9-inch) (2nd generation)',
|
90
93
|
'iPad Pro (12.9-inch)' => 'iPad Pro (12.9-inch)',
|
94
|
+
'iPad Pro (12.9 inch)' => 'iPad Pro (12.9-inch)', # iOS 10.3.1 simulator
|
95
|
+
'iPad Pro' => 'iPad Pro (12.9-inch)', # iOS 9.3 simulator
|
91
96
|
'Apple TV 1080p' => 'Apple TV',
|
92
97
|
'Apple TV 4K (at 1080p)' => 'Apple TV 4K (at 1080p)',
|
93
98
|
'Apple TV 4K' => 'Apple TV 4K',
|
@@ -122,6 +122,15 @@ module Snapshot
|
|
122
122
|
UI.verbose("Checking that helper files contain #{current_version}")
|
123
123
|
|
124
124
|
helper_files = Update.find_helper
|
125
|
+
if helper_files.empty?
|
126
|
+
UI.error("Your Snapshot Helper file is missing, please place a copy")
|
127
|
+
UI.error("in your project directory")
|
128
|
+
UI.message("More information about Snapshot setup can be found here:")
|
129
|
+
UI.message("https://docs.fastlane.tools/actions/snapshot/#quick-start")
|
130
|
+
UI.user_error!("Please add a Snapshot Helper file to your project")
|
131
|
+
return
|
132
|
+
end
|
133
|
+
|
125
134
|
helper_files.each do |path|
|
126
135
|
content = File.read(path)
|
127
136
|
|
data/spaceship/README.md
CHANGED
@@ -177,12 +177,12 @@ Overview of the used API endpoints
|
|
177
177
|
- Repair provisioning profiles
|
178
178
|
- Download provisioning profiles
|
179
179
|
- Team selection
|
180
|
-
- `https://
|
180
|
+
- `https://appstoreconnect.apple.com`:
|
181
181
|
- Managing apps
|
182
182
|
- Managing beta testers
|
183
183
|
- Submitting updates to review
|
184
184
|
- Managing app metadata
|
185
|
-
- `https://du-itc.
|
185
|
+
- `https://du-itc.appstoreconnect.apple.com`:
|
186
186
|
- Upload icons, screenshots, trailers ...
|
187
187
|
|
188
188
|
_spaceship_ uses all those API points to offer this seamless experience.
|
@@ -50,6 +50,7 @@ module Spaceship
|
|
50
50
|
UnexpectedResponse = Spaceship::UnexpectedResponse
|
51
51
|
AppleTimeoutError = Spaceship::AppleTimeoutError
|
52
52
|
UnauthorizedAccessError = Spaceship::UnauthorizedAccessError
|
53
|
+
GatewayTimeoutError = Spaceship::GatewayTimeoutError
|
53
54
|
InternalServerError = Spaceship::InternalServerError
|
54
55
|
|
55
56
|
# Authenticates with Apple's web services. This method has to be called once
|
@@ -469,7 +470,7 @@ module Spaceship
|
|
469
470
|
elsif response.status == 412 && AUTH_TYPES.include?(response.body["authType"])
|
470
471
|
# Need to acknowledge Apple ID and Privacy statement - https://github.com/fastlane/fastlane/issues/12577
|
471
472
|
# Looking for status of 412 might be enough but might be safer to keep looking only at what is being reported
|
472
|
-
raise AppleIDAndPrivacyAcknowledgementNeeded.new, "Need to acknowledge to Apple's Apple ID and Privacy statement. Please manually log into https://appleid.apple.com (or https://
|
473
|
+
raise AppleIDAndPrivacyAcknowledgementNeeded.new, "Need to acknowledge to Apple's Apple ID and Privacy statement. Please manually log into https://appleid.apple.com (or https://appstoreconnect.apple.com) to acknowledge the statement."
|
473
474
|
elsif (response['Set-Cookie'] || "").include?("itctx")
|
474
475
|
raise "Looks like your Apple ID is not enabled for App Store Connect, make sure to be able to login online"
|
475
476
|
else
|
@@ -507,7 +508,7 @@ module Spaceship
|
|
507
508
|
itc_service_key_path = "/tmp/spaceship_itc_service_key.txt"
|
508
509
|
return File.read(itc_service_key_path) if File.exist?(itc_service_key_path)
|
509
510
|
|
510
|
-
response = request(:get, "https://olympus.itunes.apple.com/v1/app/config?hostname=
|
511
|
+
response = request(:get, "https://olympus.itunes.apple.com/v1/app/config?hostname=appstoreconnect.apple.com")
|
511
512
|
@service_key = response.body["authServiceKey"].to_s
|
512
513
|
|
513
514
|
raise "Service key is empty" if @service_key.length == 0
|
@@ -532,6 +533,7 @@ module Spaceship
|
|
532
533
|
Faraday::Error::TimeoutError,
|
533
534
|
Faraday::ParsingError, # <h2>Internal Server Error</h2> with content type json
|
534
535
|
AppleTimeoutError,
|
536
|
+
GatewayTimeoutError,
|
535
537
|
InternalServerError => ex # New Faraday version: Faraday::TimeoutError => ex
|
536
538
|
tries -= 1
|
537
539
|
unless tries.zero?
|
@@ -628,6 +630,8 @@ module Spaceship
|
|
628
630
|
raise_insuffient_permission_error!(caller_location: 3)
|
629
631
|
elsif body.to_s.include?("Internal Server Error - Read")
|
630
632
|
raise InternalServerError, "Received an internal server error from App Store Connect / Developer Portal, please try again later"
|
633
|
+
elsif body.to_s.include?("Gateway Timeout - In read")
|
634
|
+
raise GatewayTimeoutError, "Received a gateway timeout error from App Store Connect / Developer Portal, please try again later"
|
631
635
|
elsif (body["resultString"] || "").include?("Program License Agreement")
|
632
636
|
raise ProgramLicenseAgreementUpdated, "#{body['userString']} Please manually log into your Apple Developer account to review and accept the updated agreement."
|
633
637
|
end
|
@@ -1,5 +1,6 @@
|
|
1
1
|
require_relative 'portal_base'
|
2
2
|
require_relative 'app_group'
|
3
|
+
require_relative 'cloud_container'
|
3
4
|
|
4
5
|
module Spaceship
|
5
6
|
module Portal
|
@@ -57,6 +58,9 @@ module Spaceship
|
|
57
58
|
# @return (Array of Spaceship::Portal::AppGroup) Associated groups
|
58
59
|
attr_accessor :associated_groups
|
59
60
|
|
61
|
+
# @return (Array of Spaceship::Portal::CloudContainer) Associated cloud containers
|
62
|
+
attr_accessor :associated_cloud_containers
|
63
|
+
|
60
64
|
attr_mapping(
|
61
65
|
'appIdId' => :app_id,
|
62
66
|
'name' => :name,
|
@@ -70,7 +74,8 @@ module Spaceship
|
|
70
74
|
'isProdPushEnabled' => :prod_push_enabled,
|
71
75
|
'associatedApplicationGroupsCount' => :app_groups_count,
|
72
76
|
'associatedCloudContainersCount' => :cloud_containers_count,
|
73
|
-
'associatedIdentifiersCount' => :identifiers_count
|
77
|
+
'associatedIdentifiersCount' => :identifiers_count,
|
78
|
+
'associatedCloudContainers' => :associated_cloud_containers
|
74
79
|
)
|
75
80
|
|
76
81
|
class << self
|
@@ -117,6 +122,14 @@ module Spaceship
|
|
117
122
|
end
|
118
123
|
end
|
119
124
|
|
125
|
+
def associated_cloud_containers
|
126
|
+
return unless raw_data['associatedCloudContainers']
|
127
|
+
|
128
|
+
@associated_cloud_containers ||= raw_data['associatedCloudContainers'].map do |info|
|
129
|
+
Spaceship::Portal::CloudContainer.new(info)
|
130
|
+
end
|
131
|
+
end
|
132
|
+
|
120
133
|
# Delete this App ID. This action will most likely fail if the App ID is already in the store
|
121
134
|
# or there are active profiles
|
122
135
|
# @return (App) The app you just deletd
|
@@ -147,6 +160,14 @@ module Spaceship
|
|
147
160
|
self.class.factory(app)
|
148
161
|
end
|
149
162
|
|
163
|
+
# Associate specific iCloud Containers with this app
|
164
|
+
# @return (App) The updated detailed app. This is nil if the app couldn't be found.
|
165
|
+
def associate_cloud_containers(containers)
|
166
|
+
raise "`associate_cloud_containers` not available for Mac apps" if mac?
|
167
|
+
app = client.associate_cloud_containers_with_app(self, containers)
|
168
|
+
self.class.factory(app)
|
169
|
+
end
|
170
|
+
|
150
171
|
# Associate specific merchants with this app
|
151
172
|
# @return (App) The updated detailed app. This is nil if the app couldn't be found
|
152
173
|
def associate_merchants(merchants)
|
@@ -0,0 +1,74 @@
|
|
1
|
+
require_relative 'portal_base'
|
2
|
+
|
3
|
+
module Spaceship
|
4
|
+
module Portal
|
5
|
+
# Represents an iCloud Container of the Apple Dev Portal
|
6
|
+
class CloudContainer < PortalBase
|
7
|
+
# @return (String) The identifier assigned to this container
|
8
|
+
# @example
|
9
|
+
# "iCloud.com.example.application"
|
10
|
+
attr_accessor :identifier
|
11
|
+
|
12
|
+
# @return (String) The prefix assigned to this container
|
13
|
+
# @example
|
14
|
+
# "9J57U9392R"
|
15
|
+
attr_accessor :prefix
|
16
|
+
|
17
|
+
# @return (String) The name of this container
|
18
|
+
# @example
|
19
|
+
# "iCloud com example application"
|
20
|
+
attr_accessor :name
|
21
|
+
|
22
|
+
# @return (String) Status of the container
|
23
|
+
# @example
|
24
|
+
# "current"
|
25
|
+
attr_accessor :status
|
26
|
+
|
27
|
+
# @return (String) The identifier of this iCloud container, provided by the Dev Portal
|
28
|
+
# @example
|
29
|
+
# "2MAY7NPHAA"
|
30
|
+
attr_accessor :cloud_container
|
31
|
+
|
32
|
+
# @return (Bool) Is the container editable?
|
33
|
+
attr_accessor :can_edit
|
34
|
+
|
35
|
+
# @return (Bool) Is the container deletable?
|
36
|
+
attr_accessor :can_delete
|
37
|
+
|
38
|
+
attr_mapping(
|
39
|
+
'identifier' => :identifier,
|
40
|
+
'prefix' => :prefix,
|
41
|
+
'name' => :name,
|
42
|
+
'cloudContainer' => :cloud_container,
|
43
|
+
'status' => :status,
|
44
|
+
'canEdit' => :can_edit,
|
45
|
+
'canDelete' => :can_delete
|
46
|
+
)
|
47
|
+
|
48
|
+
class << self
|
49
|
+
# @return (Array) Returns all iCloud containers available for this account
|
50
|
+
def all
|
51
|
+
client.cloud_containers.map { |container| self.factory(container) }
|
52
|
+
end
|
53
|
+
|
54
|
+
# Creates a new iCloud Container on the Apple Dev Portal
|
55
|
+
#
|
56
|
+
# @param identifier [String] the identifier to assign to this container
|
57
|
+
# @param name [String] the name of the container
|
58
|
+
# @return (CloudContainer) The container you just created
|
59
|
+
def create!(identifier: nil, name: nil)
|
60
|
+
new_container = client.create_cloud_container!(name, identifier)
|
61
|
+
self.new(new_container)
|
62
|
+
end
|
63
|
+
|
64
|
+
# Find a specific iCloud Container identifier
|
65
|
+
# @return (CloudContainer) The iCloud Container you're looking for. This is nil if the container can't be found.
|
66
|
+
def find(identifier)
|
67
|
+
all.find do |container|
|
68
|
+
container.identifier == identifier
|
69
|
+
end
|
70
|
+
end
|
71
|
+
end
|
72
|
+
end
|
73
|
+
end
|
74
|
+
end
|
@@ -4,6 +4,7 @@ require 'spaceship/portal/website_push'
|
|
4
4
|
require 'spaceship/portal/app_group'
|
5
5
|
require 'spaceship/portal/app_service'
|
6
6
|
require 'spaceship/portal/certificate'
|
7
|
+
require 'spaceship/portal/cloud_container'
|
7
8
|
require 'spaceship/portal/device'
|
8
9
|
require 'spaceship/portal/provisioning_profile'
|
9
10
|
require 'spaceship/portal/portal_client'
|
@@ -2,6 +2,7 @@ require_relative '../client'
|
|
2
2
|
|
3
3
|
require_relative 'app'
|
4
4
|
require_relative 'app_group'
|
5
|
+
require_relative 'cloud_container'
|
5
6
|
require_relative 'device'
|
6
7
|
require_relative 'merchant'
|
7
8
|
require_relative 'passbook'
|
@@ -149,6 +150,18 @@ module Spaceship
|
|
149
150
|
details_for_app(app)
|
150
151
|
end
|
151
152
|
|
153
|
+
def associate_cloud_containers_with_app(app, containers)
|
154
|
+
ensure_csrf(Spaceship::Portal::CloudContainer)
|
155
|
+
|
156
|
+
request(:post, 'account/ios/identifiers/assignCloudContainerToAppId.action', {
|
157
|
+
teamId: team_id,
|
158
|
+
appIdId: app.app_id,
|
159
|
+
cloudContainers: containers.map(&:cloud_container)
|
160
|
+
})
|
161
|
+
|
162
|
+
details_for_app(app)
|
163
|
+
end
|
164
|
+
|
152
165
|
def associate_merchants_with_app(app, merchants, mac)
|
153
166
|
ensure_csrf(Spaceship::Portal::Merchant)
|
154
167
|
|
@@ -375,6 +388,37 @@ module Spaceship
|
|
375
388
|
parse_response(r)
|
376
389
|
end
|
377
390
|
|
391
|
+
#####################################################
|
392
|
+
# @!group Cloud Containers
|
393
|
+
#####################################################
|
394
|
+
|
395
|
+
def cloud_containers
|
396
|
+
paging do |page_number|
|
397
|
+
r = request(:post, 'account/cloudContainer/listCloudContainers.action', {
|
398
|
+
teamId: team_id,
|
399
|
+
pageNumber: page_number,
|
400
|
+
pageSize: page_size,
|
401
|
+
sort: 'name=asc'
|
402
|
+
})
|
403
|
+
result = parse_response(r, 'cloudContainerList')
|
404
|
+
|
405
|
+
csrf_cache[Spaceship::Portal::CloudContainer] = self.csrf_tokens
|
406
|
+
|
407
|
+
result
|
408
|
+
end
|
409
|
+
end
|
410
|
+
|
411
|
+
def create_cloud_container!(name, identifier)
|
412
|
+
ensure_csrf(Spaceship::Portal::CloudContainer)
|
413
|
+
|
414
|
+
r = request(:post, 'account/cloudContainer/addCloudContainer.action', {
|
415
|
+
name: valid_name_for(name),
|
416
|
+
identifier: identifier,
|
417
|
+
teamId: team_id
|
418
|
+
})
|
419
|
+
parse_response(r, 'cloudContainer')
|
420
|
+
end
|
421
|
+
|
378
422
|
#####################################################
|
379
423
|
# @!group Team
|
380
424
|
#####################################################
|
@@ -656,10 +700,7 @@ module Spaceship
|
|
656
700
|
end
|
657
701
|
|
658
702
|
def delete_provisioning_profile!(profile_id, mac: false)
|
659
|
-
|
660
|
-
fetch_csrf_token_for_provisioning
|
661
|
-
end
|
662
|
-
|
703
|
+
fetch_csrf_token_for_provisioning
|
663
704
|
r = request(:post, "account/#{platform_slug(mac)}/profile/deleteProvisioningProfile.action", {
|
664
705
|
teamId: team_id,
|
665
706
|
provisioningProfileId: profile_id
|
@@ -70,6 +70,11 @@ module Spaceship
|
|
70
70
|
Spaceship::Portal::AppService
|
71
71
|
end
|
72
72
|
|
73
|
+
# @return (Class) Access the iCloud Containers for the spaceship
|
74
|
+
def cloud_container
|
75
|
+
Spaceship::Portal::CloudContainer.set_client(@client)
|
76
|
+
end
|
77
|
+
|
73
78
|
# @return (Class) Access the devices for the spaceship
|
74
79
|
def device
|
75
80
|
Spaceship::Portal::Device.set_client(@client)
|
@@ -122,6 +127,10 @@ module Spaceship
|
|
122
127
|
Spaceship::Portal.app_service
|
123
128
|
end
|
124
129
|
|
130
|
+
def cloud_container
|
131
|
+
Spaceship::Portal.cloud_container
|
132
|
+
end
|
133
|
+
|
125
134
|
def device
|
126
135
|
Spaceship::Portal.device
|
127
136
|
end
|
@@ -15,7 +15,7 @@ module Spaceship
|
|
15
15
|
# Each request method should make only one request. For more high-level logic, put code in the data models.
|
16
16
|
|
17
17
|
def self.hostname
|
18
|
-
'https://
|
18
|
+
'https://appstoreconnect.apple.com/testflight/v2/'
|
19
19
|
end
|
20
20
|
|
21
21
|
##
|
@@ -46,8 +46,8 @@ module Spaceship
|
|
46
46
|
end
|
47
47
|
|
48
48
|
# @return (Array) of Review Objects
|
49
|
-
def reviews(store_front = '', version_id = '')
|
50
|
-
raw_reviews = client.get_reviews(application.apple_id, application.platform, store_front, version_id)
|
49
|
+
def reviews(store_front = '', version_id = '', upto_date = nil)
|
50
|
+
raw_reviews = client.get_reviews(application.apple_id, application.platform, store_front, version_id, upto_date)
|
51
51
|
raw_reviews.map do |review|
|
52
52
|
review["value"]["application"] = self.application
|
53
53
|
AppReview.factory(review["value"])
|
@@ -12,6 +12,11 @@ module Spaceship
|
|
12
12
|
# @return (AppVersion) The version to use for this submission
|
13
13
|
attr_accessor :version
|
14
14
|
|
15
|
+
# @return (String) The platform of the device. This is usually "ios"
|
16
|
+
# @example
|
17
|
+
# "appletvos"
|
18
|
+
attr_accessor :platform
|
19
|
+
|
15
20
|
# @return (Boolean) Submitted for Review
|
16
21
|
attr_accessor :submitted_for_review
|
17
22
|
|
@@ -115,10 +120,11 @@ module Spaceship
|
|
115
120
|
end
|
116
121
|
|
117
122
|
# @param application (Spaceship::Tunes::Application) The app this submission is for
|
118
|
-
def create(application, version)
|
119
|
-
attrs = client.prepare_app_submissions(application.apple_id, application.edit_version.version_id)
|
123
|
+
def create(application, version, platform: nil)
|
124
|
+
attrs = client.prepare_app_submissions(application.apple_id, application.edit_version(platform: platform).version_id)
|
120
125
|
attrs[:application] = application
|
121
126
|
attrs[:version] = version
|
127
|
+
attrs[:platform] = platform
|
122
128
|
|
123
129
|
return self.factory(attrs)
|
124
130
|
end
|
@@ -142,7 +148,7 @@ module Spaceship
|
|
142
148
|
)
|
143
149
|
end
|
144
150
|
|
145
|
-
client.send_app_submission(application.apple_id, application.edit_version.version_id, raw_data_clone)
|
151
|
+
client.send_app_submission(application.apple_id, application.edit_version(platform: platform).version_id, raw_data_clone)
|
146
152
|
@submitted_for_review = true
|
147
153
|
end
|
148
154
|
|
@@ -405,7 +405,7 @@ module Spaceship
|
|
405
405
|
|
406
406
|
# @return (String) An URL to this specific resource. You can enter this URL into your browser
|
407
407
|
def url
|
408
|
-
url = "https://
|
408
|
+
url = "https://appstoreconnect.apple.com/WebObjects/iTunesConnect.woa/ra/ng/app/#{application.apple_id}/#{self.platform}/versioninfo/"
|
409
409
|
url += "deliverable" if self.is_live?
|
410
410
|
return url
|
411
411
|
end
|
@@ -138,7 +138,7 @@ module Spaceship
|
|
138
138
|
|
139
139
|
# @return (String) An URL to this specific resource. You can enter this URL into your browser
|
140
140
|
def url
|
141
|
-
"https://
|
141
|
+
"https://appstoreconnect.apple.com/WebObjects/iTunesConnect.woa/ra/ng/app/#{self.apple_id}"
|
142
142
|
end
|
143
143
|
|
144
144
|
def analytics
|
@@ -357,13 +357,13 @@ module Spaceship
|
|
357
357
|
# @!group Submit for Review
|
358
358
|
#####################################################
|
359
359
|
|
360
|
-
def create_submission
|
361
|
-
version = self.latest_version
|
360
|
+
def create_submission(platform: nil)
|
361
|
+
version = self.latest_version(platform: platform)
|
362
362
|
if version.nil?
|
363
363
|
raise "Could not find a valid version to submit for review"
|
364
364
|
end
|
365
365
|
|
366
|
-
Spaceship::Tunes::AppSubmission.create(self, version)
|
366
|
+
Spaceship::Tunes::AppSubmission.create(self, version, platform: platform)
|
367
367
|
end
|
368
368
|
|
369
369
|
# Cancels all ongoing TestFlight beta submission for this application
|
@@ -50,7 +50,7 @@ module Spaceship
|
|
50
50
|
#####################################################
|
51
51
|
|
52
52
|
def self.hostname
|
53
|
-
"https://
|
53
|
+
"https://appstoreconnect.apple.com/WebObjects/iTunesConnect.woa/"
|
54
54
|
end
|
55
55
|
|
56
56
|
# Shows a team selection for the user in the terminal. This should not be
|
@@ -358,10 +358,13 @@ module Spaceship
|
|
358
358
|
parse_response(r, 'data')
|
359
359
|
end
|
360
360
|
|
361
|
-
def get_reviews(app_id, platform, storefront, version_id)
|
361
|
+
def get_reviews(app_id, platform, storefront, version_id, upto_date = nil)
|
362
362
|
index = 0
|
363
363
|
per_page = 100 # apple default
|
364
364
|
all_reviews = []
|
365
|
+
|
366
|
+
upto_date = Time.parse(upto_date) unless upto_date.nil?
|
367
|
+
|
365
368
|
loop do
|
366
369
|
rating_url = "ra/apps/#{app_id}/platforms/#{platform}/reviews?"
|
367
370
|
rating_url << "sort=REVIEW_SORT_ORDER_MOST_RECENT"
|
@@ -371,12 +374,20 @@ module Spaceship
|
|
371
374
|
|
372
375
|
r = request(:get, rating_url)
|
373
376
|
all_reviews.concat(parse_response(r, 'data')['reviews'])
|
377
|
+
last_review_date = Time.at(all_reviews[-1]['value']['lastModified'] / 1000)
|
378
|
+
|
379
|
+
if upto_date && last_review_date < upto_date
|
380
|
+
all_reviews = all_reviews.select { |review| Time.at(review['value']['lastModified'] / 1000) > upto_date }
|
381
|
+
break
|
382
|
+
end
|
383
|
+
|
374
384
|
if all_reviews.count < parse_response(r, 'data')['reviewCount']
|
375
385
|
index += per_page
|
376
386
|
else
|
377
387
|
break
|
378
388
|
end
|
379
389
|
end
|
390
|
+
|
380
391
|
all_reviews
|
381
392
|
end
|
382
393
|
|