fastlane 2.120.0.beta.20190409200021 → 2.120.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA1:
3
- metadata.gz: 0f362836779ae94d1375000a6bd541c1590fc613
4
- data.tar.gz: 06605ed056708f0bb519c65fe82247d20259cac4
3
+ metadata.gz: 0ef2c55dc80f08a06f973a22f3497f780c98f071
4
+ data.tar.gz: e55e8f9723433c7179e5c2ba711e249c7c6f7a13
5
5
  SHA512:
6
- metadata.gz: ef32f05c5fd00b1f931f499e016b9dd755b455b8a73b6f6c51e796408051c6ca321da54dae7d8febc1ad9b63a9987cc866b4d91c5b64ee9a8b21084ff18942a8
7
- data.tar.gz: cfc325565ed8aab5f69fd2ff0c720ad72b58363ed61928f47ac23dc993d8cc0a3b3e542ca36c6123090872111537c05aabc596d087a7726406a2b2404f387e5e
6
+ metadata.gz: 7579b03ba7dea736f98b6107e01628849d0748763f1191c741cc7c76aa002f367907598135823a71f62b07552fc1e385a04817546077791cb3b31eda5c4f4e30
7
+ data.tar.gz: be2d8ae35276ec9ac10ddeab361b0db8467e1f4e034eb19f52cd3b737e8379f71e7c62f83c65caf07e4a1c94898e1f38098b4f1e28220ed18055e24c18bc6efb
data/README.md CHANGED
@@ -33,29 +33,17 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
33
33
  <!-- This table is regenerated and resorted on each release -->
34
34
  <table id='team'>
35
35
  <tr>
36
- <td id='jan-piotrowski'>
37
- <a href='https://github.com/janpio'>
38
- <img src='https://github.com/janpio.png?size=140'>
39
- </a>
40
- <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
41
- </td>
42
- <td id='danielle-tomlinson'>
43
- <a href='https://github.com/DanToml'>
44
- <img src='https://github.com/DanToml.png?size=140'>
45
- </a>
46
- <h4 align='center'><a href='https://twitter.com/DanToml'>Danielle Tomlinson</a></h4>
47
- </td>
48
- <td id='jorge-revuelta-h'>
49
- <a href='https://github.com/minuscorp'>
50
- <img src='https://github.com/minuscorp.png?size=140'>
36
+ <td id='manu-wallner'>
37
+ <a href='https://github.com/milch'>
38
+ <img src='https://github.com/milch.png?size=140'>
51
39
  </a>
52
- <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
40
+ <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
53
41
  </td>
54
- <td id='helmut-januschka'>
55
- <a href='https://github.com/hjanuschka'>
56
- <img src='https://github.com/hjanuschka.png?size=140'>
42
+ <td id='kohki-miki'>
43
+ <a href='https://github.com/giginet'>
44
+ <img src='https://github.com/giginet.png?size=140'>
57
45
  </a>
58
- <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
46
+ <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
59
47
  </td>
60
48
  <td id='aaron-brager'>
61
49
  <a href='https://github.com/getaaron'>
@@ -63,37 +51,17 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
63
51
  </a>
64
52
  <h4 align='center'><a href='https://twitter.com/getaaron'>Aaron Brager</a></h4>
65
53
  </td>
66
- </tr>
67
- <tr>
68
- <td id='jérôme-lacoste'>
69
- <a href='https://github.com/lacostej'>
70
- <img src='https://github.com/lacostej.png?size=140'>
71
- </a>
72
- <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
73
- </td>
74
54
  <td id='luka-mirosevic'>
75
55
  <a href='https://github.com/lmirosevic'>
76
56
  <img src='https://github.com/lmirosevic.png?size=140'>
77
57
  </a>
78
58
  <h4 align='center'><a href='https://twitter.com/lmirosevic'>Luka Mirosevic</a></h4>
79
59
  </td>
80
- <td id='kohki-miki'>
81
- <a href='https://github.com/giginet'>
82
- <img src='https://github.com/giginet.png?size=140'>
83
- </a>
84
- <h4 align='center'><a href='https://twitter.com/giginet'>Kohki Miki</a></h4>
85
- </td>
86
- <td id='fumiya-nakamura'>
87
- <a href='https://github.com/nafu'>
88
- <img src='https://github.com/nafu.png?size=140'>
89
- </a>
90
- <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
91
- </td>
92
- <td id='josh-holtz'>
93
- <a href='https://github.com/joshdholtz'>
94
- <img src='https://github.com/joshdholtz.png?size=140'>
60
+ <td id='jimmy-dee'>
61
+ <a href='https://github.com/jdee'>
62
+ <img src='https://github.com/jdee.png?size=140'>
95
63
  </a>
96
- <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
64
+ <h4 align='center'>Jimmy Dee</h4>
97
65
  </td>
98
66
  </tr>
99
67
  <tr>
@@ -103,17 +71,17 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
103
71
  </a>
104
72
  <h4 align='center'><a href='https://twitter.com/mellis1995'>Matthew Ellis</a></h4>
105
73
  </td>
106
- <td id='olivier-halligon'>
107
- <a href='https://github.com/AliSoftware'>
108
- <img src='https://github.com/AliSoftware.png?size=140'>
74
+ <td id='fumiya-nakamura'>
75
+ <a href='https://github.com/nafu'>
76
+ <img src='https://github.com/nafu.png?size=140'>
109
77
  </a>
110
- <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
78
+ <h4 align='center'><a href='https://twitter.com/nafu003'>Fumiya Nakamura</a></h4>
111
79
  </td>
112
- <td id='andrew-mcburney'>
113
- <a href='https://github.com/armcburney'>
114
- <img src='https://github.com/armcburney.png?size=140'>
80
+ <td id='danielle-tomlinson'>
81
+ <a href='https://github.com/DanToml'>
82
+ <img src='https://github.com/DanToml.png?size=140'>
115
83
  </a>
