fastlane 2.132.0.beta.20190920200012 → 2.132.0.beta.20190925200108

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: 3247e4c5b3c80c88baa6b716a4f7650dc61a4e8a
4
- data.tar.gz: 001e2c7f0b92be7c892bf4e5647b0a6071a07f09
3
+ metadata.gz: 5299efbbf927954bec3d42a5d107971a03083066
4
+ data.tar.gz: de00900bf485865c46fe29bebed94d7d295a2961
5
5
  SHA512:
6
- metadata.gz: 4121debd22ce939ebcafcde83bb556ed5f85ec7bbc801013fd3eb49ec0980253e94f8c40f04654d802bdafb9ecd123b21cbd7e4cfb20726f97866308d9e6ab21
7
- data.tar.gz: d4f8079fb3a28209abc6ba9eb8c122d04b8430aff9bbb62558c5244003420fe59958a78c6d4e76aaaee2605f73f253d75924a917535b93fc2da4485cec9d9610
6
+ metadata.gz: 50a851a3fb4d10fc8638028ceef2b5cb96ba18a6442844c0a1e472c6187a4fc535faf0936855d05887e5312d8ddc0d6b34fadb3cc929b39577cbfd6829977bf4
7
+ data.tar.gz: 288fed847f6b8502dfefdef7cead756ec5acaafe19bac106d44d34a335831fe53910bb471cb6952e74fb2de4915871f0ee10a8d25933c95b5bc1ba82a474f461
@@ -36,6 +36,7 @@ module Fastlane
36
36
  return build_nr
37
37
  else
38
38
  version_number = params[:version]
39
+ platform = params[:platform]
39
40
 
40
41
  # Create filter for get_builds with optional version number
41
42
  filter = { app: app.apple_id }
@@ -46,18 +47,25 @@ module Fastlane
46
47
  version_number_message = "any version"
47
48
  end
48
49
 
50
+ if platform
51
+ filter["preReleaseVersion.platform"] = Spaceship::ConnectAPI::Platform.map(platform)
52
+ platform_message = "#{platform} platform"
53
+ else
54
+ platform_message = "any platform"
55
+ end
56
+
49
57
  UI.message("Fetching the latest build number for #{version_number_message}")
50
58
 
51
59
  # Get latest build for optional version number and return build number if found
52
60
  build = Spaceship::ConnectAPI.get_builds(filter: filter, sort: "-uploadedDate", includes: "preReleaseVersion", limit: 1).first
53
61
  if build
54
62
  build_nr = build.version
55
- UI.message("Latest upload for version #{build.app_version} is build: #{build_nr}")
63
+ UI.message("Latest upload for version #{build.app_version} on #{platform_message} is build: #{build_nr}")
56
64
  return build_nr
57
65
  end
58
66
 
59
67
  # Let user know that build couldn't be found
60
- UI.important("Could not find a build for #{version_number_message} on App Store Connect")
68
+ UI.important("Could not find a build for #{version_number_message} on #{platform_message} on App Store Connect")
61
69
 
62
70
  if params[:initial_build_number].nil?
63
71
  UI.user_error!("Could not find a build on App Store Connect - and 'initial_build_number' option is not set")
@@ -6,7 +6,7 @@
6
6
 
7
7
  A new approach to iOS code signing: Share one code signing identity across your development team to simplify your codesigning setup and prevent code signing issues.
8
8
 
