fastlane 2.47.0.beta.20170712010003 → 2.47.0.beta.20170713010003
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 +4 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane_core/lib/fastlane_core/build_watcher.rb +2 -2
- data/gym/lib/gym/error_handler.rb +52 -31
- data/spaceship/lib/spaceship/portal/key.rb +99 -0
- data/spaceship/lib/spaceship/portal/portal.rb +1 -0
- data/spaceship/lib/spaceship/portal/portal_client.rb +48 -0
- metadata +3 -2
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 87fdbf460eea76afd41b155d334da48b710b2d4f
|
4
|
+
data.tar.gz: 19ca586cb7f4f518383e8a293c3251a49b22ae49
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 966fac603239f16233f92dbea02d932a4fc01191ec03d84c3d5a69434aeb8245fab59c050d81fe441e0f611154402899f142b2eab2c17487f27c37c1944783f8
|
7
|
+
data.tar.gz: a3b6baab3fd47dbb4b36594300e7446ffbc1cacbf9b575ab1feb015c6c45b2f18a98b2d57cf027a3ecda33e7f683aaa509f0211c2ab0182825f27901e886e80b
|
data/README.md
CHANGED
@@ -95,6 +95,10 @@ Get started distributing your first app with fastlane within minutes:
|
|
95
95
|
Want to learn more? Explore guides for [iOS](https://docs.fastlane.tools/getting-started/ios/setup/)
|
96
96
|
or [Android](https://docs.fastlane.tools/getting-started/android/setup/).
|
97
97
|
|
98
|
+
## System Requirements
|
99
|
+
|
100
|
+
Currently, _fastlane_ is officially supported to run on macOS. Support for other operating systems is limited and untested at this point in time. _fastlane_ uses system APIs that may not be implemented on other platforms, for example, we use the Ruby `fork` method for sub-process management, which isn't available on Windows.
|
101
|
+
|
98
102
|
## Available Commands
|
99
103
|
|
100
104
|
Typically you'll use `fastlane` by triggering individual lanes:
|
@@ -35,13 +35,13 @@ module FastlaneCore
|
|
35
35
|
end
|
36
36
|
|
37
37
|
def report_status(build: nil)
|
38
|
-
# Due to iTunes Connect, builds disappear from the build list
|
38
|
+
# Due to iTunes Connect, builds disappear from the build list altogether
|
39
39
|
# after they finished processing. Before returning this build, we have to
|
40
40
|
# wait for the build to appear in the build list again
|
41
41
|
# As this method is very often used to wait for a build, and then do something
|
42
42
|
# with it, we have to be sure that the build actually is ready
|
43
43
|
if build.nil?
|
44
|
-
UI.message("Build doesn't show up in the build list
|
44
|
+
UI.message("Build doesn't show up in the build list anymore, waiting for it to appear again")
|
45
45
|
elsif build.active?
|
46
46
|
UI.success("Build #{build.train_version} - #{build.build_version} is already being tested")
|
47
47
|
elsif build.ready_to_submit? || build.export_compliance_missing?
|
@@ -51,9 +51,10 @@ module Gym
|
|
51
51
|
print "For more information visit this stackoverflow answer:"
|
52
52
|
print "https://stackoverflow.com/a/17031697/445598"
|
53
53
|
end
|
54
|
-
print_full_log_path
|
55
54
|
print_xcode_path_instructions
|
56
55
|
print_xcode_version
|
56
|
+
print_full_log_path
|
57
|
+
print_build_error_instructions
|
57
58
|
UI.build_failure!("Error building the application - see the log above", error_info: output)
|
58
59
|
end
|
59
60
|
|
@@ -89,6 +90,7 @@ module Gym
|
|
89
90
|
print "provisioning profile and code signing identity."
|
90
91
|
end
|
91
92
|
print_full_log_path
|
93
|
+
print_build_error_instructions
|
92
94
|
UI.build_failure!("Error packaging up the application", error_info: output)
|
93
95
|
end
|
94
96
|
|
@@ -102,18 +104,8 @@ module Gym
|
|
102
104
|
UI.build_failure!("Archive invalid")
|
103
105
|
end
|
104
106
|
|
105
|
-
def find_standard_output_path(output)
|
106
|
-
m = /Created bundle at path '(.*)'/.match(output)
|
107
|
-
return File.join(m[1], 'IDEDistribution.standard.log') unless m.nil?
|
108
|
-
end
|
109
|
-
|
110
107
|
private
|
111
108
|
|
112
|
-
def read_standard_output(output)
|
113
|
-
path = find_standard_output_path output
|
114
|
-
return File.read(path) if File.exist?(path)
|
115
|
-
end
|
116
|
-
|
117
109
|
# Just to make things easier
|
118
110
|
def print(text)
|
119
111
|
UI.error text
|
@@ -121,8 +113,21 @@ module Gym
|
|
121
113
|
|
122
114
|
def print_full_log_path
|
123
115
|
return if Gym.config[:disable_xcpretty]
|
116
|
+
|
124
117
|
log_path = Gym::BuildCommandGenerator.xcodebuild_log_path
|
125
|
-
|
118
|
+
return unless File.exist?(log_path)
|
119
|
+
|
120
|
+
# `xcodebuild` doesn't properly mark lines as failure reason or important information
|
121
|
+
# so we assume that the last few lines show the error message that's relevant
|
122
|
+
# (at least that's what was correct during testing)
|
123
|
+
log_content = File.read(log_path).split("\n")[-5..-1]
|
124
|
+
log_content.each do |row|
|
125
|
+
UI.command_output(row)
|
126
|
+
end
|
127
|
+
|
128
|
+
UI.message("")
|
129
|
+
UI.error("⬆️ Check out the few lines of raw `xcodebuild` output above for potential hints on how to solve this error")
|
130
|
+
UI.important("📋 For the complete and more detailed error log, check the full log at:")
|
126
131
|
UI.important("📋 #{log_path}")
|
127
132
|
end
|
128
133
|
|
@@ -148,25 +153,41 @@ module Gym
|
|
148
153
|
default_xcode_path = "/Applications/"
|
149
154
|
|
150
155
|
xcode_installations_in_default_path = Dir[File.join(default_xcode_path, "Xcode*.app")]
|
151
|
-
|
152
|
-
|
153
|
-
|
154
|
-
|
155
|
-
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
|
166
|
-
|
167
|
-
|
168
|
-
|
169
|
-
|
156
|
+
return unless xcode_installations_in_default_path.count > 1
|
157
|
+
UI.message ""
|
158
|
+
UI.important "Maybe the error shown is caused by using the wrong version of Xcode"
|
159
|
+
UI.important "Found multiple versions of Xcode in '#{default_xcode_path}'"
|
160
|
+
UI.important "Make sure you selected the right version for your project"
|
161
|
+
UI.important "This build process was executed using '#{xcode_path}'"
|
162
|
+
UI.important "If you want to update your Xcode path, either"
|
163
|
+
UI.message ""
|
164
|
+
|
165
|
+
UI.message "- Specify the Xcode version in your Fastfile"
|
166
|
+
UI.command_output "xcversion(version: \"8.1\") # Selects Xcode 8.1.0"
|
167
|
+
UI.message ""
|
168
|
+
|
169
|
+
UI.message "- Specify an absolute path to your Xcode installation in your Fastfile"
|
170
|
+
UI.command_output "xcode_select \"/Applications/Xcode8.app\""
|
171
|
+
UI.message ""
|
172
|
+
|
173
|
+
UI.message "- Manually update the path using"
|
174
|
+
UI.command_output "sudo xcode-select -s /Applications/Xcode.app"
|
175
|
+
UI.message ""
|
176
|
+
end
|
177
|
+
|
178
|
+
# Indicate that code signing errors are not caused by fastlane
|
179
|
+
# and that fastlane only runs `xcodebuild` commands
|
180
|
+
def print_build_error_instructions
|
181
|
+
UI.message("")
|
182
|
+
UI.error("Looks like fastlane ran into a build/archive error with your project")
|
183
|
+
UI.error("It's hard to tell what's causing the error, so we wrote some guides on how")
|
184
|
+
UI.error("to troubleshoot build and signing issues: https://docs.fastlane.tools/codesigning/getting-started/")
|
185
|
+
UI.error("Before submitting an issue on GitHub, please follow the guide above and make")
|
186
|
+
UI.error("sure your project is set up correctly.")
|
187
|
+
UI.error("fastlane uses `xcodebuild` commands to generate your binary, you can see the")
|
188
|
+
UI.error("the full commands printed out in yellow in the above log.")
|
189
|
+
UI.error("Make sure to inspect the output above, as usually you'll find more error information there")
|
190
|
+
UI.message("")
|
170
191
|
end
|
171
192
|
end
|
172
193
|
end
|
@@ -0,0 +1,99 @@
|
|
1
|
+
module Spaceship
|
2
|
+
module Portal
|
3
|
+
class Key < PortalBase
|
4
|
+
##
|
5
|
+
# data model for managing JWT tokens or "Keys" as the ADP refers to them
|
6
|
+
|
7
|
+
APNS_ID = 'U27F4V844T'
|
8
|
+
DEVICE_CHECK_ID = 'DQ8HTZ7739'
|
9
|
+
MUSIC_KIT_ID = '6A7HVUVQ3M'
|
10
|
+
|
11
|
+
attr_accessor :id
|
12
|
+
attr_accessor :name
|
13
|
+
|
14
|
+
attr_mapping({
|
15
|
+
'keyId' => :id,
|
16
|
+
'keyName' => :name,
|
17
|
+
'services' => :services,
|
18
|
+
'canDownload' => :can_download,
|
19
|
+
'canRevoke' => :can_revoke
|
20
|
+
})
|
21
|
+
|
22
|
+
def self.all
|
23
|
+
keys = client.list_keys
|
24
|
+
keys.map do |key|
|
25
|
+
new(key)
|
26
|
+
end
|
27
|
+
end
|
28
|
+
|
29
|
+
def self.find(id)
|
30
|
+
key = client.get_key(id: id)
|
31
|
+
new(key)
|
32
|
+
end
|
33
|
+
|
34
|
+
##
|
35
|
+
# Creates a new JWT / Key for making requests to services.
|
36
|
+
#
|
37
|
+
# @param name [String] the name of the key
|
38
|
+
# @param apns [Bool] whether the key should be able to make APNs requests
|
39
|
+
# @param device_check [Bool] whether the key should be able to make DeviceCheck requests
|
40
|
+
# @param music_id [String] the Music Id id (the autogenerated id, not the user specified identifier "music.com.etc...")
|
41
|
+
def self.create(name: nil, apns: nil, device_check: nil, music_id: nil)
|
42
|
+
service_config = {}
|
43
|
+
service_config[APNS_ID] = [] if apns
|
44
|
+
service_config[DEVICE_CHECK_ID] = [] if device_check
|
45
|
+
service_config[MUSIC_KIT_ID] = [music_id] if music_id
|
46
|
+
|
47
|
+
key = client.create_key!(name: name, service_configs: service_config)
|
48
|
+
new(key)
|
49
|
+
end
|
50
|
+
|
51
|
+
def revoke!
|
52
|
+
client.revoke_key!(id: id)
|
53
|
+
end
|
54
|
+
|
55
|
+
def download
|
56
|
+
client.download_key(id: id)
|
57
|
+
end
|
58
|
+
|
59
|
+
def services
|
60
|
+
raw_data['services'] || reload
|
61
|
+
super
|
62
|
+
end
|
63
|
+
|
64
|
+
def service_configs_for(service_id)
|
65
|
+
if (service = find_service(service_id))
|
66
|
+
service['configurations']
|
67
|
+
end
|
68
|
+
end
|
69
|
+
|
70
|
+
def has_apns?
|
71
|
+
has_service?(APNS_ID)
|
72
|
+
end
|
73
|
+
|
74
|
+
def has_music_kit?
|
75
|
+
has_service?(MUSIC_KIT_ID)
|
76
|
+
end
|
77
|
+
|
78
|
+
def has_device_check?
|
79
|
+
has_service?(DEVICE_CHECK_ID)
|
80
|
+
end
|
81
|
+
|
82
|
+
def reload
|
83
|
+
self.raw_data = self.class.find(id).raw_data
|
84
|
+
end
|
85
|
+
|
86
|
+
private
|
87
|
+
|
88
|
+
def find_service(service_id)
|
89
|
+
services.find do |service|
|
90
|
+
service['id'] == service_id
|
91
|
+
end
|
92
|
+
end
|
93
|
+
|
94
|
+
def has_service?(service_id)
|
95
|
+
find_service(service_id) != nil
|
96
|
+
end
|
97
|
+
end
|
98
|
+
end
|
99
|
+
end
|
@@ -560,6 +560,54 @@ module Spaceship
|
|
560
560
|
parse_response(r, 'provisioningProfile')
|
561
561
|
end
|
562
562
|
|
563
|
+
#####################################################
|
564
|
+
# @!group Keys
|
565
|
+
#####################################################
|
566
|
+
|
567
|
+
def list_keys
|
568
|
+
paging do |page_number|
|
569
|
+
response = request(:post, 'account/auth/key/list', {
|
570
|
+
teamId: team_id,
|
571
|
+
pageNumber: page_number,
|
572
|
+
pageSize: page_size,
|
573
|
+
sort: 'name=asc'
|
574
|
+
})
|
575
|
+
parse_response(response, 'keys')
|
576
|
+
end
|
577
|
+
end
|
578
|
+
|
579
|
+
def get_key(id: nil)
|
580
|
+
response = request(:post, 'account/auth/key/get', { teamId: team_id, keyId: id })
|
581
|
+
# response contains a list of keys with 1 item
|
582
|
+
parse_response(response, 'keys').first
|
583
|
+
end
|
584
|
+
|
585
|
+
def download_key(id: nil)
|
586
|
+
response = request(:get, 'account/auth/key/download', { teamId: team_id, keyId: id })
|
587
|
+
parse_response(response)
|
588
|
+
end
|
589
|
+
|
590
|
+
def create_key!(name: nil, service_configs: nil)
|
591
|
+
params = {
|
592
|
+
name: name,
|
593
|
+
serviceConfigurations: service_configs,
|
594
|
+
teamId: team_id
|
595
|
+
}
|
596
|
+
|
597
|
+
response = request(:post, 'account/auth/key/create') do |req|
|
598
|
+
req.headers['Content-Type'] = 'application/json'
|
599
|
+
req.body = params.to_json
|
600
|
+
end
|
601
|
+
|
602
|
+
# response contains a list of keys with 1 item
|
603
|
+
parse_response(response, 'keys').first
|
604
|
+
end
|
605
|
+
|
606
|
+
def revoke_key!(id: nil)
|
607
|
+
response = request(:post, 'account/auth/key/revoke', { teamId: team_id, keyId: id })
|
608
|
+
parse_response(response)
|
609
|
+
end
|
610
|
+
|
563
611
|
private
|
564
612
|
|
565
613
|
# This is a cache of entity type (App, AppGroup, Certificate, Device) to csrf_tokens
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 2.47.0.beta.
|
4
|
+
version: 2.47.0.beta.20170713010003
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Felix Krause
|
@@ -15,7 +15,7 @@ authors:
|
|
15
15
|
autorequire:
|
16
16
|
bindir: bin
|
17
17
|
cert_chain: []
|
18
|
-
date: 2017-07-
|
18
|
+
date: 2017-07-13 00:00:00.000000000 Z
|
19
19
|
dependencies:
|
20
20
|
- !ruby/object:Gem::Dependency
|
21
21
|
name: slack-notifier
|
@@ -1312,6 +1312,7 @@ files:
|
|
1312
1312
|
- spaceship/lib/spaceship/portal/app_service.rb
|
1313
1313
|
- spaceship/lib/spaceship/portal/certificate.rb
|
1314
1314
|
- spaceship/lib/spaceship/portal/device.rb
|
1315
|
+
- spaceship/lib/spaceship/portal/key.rb
|
1315
1316
|
- spaceship/lib/spaceship/portal/person.rb
|
1316
1317
|
- spaceship/lib/spaceship/portal/persons.rb
|
1317
1318
|
- spaceship/lib/spaceship/portal/portal.rb
|