116
- <h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
84
+ <h4 align='center'><a href='https://twitter.com/DanToml'>Danielle Tomlinson</a></h4>
117
85
  </td>
118
86
  <td id='iulian-onofrei'>
119
87
  <a href='https://github.com/revolter'>
@@ -121,31 +89,31 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
121
89
  </a>
122
90
  <h4 align='center'><a href='https://twitter.com/Revolt666'>Iulian Onofrei</a></h4>
123
91
  </td>
124
- <td id='maksym-grebenets'>
125
- <a href='https://github.com/mgrebenets'>
126
- <img src='https://github.com/mgrebenets.png?size=140'>
92
+ <td id='josh-holtz'>
93
+ <a href='https://github.com/joshdholtz'>
94
+ <img src='https://github.com/joshdholtz.png?size=140'>
127
95
  </a>
128
- <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
96
+ <h4 align='center'><a href='https://twitter.com/joshdholtz'>Josh Holtz</a></h4>
129
97
  </td>
130
98
  </tr>
131
99
  <tr>
132
- <td id='stefan-natchev'>
133
- <a href='https://github.com/snatchev'>
134
- <img src='https://github.com/snatchev.png?size=140'>
135
- </a>
136
- <h4 align='center'><a href='https://twitter.com/snatchev'>Stefan Natchev</a></h4>
137
- </td>
138
100
  <td id='felix-krause'>
139
101
  <a href='https://github.com/KrauseFx'>
140
102
  <img src='https://github.com/KrauseFx.png?size=140'>
141
103
  </a>
142
104
  <h4 align='center'><a href='https://twitter.com/KrauseFx'>Felix Krause</a></h4>
143
105
  </td>
144
- <td id='jimmy-dee'>
145
- <a href='https://github.com/jdee'>
146
- <img src='https://github.com/jdee.png?size=140'>
106
+ <td id='helmut-januschka'>
107
+ <a href='https://github.com/hjanuschka'>
108
+ <img src='https://github.com/hjanuschka.png?size=140'>
147
109
  </a>
148
- <h4 align='center'>Jimmy Dee</h4>
110
+ <h4 align='center'><a href='https://twitter.com/hjanuschka'>Helmut Januschka</a></h4>
111
+ </td>
112
+ <td id='jan-piotrowski'>
113
+ <a href='https://github.com/janpio'>
114
+ <img src='https://github.com/janpio.png?size=140'>
115
+ </a>
116
+ <h4 align='center'><a href='https://twitter.com/Sujan'>Jan Piotrowski</a></h4>
149
117
  </td>
150
118
  <td id='joshua-liebowitz'>
151
119
  <a href='https://github.com/taquitos'>
@@ -153,11 +121,43 @@ If the above doesn't help, please [submit an issue](https://github.com/fastlane/
153
121
  </a>
154
122
  <h4 align='center'><a href='https://twitter.com/taquitos'>Joshua Liebowitz</a></h4>
155
123
  </td>
156
- <td id='manu-wallner'>
157
- <a href='https://github.com/milch'>
158
- <img src='https://github.com/milch.png?size=140'>
124
+ <td id='olivier-halligon'>
125
+ <a href='https://github.com/AliSoftware'>
126
+ <img src='https://github.com/AliSoftware.png?size=140'>
159
127
  </a>
160
- <h4 align='center'><a href='https://twitter.com/acrooow'>Manu Wallner</a></h4>
128
+ <h4 align='center'><a href='https://twitter.com/aligatr'>Olivier Halligon</a></h4>
129
+ </td>
130
+ </tr>
131
+ <tr>
132
+ <td id='maksym-grebenets'>
133
+ <a href='https://github.com/mgrebenets'>
134
+ <img src='https://github.com/mgrebenets.png?size=140'>
135
+ </a>
136
+ <h4 align='center'><a href='https://twitter.com/mgrebenets'>Maksym Grebenets</a></h4>
137
+ </td>
138
+ <td id='jorge-revuelta-h'>
139
+ <a href='https://github.com/minuscorp'>
140
+ <img src='https://github.com/minuscorp.png?size=140'>
141
+ </a>
142
+ <h4 align='center'><a href='https://twitter.com/minuscorp'>Jorge Revuelta H</a></h4>
143
+ </td>
144
+ <td id='stefan-natchev'>
145
+ <a href='https://github.com/snatchev'>
146
+ <img src='https://github.com/snatchev.png?size=140'>
147
+ </a>
148
+ <h4 align='center'><a href='https://twitter.com/snatchev'>Stefan Natchev</a></h4>
149
+ </td>
150
+ <td id='jérôme-lacoste'>
151
+ <a href='https://github.com/lacostej'>
152
+ <img src='https://github.com/lacostej.png?size=140'>
153
+ </a>
154
+ <h4 align='center'><a href='https://twitter.com/lacostej'>Jérôme Lacoste</a></h4>
155
+ </td>
156
+ <td id='andrew-mcburney'>
157
+ <a href='https://github.com/armcburney'>
158
+ <img src='https://github.com/armcburney.png?size=140'>
159
+ </a>
160
+ <h4 align='center'><a href='https://twitter.com/armcburney'>Andrew McBurney</a></h4>
161
161
  </td>
162
162
  </tr>
163
163
  </table>
@@ -24,47 +24,50 @@ module Fastlane
24
24
  Spaceship::Tunes.select_team
25
25
  UI.message("Login successful")
26
26
 
27
- platform = params[:platform]
28
-
29
27
  app = Spaceship::Tunes::Application.find(params[:app_identifier])
30
28
  if params[:live]
31
29
  UI.message("Fetching the latest build number for live-version")