9
- _match_ is the implementation of the [https://codesigning.guide concept](https://codesigning.guide). _match_ creates all required certificates & provisioning profiles and stores them in a separate git repository. Every team member with access to the repo can use those credentials for code signing. _match_ also automatically repairs broken and expired credentials. It's the easiest way to share signing credentials across teams
9
+ _match_ is the implementation of the [codesigning.guide concept](https://codesigning.guide). _match_ creates all required certificates & provisioning profiles and stores them in a separate git repository. Every team member with access to the repo can use those credentials for code signing. _match_ also automatically repairs broken and expired credentials. It's the easiest way to share signing credentials across teams
10
10
 
11
11
  [More information on how to get started with codesigning](https://docs.fastlane.tools/codesigning/getting-started/)
12
12
 
@@ -138,7 +138,7 @@ match(git_branch: "team2", username: "user@team2.com")
138
138
 
139
139
  #### Google Cloud Storage
140
140
 
141
- If you use Google Cloud Storage, you don't need to do anything manually. Just use Google Cloud Storage, and the top level folder will be the team ID.
141
+ If you use Google Cloud Storage, you don't need to do anything manually for multiple teams. Just use Google Cloud Storage, and the top level folder will be the team ID.
142
142
 
143
143
  ### Run
144
144
 
@@ -233,7 +233,7 @@ There are two cases for reading and writing certificates stored in a Google Clou
233
233
  1. Continuous integration jobs. These will authenticate to your Google Cloud project via a service account, and use a `gc_keys.json` file as credentials.
234
234
  1. Developers on a local workstation. In this case, you should choose whether everyone on your team will create their own `gc_keys.json` file, or whether you want to manage access to the bucket directly using your developers' Google accounts.
235
235
 
236
- When running `fastlane match init` the first time, the setup process will give you the option to create your `gc_keys.json` file. This file contains the auth credentials needed to access your Google Cloud storage bucket. Make sure to keep that file secret and never add it to version control. We recommend adding `gc_keys.json` to your `.gitignore`
236
+ When running `fastlane match init` the first time, the setup process will give you the option to create your `gc_keys.json` file. This file contains the authentication credentials needed to access your Google Cloud storage bucket. Make sure to keep that file secret and never add it to version control. We recommend adding `gc_keys.json` to your `.gitignore`
237
237
 
238
238
  ##### Managing developer access via keys
239
239
  If you want to manage developer access to your certificates via authentication keys, every developer should create their own `gc_keys.json` and add the file to all their work machines. This will give the admin full control over who has read/write access to the given Storage bucket. At the same time it allows your team to revoke a single key if a file gets compromised.
@@ -0,0 +1,58 @@
1
+ module Fastlane
2
+ module Actions
3
+ class EnsureEnvVarsAction < Action
4
+ def self.run(params)
5
+ variables = params[:env_vars]
6
+
7
+ variables.each do |variable|
8
+ next unless ENV[variable].to_s.strip.empty?
9
+
10
+ UI.user_error!("Missing environment variable '#{variable}'")
11
+ end
12
+
13
+ is_one = variables.length == 1
14
+
15
+ UI.success("Environment variable#{is_one ? '' : 's'} '#{variables.join('\', \'')}' #{is_one ? 'is' : 'are'} set!")
16
+ end
17
+
18
+ def self.description
19
+ 'Raises an exception if the specified env vars are not set'
20
+ end
21
+
22
+ def self.details
23
+ 'This action will check if some environment variables are set.'
24
+ end
25
+
26
+ def self.available_options
27
+ [
28
+ FastlaneCore::ConfigItem.new(key: :env_vars,
29
+ description: 'The environment variables names that should be checked',
30
+ type: Array,
31
+ verify_block: proc do |value|
32
+ UI.user_error!('Specify at least one environment variable name') if value.empty?
33
+ end)
34
+ ]
35
+ end
36
+
37
+ def self.authors
38
+ ['revolter']
39
+ end
40
+
41
+ def self.example_code
42
+ [
43
+ 'ensure_env_vars(
44
+ env_vars: [\'GITHUB_USER_NAME\', \'GITHUB_API_TOKEN\']
45
+ )'
46
+ ]
47
+ end
48
+
49
+ def self.category
50
+ :misc
51
+ end
52
+
53
+ def self.is_supported?(platform)
54
+ true
55
+ end
56
+ end
57
+ end
58
+ end
@@ -11,15 +11,26 @@ module Fastlane
11
11
  require 'uri'
12
12
  require 'base64'
13
13
 
14
- UI.message("Parameter App name: #{params[:app_name]}")
14
+ app_id = params[:app_id].to_s.strip
15
15
  auth_token = params[:auth_token]
16
- app_name = params[:app_name]
16
+ app_name = params[:app_name].to_s
17
17
  apns_p12_password = params[:apns_p12_password]
18
18
  android_token = params[:android_token]
19
19
  android_gcm_sender_id = params[:android_gcm_sender_id]
20
20
 
21
+ has_app_id = !app_id.empty?
22
+ has_app_name = !app_name.empty?
23
+
24
+ is_update = has_app_id
25
+
26
+ UI.user_error!('Please specify the `app_id` or the `app_name` parameters!') if !has_app_id && !has_app_name
27
+
28
+ UI.message("Parameter App ID: #{app_id}") if has_app_id
29
+ UI.message("Parameter App name: #{app_name}") if has_app_name
30
+
21
31
  payload = {}
22
- payload['name'] = app_name
32
+
33
+ payload['name'] = app_name if has_app_name
23
34
 
24
35
  unless params[:apns_p12].nil?
25
36
  data = File.read(params[:apns_p12])
@@ -33,61 +44,70 @@ module Fastlane
33
44
  payload["gcm_key"] = android_token unless android_token.nil?
34
45
  payload["android_gcm_sender_id"] = android_gcm_sender_id unless android_gcm_sender_id.nil?
35
46
 
36
- # here's the actual lifting - POST to OneSignal
47
+ # here's the actual lifting - POST or PUT to OneSignal
37
48
 
38
49
  json_headers = { 'Content-Type' => 'application/json', 'Authorization' => "Basic #{auth_token}" }
39
- uri = URI.parse('https://onesignal.com/api/v1/apps')
50
+ url = +'https://onesignal.com/api/v1/apps'
51
+ url << '/' + app_id if is_update
52
+ uri = URI.parse(url)
40
53
  http = Net::HTTP.new(uri.host, uri.port)
41
54
  http.use_ssl = true
42
- response = http.post(uri.path, payload.to_json, json_headers)
55
+
56
+ if is_update
57
+ response = http.put(uri.path, payload.to_json, json_headers)
58
+ else
59
+ response = http.post(uri.path, payload.to_json, json_headers)
60
+ end
61
+
43
62
  response_body = JSON.parse(response.body)
44
63
 
45
64
  Actions.lane_context[SharedValues::ONE_SIGNAL_APP_ID] = response_body["id"]
46
65
  Actions.lane_context[SharedValues::ONE_SIGNAL_APP_AUTH_KEY] = response_body["basic_auth_key"]
47
66
 
48
- check_response_code(response)
67
+ check_response_code(response, is_update)
49
68
  end
50
69
 
51
- def self.check_response_code(response)
70
+ def self.check_response_code(response, is_update)
52
71
  case response.code.to_i
53
72
  when 200, 204
54
- puts("Successfully created new OneSignal app".green)
73
+ UI.success("Successfully #{is_update ? 'updated' : 'created new'} OneSignal app")
55
74
  else
56
75
  UI.user_error!("Unexpected #{response.code} with response: #{response.body}")
57
76
  end
58
77
  end
59
78
 
60
79
  def self.description
61
- "Create a new [OneSignal](https://onesignal.com/) application"
80
+ "Create or update a new [OneSignal](https://onesignal.com/) application"
62
81
  end
63
82
 
64
83
  def self.details
65
- "You can use this action to automatically create a OneSignal application. You can also upload a `.p12` with password, a GCM key, or both."
84
+ "You can use this action to automatically create or update a OneSignal application. You can also upload a `.p12` with password, a GCM key, or both."
66
85
  end
67
86
 
68
87
  def self.available_options
69
88
  [
70
- FastlaneCore::ConfigItem.new(key: :auth_token,
71
- env_name: "ONE_SIGNAL_AUTH_KEY",
72
- sensitive: true,
73
- description: "OneSignal Authorization Key",
74
- verify_block: proc do |value|
75
- unless value.to_s.length > 0
76
- UI.error("Please add 'ENV[\"ONE_SIGNAL_AUTH_KEY\"] = \"your token\"' to your Fastfile's `before_all` section.")
77
- UI.user_error!("No ONE_SIGNAL_AUTH_KEY given.")
78
- end
79
- end),
89
+ FastlaneCore::ConfigItem.new(key: :app_id,
90
+ env_name: "ONE_SIGNAL_APP_ID",
91
+ sensitive: true,
92
+ description: "OneSignal App ID. Setting this updates an existing app",
93
+ optional: true),
80
94
 
81
- FastlaneCore::ConfigItem.new(key: :app_name,
82
- env_name: "ONE_SIGNAL_APP_NAME",
83
- description: "OneSignal App Name",
95
+ FastlaneCore::ConfigItem.new(key: :auth_token,
96
+ env_name: "ONE_SIGNAL_AUTH_KEY",
97
+ sensitive: true,
98
+ description: "OneSignal Authorization Key",
84
99
  verify_block: proc do |value|
85
- unless value.to_s.length > 0
86
- UI.error("Please add 'ENV[\"ONE_SIGNAL_APP_NAME\"] = \"Your app name\"' to your Fastfile's `before_all` section.")
87
- UI.user_error!("No ONE_SIGNAL_APP_NAME given.")
100
+ if value.to_s.empty?
101
+ UI.error("Please add 'ENV[\"ONE_SIGNAL_AUTH_KEY\"] = \"your token\"' to your Fastfile's `before_all` section.")
102
+ UI.user_error!("No ONE_SIGNAL_AUTH_KEY given.")
88
103
  end
89
104
  end),
90
105
 
106
+ FastlaneCore::ConfigItem.new(key: :app_name,
107
+ env_name: "ONE_SIGNAL_APP_NAME",
108
+ description: "OneSignal App Name. This is required when creating an app (in other words, when `:app_id` is not set, and optional when updating an app",
109
+ optional: true),
110
+
91
111
  FastlaneCore::ConfigItem.new(key: :android_token,
92
112
  env_name: "ANDROID_TOKEN",
93
113
  description: "ANDROID GCM KEY",
@@ -121,8 +141,8 @@ module Fastlane
121
141
 
122
142
  def self.output
123
143
  [
124
- ['ONE_SIGNAL_APP_ID', 'The OneSignal app ID of the newly created app'],
125
- ['ONE_SIGNAL_APP_AUTH_KEY', 'The auth token for the newly created OneSignal app']
144
+ ['ONE_SIGNAL_APP_ID', 'The app ID of the newly created or updated app'],
145
+ ['ONE_SIGNAL_APP_AUTH_KEY', 'The auth token for the newly created or updated app']
126
146
  ]
127
147
  end
128
148
 
@@ -144,6 +164,16 @@ module Fastlane
144
164
  apns_p12: "Path to Apple .p12 file (optional)",
145
165
  apns_p12_password: "Password for .p12 file (optional)",
146
166
  apns_env: "production/sandbox (defaults to production)"
167
+ )',
168
+ 'onesignal(
169
+ app_id: "Your OneSignal App ID",
170
+ auth_token: "Your OneSignal Auth Token",
171
+ app_name: "New Name for OneSignal App",
172
+ android_token: "Your Android GCM key (optional)",
173
+ android_gcm_sender_id: "Your Android GCM Sender ID (optional)",
174
+ apns_p12: "Path to Apple .p12 file (optional)",
175
+ apns_p12_password: "Password for .p12 file (optional)",
176
+ apns_env: "production/sandbox (defaults to production)"
147
177
  )'
148
178
  ]
149
179
  end
@@ -47,6 +47,10 @@ module Fastlane
47
47
  command << "--verbose"
48
48
  end
49
49
 
50
+ if params[:use_modular_headers]
51
+ command << "--use-modular-headers"
52
+ end
53
+
50
54
  result = Actions.sh(command.join(' '))
51
55
  UI.success("Successfully pushed Podspec ⬆️ ")
52
56
  return result
@@ -118,7 +122,12 @@ module Fastlane
118
122
  optional: true,
119
123
  type: Boolean,
120
124
  default_value: false,
121
- env_name: "FL_POD_PUSH_VERBOSE")
125
+ env_name: "FL_POD_PUSH_VERBOSE"),
126
+ FastlaneCore::ConfigItem.new(key: :use_modular_headers,
127
+ description: "Use modular headers option during validation",
128
+ optional: true,
129
+ type: Boolean,
130
+ env_name: "FL_POD_PUSH_USE_MODULAR_HEADERS")
122
131
  ]
