Skip to content

Commit 52b987c

Browse files
tmm1mfurtak
authored andcommitted
Fix pilot testflight distribution after recent iTC changes (fastlane#5407)
* fix pilot testflight distribution * Updates testflight fix to account for encryption attributes * fix tests
1 parent 400c6b8 commit 52b987c

File tree

3 files changed

+184
-54
lines changed

3 files changed

+184
-54
lines changed

spaceship/lib/spaceship/tunes/tunes_client.rb

Lines changed: 35 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -565,13 +565,8 @@ def update_build_information!(app_id: nil,
565565
feedback_email: nil,
566566
platform: 'ios')
567567
url = "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/testInformation"
568-
r = request(:get) do |req|
569-
req.url url
570-
req.headers['Content-Type'] = 'application/json'
571-
end
572-
handle_itc_response(r.body)
573568

574-
build_info = r.body['data']
569+
build_info = get_build_info_for_review(app_id: app_id, train: train, build_number: build_number, platform: platform)
575570
build_info["details"].each do |current|
576571
current["whatsNew"]["value"] = whats_new if whats_new
577572
current["description"]["value"] = description if description
@@ -609,79 +604,70 @@ def submit_testflight_build_for_review!(app_id: nil, train: nil, build_number: n
609604
review_user_name: nil,
610605
review_password: nil,
611606
review_notes: nil,
612-
encryption: false)
607+
encryption: false,
608+
encryption_updated: false,
609+
is_exempt: false,
610+
proprietary: false,
611+
third_party: false)
613612

614613
build_info = get_build_info_for_review(app_id: app_id, train: train, build_number: build_number, platform: platform)
615614
# Now fill in the values provided by the user
616615

617616
# First the localised values:
618-
build_info['testInfo']['details'].each do |current|
617+
build_info['details'].each do |current|
619618
current['whatsNew']['value'] = changelog if changelog
620619
current['description']['value'] = description if description
621620
current['feedbackEmail']['value'] = feedback_email if feedback_email
622621
current['marketingUrl']['value'] = marketing_url if marketing_url
623622
current['privacyPolicyUrl']['value'] = privacy_policy_url if privacy_policy_url
624623
current['pageLanguageValue'] = current['language'] # There is no valid reason why we need this, only iTC being iTC
625624
end
626-
build_info['significantChange'] ||= {}
627-
build_info['significantChange']['value'] = significant_change
628-
build_info['testInfo']['reviewFirstName']['value'] = first_name if first_name
629-
build_info['testInfo']['reviewLastName']['value'] = last_name if last_name
630-
build_info['testInfo']['reviewPhone']['value'] = phone_number if phone_number
631-
build_info['testInfo']['reviewEmail']['value'] = review_email if review_email
632-
build_info['testInfo']['reviewAccountRequired']['value'] = (review_user_name.to_s + review_password.to_s).length > 0
633-
build_info['testInfo']['reviewUserName']['value'] = review_user_name if review_user_name
634-
build_info['testInfo']['reviewPassword']['value'] = review_password if review_password
635-
build_info['testInfo']['reviewNotes']['value'] = review_notes if review_notes
625+
626+
review_info = {
627+
"significantChange" => {
628+
"value" => significant_change
629+
},
630+
"buildTestInformationTO" => build_info,
631+
"exportComplianceTO" => {
632+
"usesEncryption" => {
633+
"value" => encryption
634+
},
635+
"encryptionUpdated" => {
636+
"value" => encryption_updated
637+
},
638+
"isExempt" => {
639+
"value" => is_exempt
640+
},
641+
"containsProprietaryCryptography" => {
642+
"value" => proprietary
643+
},
644+
"containsThirdPartyCryptography" => {
645+
"value" => third_party
646+
}
647+
}
648+
}
636649

637650
r = request(:post) do |req| # same URL, but a POST request
638-
req.url "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/submit/start"
651+
req.url "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/review/submit"
639652

640-
req.body = build_info.to_json
653+
req.body = review_info.to_json
641654
req.headers['Content-Type'] = 'application/json'
642655
end
643656
handle_itc_response(r.body)
644-
645-
encryption_info = r.body['data']
646-
update_encryption_compliance(app_id: app_id,
647-
train: train,
648-
build_number: build_number,
649-
platform: platform,
650-
encryption_info: encryption_info,
651-
encryption: encryption)
652657
end
653658
# rubocop:enable Metrics/ParameterLists
654659

655660
def get_build_info_for_review(app_id: nil, train: nil, build_number: nil, platform: 'ios')
661+
url = "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/testInformation"
656662
r = request(:get) do |req|
657-
req.url "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/submit/start"
663+
req.url url
658664
req.headers['Content-Type'] = 'application/json'
659665
end
660666
handle_itc_response(r.body)
661667

662668
r.body['data']
663669
end
664670