32
30
  UI.user_error!("Could not find a live-version of #{params[:app_identifier]} on iTC") unless app.live_version
33
31
  build_nr = app.live_version.current_build_number
32
+
33
+ UI.message("Latest upload for live-version #{app.live_version.version} is build: #{build_nr}")
34
34
  else
35
35
  version_number = params[:version]
36
- unless version_number
37
- # Automatically fetch the latest version in testflight
38
- begin
39
- train_numbers = app.all_build_train_numbers(platform: platform)
40
- testflight_version = self.order_versions(train_numbers).last
41
- rescue
42
- testflight_version = params[:version]
43
- end
44
-
45
- if testflight_version
46
- version_number = testflight_version
47
- else
48
- version_number = UI.input("You have to specify a new version number, as there are multiple to choose from")
49
- end
50
36
 
37
+ # Filter on app (and version is specified)
38
+ filter = { app: app.apple_id }
39
+ filter["version"] = version_number if version_number
40
+
41
+ # Get version number from latest pre-release if no version number given
42
+ client = Spaceship::ConnectAPI::Base.client
43
+ version = client.get_pre_release_versions(filter: filter, sort: "-version", limit: 1).first
44
+ unless version
45
+ UI.user_error!("Could not find a build number for version #{version_number}")
51
46
  end
52
47
 
48
+ # Need pre_release_version_id for filtering build numbers
49
+ pre_release_version_id = version["id"]
50
+ version_number = version["attributes"]["version"]
51
+
53
52
  UI.message("Fetching the latest build number for version #{version_number}")
54
53
 
55
- begin
56
- build_numbers = app.all_builds_for_train(train: version_number, platform: platform).map(&:build_version)
57
- build_nr = self.order_versions(build_numbers).last
58
- if build_nr.nil? && params[:initial_build_number]
59
- UI.message("Could not find a build on iTC. Using supplied 'initial_build_number' option")
60
- build_nr = params[:initial_build_number]
61
- end
62
- rescue
63
- UI.user_error!("Could not find a build on iTC - and 'initial_build_number' option is not set") unless params[:initial_build_number]
54
+ # Get latest build for version number
55
+ build = client.get_builds(filter: { app: app.apple_id, "preReleaseVersion" => pre_release_version_id }, sort: "-uploadedDate", limit: 1).first
56
+ if build
57
+ build_nr = build["attributes"]["version"]
58
+ build_nr
59
+ else
60
+ UI.important("Could not find a build number for version #{version_number} on App Store Connect")
61
+ end
62
+
63
+ # Show error and set initial build number
64
+ unless build_nr
65
+ UI.user_error!("Could not find a build on App Store Connect - and 'initial_build_number' option is not set") unless params[:initial_build_number]
64
66
  build_nr = params[:initial_build_number]
65
67
  end
68
+
69
+ UI.message("Latest upload for version #{version_number} is build: #{build_nr}")
66
70
  end
67
- UI.message("Latest upload for version #{version_number} is build: #{build_nr}")
68
71
 
69
72
  build_nr
70
73
  end
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
- VERSION = '2.120.0.beta.20190409200021'.freeze
2
+ VERSION = '2.120.0'.freeze
3
3
  DESCRIPTION = "The easiest way to automate beta deployments and releases for your iOS and Android apps".freeze
4
4
  MINIMUM_XCODE_RELEASE = "7.0".freeze
5
5
  RUBOCOP_REQUIREMENT = '0.49.1'.freeze
@@ -18,4 +18,4 @@ class Deliverfile: DeliverfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.119.0
21
+ // Generated with fastlane 2.120.0
@@ -1681,10 +1681,12 @@ func gitAdd(path: String? = nil,
1681
1681
  }
1682
1682
  func gitCommit(path: String,
1683
1683
  message: String,
1684
- skipGitHooks: Bool? = nil) {
1684
+ skipGitHooks: Bool? = nil,
1685
+ allowNothingToCommit: Bool? = nil) {
1685
1686
  let command = RubyCommand(commandID: "", methodName: "git_commit", className: nil, args: [RubyCommand.Argument(name: "path", value: path),
1686
1687
  RubyCommand.Argument(name: "message", value: message),
1687
- RubyCommand.Argument(name: "skip_git_hooks", value: skipGitHooks)])
1688
+ RubyCommand.Argument(name: "skip_git_hooks", value: skipGitHooks),
1689
+ RubyCommand.Argument(name: "allow_nothing_to_commit", value: allowNothingToCommit)])
1688
1690
  _ = runner.executeCommand(command)
1689
1691
  }
1690
1692
  func gitPull(onlyTags: Bool = false) {
@@ -2591,14 +2593,16 @@ func pushToGitRemote(localBranch: String? = nil,
2591
2593
  forceWithLease: Bool = false,
2592
2594
  tags: Bool = true,
2593
2595
  remote: String = "origin",
2594
- noVerify: Bool = false) {
2596
+ noVerify: Bool = false,
2597
+ setUpstream: Bool = false) {
2595
2598
  let command = RubyCommand(commandID: "", methodName: "push_to_git_remote", className: nil, args: [RubyCommand.Argument(name: "local_branch", value: localBranch),
2596
2599
  RubyCommand.Argument(name: "remote_branch", value: remoteBranch),
2597
2600
  RubyCommand.Argument(name: "force", value: force),
2598
2601
  RubyCommand.Argument(name: "force_with_lease", value: forceWithLease),
2599
2602
  RubyCommand.Argument(name: "tags", value: tags),
2600
2603
  RubyCommand.Argument(name: "remote", value: remote),
2601
- RubyCommand.Argument(name: "no_verify", value: noVerify)])
2604
+ RubyCommand.Argument(name: "no_verify", value: noVerify),
2605
+ RubyCommand.Argument(name: "set_upstream", value: setUpstream)])
2602
2606
  _ = runner.executeCommand(command)