123
132
  end
124
133
 
@@ -1,5 +1,5 @@
1
1
  module Fastlane
2
- VERSION = '2.132.0.beta.20190920200012'.freeze
2
+ VERSION = '2.132.0.beta.20190925200108'.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
@@ -97,6 +97,7 @@ module Match
97
97
  end
98
98
 
99
99
  ensure_bucket_is_selected
100
+ check_bucket_permissions
100
101
  end
101
102
 
102
103
  def currently_used_team_id
@@ -234,74 +235,122 @@ module Match
234
235
  end
235
236
  end
236
237
 
237
- # User doesn't seem to have provided a keys file.
238
- UI.message("Looks like you don't have a Google Cloud #{DEFAULT_KEYS_FILE_NAME.cyan} file")
239
- UI.message("If you have one, make sure to put it into the '#{Dir.pwd}' directory and call it '#{DEFAULT_KEYS_FILE_NAME.cyan}'")
238
+ # User doesn't seem to have provided a keys file
239
+ UI.message("Looks like you don't have a Google Cloud #{DEFAULT_KEYS_FILE_NAME.cyan} file yet.")
240
+ UI.message("If you have one, make sure to put it into the '#{Dir.pwd}' directory and call it '#{DEFAULT_KEYS_FILE_NAME.cyan}'.")
240
241
  unless UI.confirm("Do you want fastlane to help you to create a #{DEFAULT_KEYS_FILE_NAME} file?")