665-
def update_encryption_compliance(app_id: nil, train: nil, build_number: nil, platform: 'ios', encryption_info: nil, encryption: nil, is_exempt: true, proprietary: false, third_party: false)
666-
return unless encryption_info['exportComplianceRequired']
667-
# only sometimes this is required
668-
669-
encryption_info['usesEncryption']['value'] = encryption
670-
encryption_info['encryptionUpdated'] ||= {}
671-
encryption_info['encryptionUpdated']['value'] = encryption
672-
encryption_info['isExempt']['value'] = is_exempt
673-
encryption_info['containsProprietaryCryptography']['value'] = proprietary
674-
encryption_info['containsThirdPartyCryptography']['value'] = third_party
675-
676-
r = request(:post) do |req|
677-
req.url "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/submit/complete"
678-
req.body = encryption_info.to_json
679-
req.headers['Content-Type'] = 'application/json'
680-
end
681-
682-
handle_itc_response(r.body)
683-
end
684-
685671
#####################################################
686672
# @!group Submit for Review
687673
#####################################################
Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
{
2+
"data": {
3+
"sectionErrorKeys": [],
4+
"sectionInfoKeys": [],
5+
"sectionWarningKeys": [],
6+
"internalStatus": "active",
7+
"externalStatus": "submitForReview",
8+
"expirationDate": null,
9+
"internalExpirationDate": null,
10+
"externalExpirationDate": null,
11+
"primaryLanguage": "English",
12+
"primaryLocaleCode": "en-US",
13+
"availableLanguages": ["English"],
14+
"details": [{
15+
"sectionErrorKeys": [],
16+
"sectionInfoKeys": [],
17+
"sectionWarningKeys": [],
18+
"language": "English",
19+
"localeCode": "en-US",
20+
"whatsNew": {
21+
"value": null,
22+
"isEditable": true,
23+
"isRequired": true,
24+
"errorKeys": null,
25+
"maxLength": 4000,
26+
"minLength": 4
27+
},
28+
"description": {
29+
"value": null,
30+
"isEditable": true,
31+
"isRequired": true,
32+
"errorKeys": null,
33+
"maxLength": 4000,
34+
"minLength": 10
35+
},
36+
"feedbackEmail": {
37+
"value": null,
38+
"isEditable": true,
39+
"isRequired": true,
40+
"errorKeys": null,
41+
"maxLength": 500,
42+
"minLength": 1
43+
},
44+
"marketingUrl": {
45+
"value": null,
46+
"isEditable": true,
47+
"isRequired": true,
48+
"errorKeys": null,
49+
"maxLength": 255,
50+
"minLength": 1
51+
},
52+
"privacyPolicyUrl": {
53+
"value": null,
54+
"isEditable": true,
55+
"isRequired": false,
56+
"errorKeys": null,
57+
"maxLength": 255,
58+
"minLength": 1
59+
},
60+
"privacyPolicyText": null
61+
}],
62+
"reviewFirstName": {
63+
"value": null,
64+
"isEditable": true,
65+
"isRequired": true,
66+
"errorKeys": null,
67+
"maxLength": 100,
68+
"minLength": 1
69+
},
70+
"reviewLastName": {
71+
"value": null,
72+
"isEditable": true,
73+
"isRequired": true,
74+
"errorKeys": null,
75+
"maxLength": 100,
76+
"minLength": 1
77+
},
78+
"reviewPhone": {
79+
"value": null,
80+
"isEditable": true,
81+
"isRequired": true,
82+
"errorKeys": null,
83+
"maxLength": 20,
84+
"minLength": 1
85+
},
86+
"reviewEmail": {
87+
"value": null,
88+
"isEditable": true,
89+
"isRequired": true,
90+
"errorKeys": null,
91+
"maxLength": 100,
92+
"minLength": 1
93+
},
94+
"reviewNotes": {
95+
"value": null,
96+
"isEditable": true,
97+
"isRequired": false,
98+
"errorKeys": null,
99+
"maxLength": 4000,
100+
"minLength": 1
101+
},
102+
"reviewUserName": {
103+
"value": null,
104+
"isEditable": true,
105+
"isRequired": false,
106+
"errorKeys": null,
107+
"maxLength": 400,
108+
"minLength": 1
109+
},
110+
"reviewPassword": {
111+
"value": null,
112+
"isEditable": true,
113+
"isRequired": false,
114+
"errorKeys": null,
115+
"maxLength": 400,
116+
"minLength": 1
117+
},
118+
"reviewAccountRequired": {
119+
"value": false,
120+
"isEditable": true,
121+
"isRequired": false,
122+
"errorKeys": null
123+
},
124+
"eula": {
125+
"value": null,
126+
"isEditable": true,
127+
"isRequired": false,
128+
"errorKeys": null,
129+
"maxLength": null,
130+
"minLength": 1
131+
},
132+
"hasExportCompliance": false,
133+
"installCount": 0,
134+
"externalInstallCount": 0,
135+
"internalInstallCount": 0,
136+
"sessionCount": 0,
137+
"externalSessionCount": 0,
138+
"internalSessionCount": 0,
139+
"crashCount": 0,
140+
"externalCrashCount": 0,
141+
"internalCrashCount": 0
142+
}
143+
}

spaceship/spec/tunes/tunes_stubbing.rb

Lines changed: 6 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -167,16 +167,17 @@ def itc_stub_testers
167167
end
168168

169169
def itc_stub_testflight
170+
# Test information
171+
stub_request(:get, "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/898536088/platforms/ios/trains/1.0/builds/10/testInformation").
172+
to_return(status: 200, body: itc_read_fixture_file('testflight_build_info.json'), headers: { 'Content-Type' => 'application/json' })
173+
170174
# Reject review
171175
stub_request(:post, "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/898536088/platforms/ios/trains/1.0/builds/10/reject").
172176
with(body: "{}").
173177
to_return(status: 200, body: "{}", headers: { 'Content-Type' => 'application/json' })
174178

175-
# Prepare submission
176-
stub_request(:get, "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/898536088/platforms/ios/trains/1.0/builds/10/submit/start").
177-
to_return(status: 200, body: itc_read_fixture_file('testflight_submission_start.json'), headers: { 'Content-Type' => 'application/json' })
178-
# First step of submission
179-
stub_request(:post, "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/898536088/platforms/ios/trains/1.0/builds/10/submit/start").
179+
# Submission
180+
stub_request(:post, "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/ra/apps/898536088/platforms/ios/trains/1.0/builds/10/review/submit").
180181
to_return(status: 200, body: itc_read_fixture_file('testflight_submission_submit.json'), headers: { 'Content-Type' => 'application/json' })
181182
end
182183

0 commit comments

Comments
 (0)