2603
2607
  }
2604
2608
  func puts(message: String? = nil) {
@@ -4301,4 +4305,4 @@ let screengrabfile: Screengrabfile = Screengrabfile()
4301
4305
  let snapshotfile: Snapshotfile = Snapshotfile()
4302
4306
  // Please don't remove the lines below
4303
4307
  // They are used to detect outdated files
4304
- // FastlaneRunnerAPIVersion [0.9.44]
4308
+ // FastlaneRunnerAPIVersion [0.9.45]
@@ -18,4 +18,4 @@ class Gymfile: GymfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.119.0
21
+ // Generated with fastlane 2.120.0
@@ -18,4 +18,4 @@ class Matchfile: MatchfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.119.0
21
+ // Generated with fastlane 2.120.0
@@ -18,4 +18,4 @@ class Precheckfile: PrecheckfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.119.0
21
+ // Generated with fastlane 2.120.0
@@ -18,4 +18,4 @@ class Scanfile: ScanfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.119.0
21
+ // Generated with fastlane 2.120.0
@@ -18,4 +18,4 @@ class Screengrabfile: ScreengrabfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.119.0
21
+ // Generated with fastlane 2.120.0
@@ -18,4 +18,4 @@ class Snapshotfile: SnapshotfileProtocol {
18
18
 
19
19
 
20
20
 
21
- // Generated with fastlane 2.119.0
21
+ // Generated with fastlane 2.120.0
@@ -7,22 +7,15 @@ module FastlaneCore
7
7
  class << self
8
8
  # @return The build we waited for. This method will always return a build
9
9
  def wait_for_build_processing_to_be_complete(app_id: nil, platform: nil, train_version: nil, build_version: nil, poll_interval: 10, strict_build_watch: false)
10
- unless strict_build_watch
11
- # First, find the train and build version we want to watch for
12
- watched_build = watching_build(app_id: app_id, platform: platform)
13
- UI.crash!("Could not find a build for app: #{app_id} on platform: #{platform}") if watched_build.nil?
14
-
15
- unless watched_build.train_version == train_version && watched_build.build_version == build_version
16
- UI.important("Started watching build #{watched_build.train_version} - #{watched_build.build_version} but expected #{train_version} - #{build_version}")
17
- end
18
- train_version = watched_build.train_version
19
- build_version = watched_build.build_version
10
+ # Warn about strict_build_watch being removed in the future
11
+ if strict_build_watch
12
+ UI.deprecated(":strict_build_watch is no longer a used argument on FastlaneCore::BuildWatcher.")
20
13
  end
21
14
 
22
15
  loop do
23
- matched_build = matching_build(watched_train_version: train_version, watched_build_version: build_version, app_id: app_id, platform: platform)
16
+ matched_build, build_delivery = matching_build(watched_train_version: train_version, watched_build_version: build_version, app_id: app_id, platform: platform)
24
17
 
25
- report_status(build: matched_build)
18
+ report_status(build: matched_build, build_delivery: build_delivery)
26
19
 
27
20
  if matched_build && matched_build.processed?
28
21
  return matched_build
@@ -34,32 +27,30 @@ module FastlaneCore
34
27
 
35
28
  private
36
29
 
37
- def watching_build(app_id: nil, platform: nil)
38
- processing_builds = Spaceship::TestFlight::Build.all_processing_builds(app_id: app_id, platform: platform, retry_count: 2)
39
-
40
- watched_build = processing_builds.sort_by(&:upload_date).last
41
- watched_build || Spaceship::TestFlight::Build.latest(app_id: app_id, platform: platform)
42
- end
43
-
44
30
  def matching_build(watched_train_version: nil, watched_build_version: nil, app_id: nil, platform: nil)
45
- matched_builds = Spaceship::TestFlight::Build.builds_for_train(app_id: app_id, platform: platform, train_version: watched_train_version, retry_count: 2)
46
- matched_builds.find { |build| build.build_version == watched_build_version }
31
+ # Get build deliveries (newly uploaded processing builds)
32
+ client = Spaceship::ConnectAPI::Base.client
33
+ build_deliveries = client.get_build_deliveries(filter: { app: app_id, cfBundleShortVersionString: watched_train_version, cfBundleVersion: watched_build_version }, limit: 1)
34
+ build_delivery = build_deliveries.first
35
+
36
+ # Get processed builds when no longer in build deliveries
37
+ unless build_delivery
38
+ matched_builds = Spaceship::TestFlight::Build.all(app_id: app_id, platform: platform)
39
+ matched_build = matched_builds.find { |build| build.train_version.to_s == watched_train_version.to_s && build.build_version.to_s == watched_build_version.to_s }
40
+ end
41
+
42
+ return matched_build, build_delivery
47
43
  end
48
44
 
49
- def report_status(build: nil)
50
- # Due to App Store Connect, builds disappear from the build list altogether
51
- # after they finished processing. Before returning this build, we have to
52
- # wait for the build to appear in the build list again
53
- # As this method is very often used to wait for a build, and then do something
54
- # with it, we have to be sure that the build actually is ready
55
- if build.nil?
56
- UI.message("Build doesn't show up in the build list anymore, waiting for it to appear again (check your email for processing issues if this continues)")
57
- elsif build.active?
58
- UI.success("Build #{build.train_version} - #{build.build_version} is already being tested")
59
- elsif build.ready_to_submit? || build.export_compliance_missing? || build.review_rejected?
45
+ def report_status(build: nil, build_delivery: nil)
46
+ if build_delivery
47
+ UI.message("Waiting for App Store Connect to finish processing the new build (#{build_delivery['attributes']['cfBundleShortVersionString']} - #{build_delivery['attributes']['cfBundleVersion']})")
48
+ elsif build && !build.processed?
49
+ UI.message("Waiting for App Store Connect to finish processing the new build (#{build.train_version} - #{build.build_version})")
50
+ elsif build && build.processed?
60
51
  UI.success("Successfully finished processing the build #{build.train_version} - #{build.build_version}")
61
52
  else
62
- UI.message("Waiting for App Store Connect to finish processing the new build (#{build.train_version} - #{build.build_version})")
53
+ UI.message("Build doesn't show up in the build list anymore, waiting for it to appear again (check your email for processing issues if this continues)")
63
54
  end
64
55
  end
65
56
  end
@@ -58,10 +58,10 @@ module Pilot
58
58
  platform = fetch_app_platform
59
59
  app_version = FastlaneCore::IpaFileAnalyser.fetch_app_version(config[:ipa])
60
60
  app_build = FastlaneCore::IpaFileAnalyser.fetch_app_build(config[:ipa])
61
- latest_build = FastlaneCore::BuildWatcher.wait_for_build_processing_to_be_complete(app_id: app.apple_id, platform: platform, train_version: app_version, build_version: app_build, poll_interval: config[:wait_processing_interval], strict_build_watch: config[:wait_for_uploaded_build])
61
+ latest_build = FastlaneCore::BuildWatcher.wait_for_build_processing_to_be_complete(app_id: app.apple_id, platform: platform, train_version: app_version, build_version: app_build, poll_interval: config[:wait_processing_interval])
62
62
 
63
63
  unless latest_build.train_version == app_version && latest_build.build_version == app_build
64
- UI.important("Uploaded app #{app_version} - #{app_build}, but received build #{latest_build.train_version} - #{latest_build.build_version}. If you want to wait for uploaded build to be finished processing, use the `wait_for_uploaded_build` option")
64
+ UI.important("Uploaded app #{app_version} - #{app_build}, but received build #{latest_build.train_version} - #{latest_build.build_version}.")
65
65
  end
66
66
 
67
67
  return latest_build
@@ -121,6 +121,9 @@ module Pilot
121
121
  end
122
122
 
123
123
  def update_beta_app_meta(options, build)
124
+ # App Store Connect API build id
125
+ build_id = build.find_app_store_connect_build["id"]
126
+
124
127
  # Setting account required wth AppStore Connect API
125
128
  update_review_detail(build.app_id, { demo_account_required: options[:demo_account_required] })
126
129
 
@@ -143,17 +146,17 @@ module Pilot
143
146
  end
144
147
 
145
148
  if should_update_localized_build_information?(options)
146
- update_localized_build_review(build, options[:localized_build_info])
149
+ update_localized_build_review(build_id, options[:localized_build_info])
147
150
  elsif should_update_build_information?(options)
148
151
  begin
149
- update_localized_build_review(build, {}, default_info: { whats_new: options[:changelog] })
152
+ update_localized_build_review(build_id, {}, default_info: { whats_new: options[:changelog] })
150
153
  UI.success("Successfully set the changelog for build")
151
154
  rescue => ex
152
155
  UI.user_error!("Could not set changelog: #{ex}")
153
156
  end
154
157
  end
155
158
 
156
- update_build_beta_details(build, {
159
+ update_build_beta_details(build_id, {
157
160
  auto_notify_enabled: options[:notify_external_testers]
158
161
  })
159
162
  end
@@ -251,23 +254,27 @@ module Pilot
251
254
  end
252
255
 
253
256
  if options[:groups]
254
- groups = Spaceship::TestFlight::Group.filter_groups(app_id: uploaded_build.app_id) do |group|
255
- options[:groups].include?(group.name)
256
- end
257
- groups.each do |group|
258
- uploaded_build.add_group!(group)
257
+ client = Spaceship::ConnectAPI::Base.client
258
+ beta_group_ids = client.get_beta_groups(filter: { app: uploaded_build.app_id }).select do |group|
259
+ options[:groups].include?(group["attributes"]["name"])
260
+ end.map do |group|
261
+ group["id"]
259
262
  end
260
- end
261
263
 
262
- if options[:distribute_external]
263
- external_group = Spaceship::TestFlight::Group.default_external_group(app_id: uploaded_build.app_id)
264
- uploaded_build.add_group!(external_group) unless external_group.nil?
264
+ unless beta_group_ids.empty?
265
+ build = uploaded_build.find_app_store_connect_build
266
+ build_id = build["id"]
265
267
 
266
- if external_group.nil? && options[:groups].nil?
267
- UI.user_error!("You must specify at least one group using the `:groups` option to distribute externally")
268
+ client.add_beta_groups_to_build(build_id: build_id, beta_group_ids: beta_group_ids)
268
269
  end
269
270
  end
270
271
 
272
+ if options[:distribute_external] && options[:groups].nil?
273
+ # Legacy Spaceship::TestFlight API used to have a `default_external_group` that would automatically
274
+ # get selected but this no longer exists with Spaceship::ConnectAPI
275
+ UI.user_error!("You must specify at least one group using the `:groups` option to distribute externally")
276
+ end
277
+
271
278
  true
272
279
  end
273
280
 
@@ -353,10 +360,7 @@ module Pilot
353
360
  end
354
361
  end
355
362
 
356
- def update_localized_build_review(build, info_by_lang, default_info: nil)
357
- resp = Spaceship::ConnectAPI::Base.client.get_builds(filter: { expired: false, processingState: "PROCESSING,VALID", version: build.build_version })
358
- build_id = resp.first["id"]
359
-
363
+ def update_localized_build_review(build_id, info_by_lang, default_info: nil)
360
364
  info_by_lang = info_by_lang.collect { |k, v| [k.to_sym, v] }.to_h
361
365
 
362
366
  if default_info
@@ -401,12 +405,8 @@ module Pilot
401
405
  end
402
406
  end
403
407
 
404
- def update_build_beta_details(build, info)
408
+ def update_build_beta_details(build_id, info)
405
409
  client = Spaceship::ConnectAPI::Base.client
406
-
407
- build = build.find_app_store_connect_build
408
- build_id = build["id"]
409
-
410
410
  resp = client.get_build_beta_details(filter: { build: build_id })
411
411
  build_beta_details_id = resp.first["id"]
412
412
 
@@ -240,6 +240,7 @@ module Pilot
240
240
  end),
241
241
  FastlaneCore::ConfigItem.new(key: :wait_for_uploaded_build,
242
242
  env_name: "PILOT_WAIT_FOR_UPLOADED_BUILD",
243
+ deprecated: "No longer needed with the transition over to the App Store Connect API",
243
244
  description: "Use version info from uploaded ipa file to determine what build to use for distribution. If set to false, latest processing or any latest build will be used",
244
245
  is_string: false,
245
246
  default_value: false),
@@ -513,8 +513,9 @@ module Spaceship
513
513
  end
514
514
 
515
515
  # Get the `itctx` from the new (22nd May 2017) API endpoint "olympus"
516
+ # Update (29th March 2019) olympus migrates to new appstoreconnect API
516
517
  def fetch_olympus_session
517
- response = request(:get, "https://olympus.itunes.apple.com/v1/session")
518
+ response = request(:get, "https://appstoreconnect.apple.com/olympus/v1/session")
518
519
  body = response.body
519
520
  if body
520
521
  body = JSON.parse(body) if body.kind_of?(String)
@@ -543,7 +544,7 @@ module Spaceship
543
544
  # Fixes issue https://github.com/fastlane/fastlane/issues/13281
544
545
  # Even though we are using https://appstoreconnect.apple.com, the service key needs to still use a
545
546
  # hostname through itunesconnect.apple.com
546
- response = request(:get, "https://olympus.itunes.apple.com/v1/app/config?hostname=itunesconnect.apple.com")
547
+ response = request(:get, "https://appstoreconnect.apple.com/olympus/v1/app/config?hostname=itunesconnect.apple.com")
547
548
  @service_key = response.body["authServiceKey"].to_s
548
549
 
549
550
  raise "Service key is empty" if @service_key.length == 0
@@ -599,7 +600,7 @@ module Spaceship
599
600
  def fetch_program_license_agreement_messages
600
601
  all_messages = []
601
602
 
602
- messages_request = request(:get, "https://olympus.itunes.apple.com/v1/contractMessages")
603
+ messages_request = request(:get, "https://appstoreconnect.apple.com/olympus/v1/contractMessages")
603
604
  body = messages_request.body
604
605
  if body
605
606
  body = JSON.parse(body) if body.kind_of?(String)
@@ -18,13 +18,14 @@ module Spaceship
18
18
  'https://appstoreconnect.apple.com/iris/v1/'
19
19
  end
20
20
 
21
- def build_params(filter: nil, includes: nil, limit: nil, sort: nil)
21
+ def build_params(filter: nil, includes: nil, limit: nil, sort: nil, cursor: nil)
22
22
  params = {}
23
23
 
24
24
  params[:filter] = filter if filter && !filter.empty?
25
25
  params[:include] = includes if includes
26
26
  params[:limit] = limit if limit
27
27
  params[:sort] = sort if sort
28
+ params[:cursor] = cursor if cursor
28
29
 
29
30
  return params
30
31
  end
@@ -218,18 +219,30 @@ module Spaceship
218
219
  handle_response(response)
219
220
  end
220
221
 
221
- def get_builds(filter: {}, includes: "buildBetaDetail,betaBuildMetrics", limit: 10, sort: "uploadedDate")
222
+ def get_build_deliveries(filter: {}, includes: nil, limit: 10, sort: nil)
222
223
  # GET
223
- # https://appstoreconnect.apple.com/iris/v1/builds
224
+ # https://appstoreconnect.apple.com/iris/v1/buildDeliveries
224
225
  params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
225
226
 
226
- response = request(:get, "builds") do |req|
227
+ response = request(:get, "buildDeliveries") do |req|
227
228
  req.options.params_encoder = Faraday::NestedParamsEncoder
228
229
  req.params = params
229
230
  end
230
231
  handle_response(response)
231
232
  end
232
233
 
234
+ def get_builds(filter: {}, includes: "buildBetaDetail,betaBuildMetrics", limit: 10, sort: "uploadedDate", cursor: nil, only_data: true)
235
+ # GET
236
+ # https://appstoreconnect.apple.com/iris/v1/builds
237
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort, cursor: cursor)
238
+
239
+ response = request(:get, "builds") do |req|
240
+ req.options.params_encoder = Faraday::NestedParamsEncoder
241
+ req.params = params
242
+ end
243
+ handle_response(response, only_data: only_data)
244
+ end
245
+
233
246
  def patch_builds(build_id: nil, attributes: {})
234
247
  # PATCH
235
248
  # https://appstoreconnect.apple.com/iris/v1/builds/<build_id>
@@ -277,9 +290,54 @@ module Spaceship
277
290
  handle_response(response)
278
291
  end
279
292
 
293
+ def get_pre_release_versions(filter: {}, includes: nil, limit: 40, sort: nil)
294
+ # GET
295
+ # https://appstoreconnect.apple.com/iris/v1/preReleaseVersions
296
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
297
+
298
+ response = request(:get, "preReleaseVersions") do |req|
299
+ req.options.params_encoder = Faraday::NestedParamsEncoder
300
+ req.params = params
301
+ end
302
+ handle_response(response)
303
+ end
304
+
305
+ def get_beta_groups(filter: {}, includes: nil, limit: 40, sort: nil)
306
+ # GET
307
+ # https://appstoreconnect.apple.com/iris/v1/betaGroups
308
+ params = build_params(filter: filter, includes: includes, limit: limit, sort: sort)
309
+
310
+ response = request(:get, "betaGroups") do |req|
311
+ req.options.params_encoder = Faraday::NestedParamsEncoder
312
+ req.params = params
313
+ end
314
+ handle_response(response)
315
+ end
316
+
317
+ def add_beta_groups_to_build(build_id: nil, beta_group_ids: [])
318
+ # POST
319
+ # https://appstoreconnect.apple.com/iris/v1/builds/<build_id>/relationships/betaGroups
320
+
321
+ body = {
322
+ data: beta_group_ids.map do |id|
323
+ {
324
+ type: "betaGroups",
325
+ id: id
326
+ }
327
+ end
328
+ }
329
+
330
+ response = request(:post) do |req|
331
+ req.url("builds/#{build_id}/relationships/betaGroups")
332
+ req.body = body.to_json
333
+ req.headers['Content-Type'] = 'application/json'
334
+ end
335
+ handle_response(response)
336
+ end
337
+
280
338
  protected
281
339
 
282
- def handle_response(response)
340
+ def handle_response(response, only_data: true)
283
341
  if (200...300).cover?(response.status) && (response.body.nil? || response.body.empty?)
284
342
  return
285
343
  end
@@ -296,7 +354,7 @@ module Spaceship
296
354
 
297
355
  raise UnexpectedResponse, "Temporary App Store Connect error: #{response.body}" if response.body['statusCode'] == 'ERROR'
298
356
 
299
- return response.body['data'] if response.body['data']
357
+ return response.body['data'] if response.body['data'] && only_data
300
358
 
301
359
  return response.body
302
360
  end
@@ -231,7 +231,7 @@ module Spaceship
231
231
 
232
232
  # Bridges the TestFlight::Build to the App Store Connect API build
233
233
  def find_app_store_connect_build
234
- resp = Spaceship::ConnectAPI::Base.client.get_builds(filter: { expired: false, processingState: "PROCESSING,VALID", version: self.build_version, app: app_id })
234
+ resp = Spaceship::ConnectAPI::Base.client.get_builds(filter: { expired: false, processingState: "PROCESSING,VALID", version: self.build_version, "preReleaseVersion.version" => self.train_version, app: app_id })
235
235
  resp.first
236
236
  end
237
237
  end
@@ -13,12 +13,65 @@ module Spaceship::TestFlight
13
13
  # See `Spaceship::TestFlight::Build#reload`
14
14
 
15
15
  def self.all(app_id: nil, platform: nil, retry_count: 3)
16
- data = client.get_build_trains(app_id: app_id, platform: platform)
17
- trains = {}
16
+ client = Spaceship::ConnectAPI::Base.client
17
+
18
+ builds = []
19
+ included = []
20
+ cursor = nil
21
+
22
+ loop do
23
+ builds_resp = client.get_builds(filter: { app: app_id, processingState: "VALID,PROCESSING,FAILED,INVALID" }, limit: 100, sort: "uploadedDate", includes: "preReleaseVersion,app", cursor: cursor, only_data: false)
24
+ builds += builds_resp["data"]
25
+ included += (builds_resp["included"] || [])
26
+
27
+ next_page = builds_resp["links"]["next"]
28
+ break if next_page.nil?
29
+
30
+ uri = URI.parse(next_page)
31
+ params = CGI.parse(uri.query)
32
+ cursor = params["cursor"].first
18
33
 
19
- data.each do |train_version|
20
- builds_data = client.get_builds_for_train(app_id: app_id, platform: platform, train_version: train_version, retry_count: retry_count)
21
- trains[train_version] = builds_data.map { |attrs| Spaceship::TestFlight::Build.new(attrs) }
34
+ break if cursor.nil?
35
+ end
36
+
37
+ # Load with all of the data
38
+ builds.map do |build|
39
+ r = build["relationships"]["app"]["data"]
40
+ build["app"] = included.find { |h| h["type"] == r["type"] && h["id"] == r["id"] }
41
+
42
+ r = build["relationships"]["preReleaseVersion"]["data"]
43
+ build["preReleaseVersion"] = included.find { |h| h["type"] == r["type"] && h["id"] == r["id"] }
44
+
45
+ build
46
+ end
47
+
48
+ # Map to testflight build response????
49
+ train_builds = builds.map do |build|
50
+ h = {}
51
+
52
+ h['buildVersion'] = build["attributes"]["version"]
53
+ h['uploadDate'] = build["attributes"]["uploadedDate"]
54
+
55
+ processing_state = build["attributes"]["processingState"]
56
+ if processing_state == "VALID"
57
+ h['externalState'] = Spaceship::TestFlight::Build::BUILD_STATES[:active]
58
+ elsif processing_state == "PROCESSING"
59
+ h['externalState'] = Spaceship::TestFlight::Build::BUILD_STATES[:processing]
60
+ end
61
+
62
+ h['appAdamId'] = build["app"]["id"]
63
+ h['bundleId'] = build["app"]["attributes"]["bundleId"]
64
+
65
+ h['trainVersion'] = build["preReleaseVersion"]["attributes"]["version"]
66
+
67
+ h
68
+ end
69
+
70
+ trains = {}
71
+ train_builds.each do |build|
72
+ train_version = build["trainVersion"]
73
+ trains[train_version] ||= []
74
+ trains[train_version] << Spaceship::TestFlight::Build.new(build)
22
75
  end
23
76
 
24
77
  self.new(trains)
metadata CHANGED
@@ -1,33 +1,33 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.120.0.beta.20190409200021
4
+ version: 2.120.0
5
5
  platform: ruby
6
6
  authors:
7
- - Stefan Natchev
8
- - Josh Holtz
9
- - Maksym Grebenets
7
+ - Kohki Miki
8
+ - Iulian Onofrei
10
9
  - Manu Wallner
11
- - Fumiya Nakamura
12
- - Luka Mirosevic
13
- - Jan Piotrowski
14
10
  - Danielle Tomlinson
15
- - Helmut Januschka
16
- - Kohki Miki
17
11
  - Aaron Brager
18
- - Jimmy Dee
19
- - Andrew McBurney
20
- - Jorge Revuelta H
21
- - Joshua Liebowitz
22
- - Olivier Halligon
23
12
  - Jérôme Lacoste
13
+ - Maksym Grebenets
14
+ - Helmut Januschka
24
15
  - Felix Krause
25
- - Iulian Onofrei
16
+ - Fumiya Nakamura
17
+ - Stefan Natchev
18
+ - Jorge Revuelta H
26
19
  - Matthew Ellis
20
+ - Jan Piotrowski
21
+ - Andrew McBurney
22
+ - Josh Holtz
23
+ - Luka Mirosevic
24
+ - Joshua Liebowitz
25
+ - Jimmy Dee
26
+ - Olivier Halligon
27
27
  autorequire:
28
28
  bindir: bin
29
29
  cert_chain: []
30
- date: 2019-04-09 00:00:00.000000000 Z
30
+ date: 2019-04-10 00:00:00.000000000 Z
31
31
  dependencies:
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: slack-notifier
@@ -966,6 +966,8 @@ files:
966
966
  - fastlane/lib/fastlane.rb
967
967
  - fastlane/lib/fastlane/action.rb
968
968
  - fastlane/lib/fastlane/action_collector.rb
969
+ - fastlane/lib/fastlane/actions/.slack.rb.swp
970
+ - fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp
969
971
  - fastlane/lib/fastlane/actions/README.md
970
972
  - fastlane/lib/fastlane/actions/actions_helper.rb
971
973
  - fastlane/lib/fastlane/actions/adb.rb
@@ -1287,6 +1289,7 @@ files:
1287
1289
  - fastlane/swift/Fastlane.swift
1288
1290
  - fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj
1289
1291
  - fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/contents.xcworkspacedata
1292
+ - fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate
1290
1293
  - fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/xcshareddata/xcschemes/FastlaneRunner.xcscheme
1291
1294
  - fastlane/swift/FastlaneSwiftRunner/README.txt
1292
1295
  - fastlane/swift/Gymfile.swift
@@ -1569,6 +1572,7 @@ files:
1569
1572
  - spaceship/lib/spaceship/client.rb
1570
1573
  - spaceship/lib/spaceship/commands_generator.rb
1571
1574
  - spaceship/lib/spaceship/connect_api.rb
1575
+ - spaceship/lib/spaceship/connect_api/.DS_Store
1572
1576
  - spaceship/lib/spaceship/connect_api/base.rb
1573
1577
  - spaceship/lib/spaceship/connect_api/client.rb
1574
1578
  - spaceship/lib/spaceship/du/du_client.rb
@@ -1601,6 +1605,7 @@ files:
1601
1605
  - spaceship/lib/spaceship/portal/provisioning_profile.rb
1602
1606
  - spaceship/lib/spaceship/portal/provisioning_profile_template.rb
1603
1607
  - spaceship/lib/spaceship/portal/spaceship.rb
1608
+ - spaceship/lib/spaceship/portal/ui/.select_team.rb.swp
1604
1609
  - spaceship/lib/spaceship/portal/ui/select_team.rb
1605
1610
  - spaceship/lib/spaceship/portal/website_push.rb
1606
1611
  - spaceship/lib/spaceship/provider.rb
@@ -1688,24 +1693,24 @@ metadata:
1688
1693
  post_install_message:
1689
1694
  rdoc_options: []
1690
1695
  require_paths:
1696
+ - credentials_manager/lib
1697
+ - pem/lib
1698
+ - snapshot/lib
1691
1699
  - frameit/lib
1692
- - spaceship/lib
1693
- - cert/lib
1694
- - sigh/lib
1695
- - precheck/lib
1696
- - gym/lib
1700
+ - match/lib
1697
1701
  - fastlane_core/lib
1702
+ - deliver/lib
1703
+ - scan/lib
1698
1704
  - supply/lib
1699
- - produce/lib
1700
- - match/lib
1705
+ - cert/lib
1706
+ - fastlane/lib
1707
+ - spaceship/lib
1701
1708
  - pilot/lib
1702
- - snapshot/lib
1709
+ - gym/lib
1710
+ - precheck/lib
1703
1711
  - screengrab/lib
1704
- - fastlane/lib
1705
- - deliver/lib
1706
- - pem/lib
1707
- - scan/lib
1708
- - credentials_manager/lib
1712
+ - sigh/lib
1713
+ - produce/lib
1709
1714
  required_ruby_version: !ruby/object:Gem::Requirement
1710
1715
  requirements:
1711
1716
  - - ">="
@@ -1713,12 +1718,12 @@ required_ruby_version: !ruby/object:Gem::Requirement
1713
1718
  version: 2.0.0
1714
1719
  required_rubygems_version: !ruby/object:Gem::Requirement
1715
1720
  requirements:
1716
- - - ">"
1721
+ - - ">="
1717
1722
  - !ruby/object:Gem::Version
1718
- version: 1.3.1
1723
+ version: '0'
1719
1724
  requirements: []
1720
1725
  rubyforge_project:
1721
- rubygems_version: 2.6.8
1726
+ rubygems_version: 2.5.2.3
1722
1727
  signing_key:
1723
1728
  specification_version: 4
1724
1729
  summary: The easiest way to automate beta deployments and releases for your iOS and