241
242
  UI.user_error!("Process stopped, run fastlane again to start things up again")
242
243
  end
243
244
 
244
- UI.message("fastlane will help you create a keys file. First, open the following website")
245
+ UI.message("fastlane will help you create a keys file. Start by opening the following website:")
245
246
  UI.message("")
246
247
  UI.message("\t\thttps://console.cloud.google.com".cyan)
247
248
  UI.message("")
248
- UI.input("Press enter once you're logged in")
249
+ UI.input("Press [Enter] once you're logged in")
249
250
 
250
- UI.message("Now it's time to generate a new JSON auth file for fastlane to access Google Cloud")
251
251
  UI.message("First, switch to the Google Cloud project you want to use.")
252
- UI.message("If you don't have one yet, create a new one and switch to it")
252
+ UI.message("If you don't have one yet, create a new one and switch to it.")
253
253
  UI.message("")
254
- UI.message("\t\thttps://console.cloud.google.com/apis/credentials".cyan)
254
+ UI.message("\t\thttps://console.cloud.google.com/projectcreate".cyan)
255
255
  UI.message("")
256
- UI.input("Ensure the right project is selected on top of the page and confirm with enter")
256
+ UI.input("Press [Enter] once you selected the right project")
257
257
 
258
- UI.message("Now create a new JSON auth file by clicking on")
258
+ UI.message("Next fastlane will show you the steps to create a keys file.")
259
+ UI.message("For this it might be useful to switch the Google Cloud interface to English.")
260
+ UI.message("Append " + "&hl=en".cyan + " to the URL and the interface should be in English.")
261
+ UI.input("Press [Enter] to continue")
262
+
263
+ UI.message("Now it's time to generate a new JSON auth file for fastlane to access Google Cloud Storage:")
259
264
  UI.message("")
260
- UI.message("\t\t 1. Create credentials".cyan)
261
- UI.message("\t\t 2. Service account key".cyan)
262
- UI.message("\t\t 3. App Engine default service account".cyan)
263
- UI.message("\t\t 4. JSON".cyan)
264
- UI.message("\t\t 5. Create".cyan)
265
+ UI.message("\t\t 1. From the side menu choose 'APIs & Services' and then 'Credentials'".cyan)
266
+ UI.message("\t\t 2. Click 'Create credentials'".cyan)
267
+ UI.message("\t\t 3. Choose 'Service account key'".cyan)
268
+ UI.message("\t\t 4. Select 'New service account'".cyan)
269
+ UI.message("\t\t 5. Enter a name and ID for the service account".cyan)
270
+ UI.message("\t\t 6. Don't give the service account a role just yet!".cyan)
271
+ UI.message("\t\t 7. Make sure the key type is set to 'JSON'".cyan)
272
+ UI.message("\t\t 8. Click 'Create'".cyan)
265
273
  UI.message("")
266
- UI.input("Confirm with enter once you created and download the JSON file")
274
+ UI.input("Confirm with [Enter] once you created and downloaded the JSON file")
267
275
 
268
276
  UI.message("Copy the file to the current directory (#{Dir.pwd})")
269
277
  UI.message("and rename it to `#{DEFAULT_KEYS_FILE_NAME.cyan}`")
270
278
  UI.message("")
271
- UI.input("Confirm with enter")
279
+ UI.input("Confirm with [Enter]")
272
280
 
273
281
  until File.exist?(DEFAULT_KEYS_FILE_NAME)
274
282
  UI.message("Make sure to place the file in '#{Dir.pwd.cyan}' and name it '#{DEFAULT_KEYS_FILE_NAME.cyan}'")
275
- UI.input("Confirm with enter")
283
+ UI.message("")
284
+ UI.input("Confirm with [Enter]")
276
285
  end
277
286
 
278
287
  UI.important("Please never add the #{DEFAULT_KEYS_FILE_NAME.cyan} file in version control.")
279
- UI.important("Instead please add the file to your .gitignore")
280
- UI.input("Confirm with enter")
288
+ UI.important("Instead please add the file to your `.gitignore` file")
289
+ UI.message("")
290
+ UI.input("Confirm with [Enter]")
281
291
 
282
292
  return DEFAULT_KEYS_FILE_NAME
283
293
  end
284
294
 
285
295
  def ensure_bucket_is_selected
286
- # In case the user didn't provide a bucket name yet, they will
287
- # be asked to provide one here
296
+ created_bucket = UI.confirm("Did you already create a Google Cloud Storage bucket?")
288
297
  while self.bucket_name.to_s.length == 0
289
- # Have a nice selection of the available buckets here
290
- # This can only happen after we went through auth of Google Cloud
291
- available_bucket_identifiers = self.gc_storage.buckets.collect(&:id)
292
- if available_bucket_identifiers.count > 0
293
- @bucket_name = UI.select("What Google Cloud Storage bucket do you want to use? (you can define it using the `google_cloud_bucket_name` key)", available_bucket_identifiers)
294
- else
295
- UI.error("Looks like your Google Cloud account for the project ID '#{self.google_cloud_project_id}' doesn't")
296
- UI.error("have any available storage buckets yet. Please visit the following URL")
298
+ unless created_bucket
299
+ UI.message("Create a bucket at the following URL:")
297
300
  UI.message("")
298
301
  UI.message("\t\thttps://console.cloud.google.com/storage/browser".cyan)
299
302
  UI.message("")
300
- UI.message("and make sure to have the right project selected on top of the page")
301
- UI.message("click on " + "Create Bucket".cyan + ", choose a name and confirm")
303
+ UI.message("Make sure to select the right project at the top of the page!")
304
+ UI.message("")
305
+ UI.message("\t\t 1. Click 'Create bucket'".cyan)
306
+ UI.message("\t\t 2. Enter a unique name".cyan)
307
+ UI.message("\t\t 3. Select a geographic location for your bucket".cyan)
308
+ UI.message("\t\t 4. Make sure the storage class is set to 'Standard'".cyan)
309
+ UI.message("\t\t 5. Click 'Create' to create the bucket".cyan)
302
310
  UI.message("")
303
- UI.input("Once you're finished, please confirm with enter")
311
+ UI.input("Press [Enter] once you created a bucket")
312
+ end
313
+ bucket_name = UI.input("Enter the name of your bucket: ")
314
+
315
+ # Verify if the bucket exists
316
+ begin
317
+ bucket_exists = !self.gc_storage.bucket(bucket_name).nil?
318
+ rescue Google::Cloud::PermissionDeniedError
319
+ bucket_exists = true
320
+ end
321
+ created_bucket = bucket_exists
322
+ if bucket_exists
323
+ @bucket_name = bucket_name
324
+ else
325
+ UI.error("It looks like the bucket '#{bucket_name}' doesn't exist. Make sure to create it first.")
326
+ end
327
+ end
328
+ end
329
+
330
+ def check_bucket_permissions
331
+ bucket = nil
332
+ while bucket.nil?
333
+ begin
334
+ bucket = self.gc_storage.bucket(self.bucket_name)
335
+ rescue Google::Cloud::PermissionDeniedError
336
+ bucket = nil
304
337
  end
338
+ return if bucket.nil? == false
339
+ UI.error("Looks like your Google Cloud account for the project ID '#{self.google_cloud_project_id}' doesn't")
340
+ UI.error("have access to the storage bucket '#{self.bucket_name}'. Please visit the following URL:")
341
+ UI.message("")
342
+ UI.message("\t\thttps://console.cloud.google.com/storage/browser".cyan)
343
+ UI.message("")
344
+ UI.message("You need to give your account the correct permissions:")
345
+ UI.message("")
346
+ UI.message("\t\t 1. Click on your bucket to open it".cyan)
347
+ UI.message("\t\t 2. Click 'Permissions'".cyan)
348
+ UI.message("\t\t 3. Click 'Add members'".cyan)
349
+ UI.message("\t\t 4. Enter the email of your service account".cyan)
350
+ UI.message("\t\t 5. Set the role to 'Storage Admin'".cyan)
351
+ UI.message("\t\t 6. Click 'Save'".cyan)
352
+ UI.message("")
353
+ UI.input("Confirm with [Enter] once you're finished")
305
354
  end
306
355
  end
307
356
  end
@@ -229,7 +229,13 @@ module Produce
229
229
  UI.message("\tPush Notifications")
230
230
 
231
231
  if on
232
- app.update_service(Spaceship.app_service.push_notification.on)
232
+ # Don't enable push notifications if already enabled
233
+ # Enabling push notifications when already on revokes certs
234
+ # https://github.com/fastlane/fastlane/issues/15315
235
+ # https://github.com/fastlane/fastlane/issues/8883
236
+ unless app.details.enable_services.include?("push")
237
+ app.update_service(Spaceship.app_service.push_notification.on)
238
+ end
233
239
  else
234
240
  app.update_service(Spaceship.app_service.push_notification.off)
235
241
  end
@@ -192,6 +192,9 @@ module Spaceship
192
192
  # @return (Hash) Represents the trailers of this app version (read-only)
193
193
  attr_reader :trailers
194
194
 
195
+ # @return (Hash) A hash representing all in-app purchases that can get submitted with this version
196
+ attr_reader :in_app_purchases
197
+
195
198
  # @return (Hash) Represents the phased_release hash (read-only)
196
199
  # For now, please use the `toggle_phased_release` method and call `.save!`
197
200
  # as the API will probably change in the future
@@ -233,6 +236,7 @@ module Spaceship
233
236
  'supportsAppleWatch' => :supports_apple_watch,
234
237
  'versionId' => :version_id,
235
238
  'version.value' => :version,
239
+ 'submittableAddOns.value' => :in_app_purchases,
236
240
  'phasedRelease' => :phased_release,
237
241
 
238
242
  # GeoJson
@@ -9,12 +9,20 @@ module Spaceship
9
9
  # @return (String) the family name
10
10
  attr_accessor :name
11
11
 
12
- # @return (Intger) the Family Id
12
+ # @return (Intger) the family id
13
13
  attr_accessor :family_id
14
14
 
15
+ # @return (Array) all linked in-app purchases of this family
16
+ attr_accessor :linked_iaps
17
+
18
+ # @return (Intger) amount of linked in-app purchases of this family (read-only)
19
+ attr_accessor :iap_count
20
+
15
21
  attr_mapping({
16
22
  'id' => :family_id,
17
- 'name.value' => :name
23
+ 'name.value' => :name,
24
+ 'activeAddOns' => :linked_iaps,
25
+ 'totalActiveAddOns' => :iap_count
18
26
  })
19
27
 
20
28
  def versions=(value = {})
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.132.0.beta.20190920200012
4
+ version: 2.132.0.beta.20190925200108
5
5
  platform: ruby
6
6
  authors:
7
7
  - Andrew McBurney
@@ -27,7 +27,7 @@ authors:
27
27
  autorequire:
28
28
  bindir: bin
29
29
  cert_chain: []
30
- date: 2019-09-20 00:00:00.000000000 Z
30
+ date: 2019-09-25 00:00:00.000000000 Z
31
31
  dependencies:
32
32
  - !ruby/object:Gem::Dependency
33
33
  name: slack-notifier
@@ -1060,6 +1060,7 @@ files:
1060
1060
  - fastlane/lib/fastlane/actions/dsym_zip.rb
1061
1061
  - fastlane/lib/fastlane/actions/echo.rb
1062
1062
  - fastlane/lib/fastlane/actions/ensure_bundle_exec.rb
1063
+ - fastlane/lib/fastlane/actions/ensure_env_vars.rb
1063
1064
  - fastlane/lib/fastlane/actions/ensure_git_branch.rb
1064
1065
  - fastlane/lib/fastlane/actions/ensure_git_status_clean.rb
1065
1066
  - fastlane/lib/fastlane/actions/ensure_no_debug_code.rb
@@ -1746,24 +1747,24 @@ metadata:
1746
1747
  post_install_message:
1747
1748
  rdoc_options: []
1748
1749
  require_paths:
1749
- - frameit/lib
1750
- - sigh/lib
1751
- - spaceship/lib
1750
+ - precheck/lib
1752
1751
  - snapshot/lib
1753
- - scan/lib
1754
1752
  - screengrab/lib
1753
+ - fastlane/lib
1754
+ - frameit/lib
1755
+ - scan/lib
1755
1756
  - pilot/lib
1757
+ - cert/lib
1758
+ - gym/lib
1756
1759
  - pem/lib
1760
+ - spaceship/lib
1757
1761
  - fastlane_core/lib
1758
- - gym/lib
1762
+ - match/lib
1759
1763
  - credentials_manager/lib
1760
- - precheck/lib
1761
- - fastlane/lib
1762
- - cert/lib
1763
1764
  - deliver/lib
1764
1765
  - produce/lib
1766
+ - sigh/lib
1765
1767
  - supply/lib
1766
- - match/lib
1767
1768
  required_ruby_version: !ruby/object:Gem::Requirement
1768
1769
  requirements:
1769
1770
  - - ">="