fastlane-plugin-appcenter 1.7.0 → 1.11.0

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 CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: 0cf08880b9ba588e79b23dd385311f4d5a194246
4
- data.tar.gz: fe26549362f32bbd22293bc8110e432a7a94118a
2
+ SHA256:
3
+ metadata.gz: 1c1262b958ae0ddbf9a6bfa6d63b4f032f1518c706154e6c70b35adbe2c441e2
4
+ data.tar.gz: c2ffa81d7a6e4c8fb369c5d4612a0aea7c02c2cd589a3fdcb900d8b407f2eaae
5
5
  SHA512:
6
- metadata.gz: 6ffd559816032b4c385ead27b89419541746a106e63713aeef51282d1a74950dd27eaff4d1daf59db58ccfd33a3d4efa9f3a1f9ffbefc836ed82af2d7579dcf4
7
- data.tar.gz: 80b0cb6d8016fa35400e0ae7c1e7d1dfd9ac2e07cc3b6a96decb26917bf6c5988ab9a7f2fb407e4ee96e8303cd716dd6fc020785f6a2aa06f8167681f7d18e6f
6
+ metadata.gz: eb06867a95f13d484796bd47be5cad11df03e949ffffbcbf8cbe14d675c8577506e184176248ba8102fc338ab934e9d03e06938030591d9d9a72beec557f7894
7
+ data.tar.gz: b1fadb157505f3138621dffd8e95a64d306f89439ab25259c60c6a9e08d9a9dbe97d0b09b4c1daf8db70e2c9241d87225523784cb3f9c5e900c98d3a85b0b05f
data/README.md CHANGED
@@ -21,6 +21,8 @@ With [App Center](https://appcenter.ms) you can continuously build, test, releas
21
21
 
22
22
  `appcenter_upload` allows you to upload and [distribute](https://docs.microsoft.com/en-us/appcenter/distribution/uploading) apps to your testers on App Center as well as to upload .dSYM files to [collect detailed crash reports](https://docs.microsoft.com/en-us/appcenter/crashes/ios) in App Center.
23
23
 
24
+ `appcenter_fetch_version_number` allows you to obtain the latest version number (short or full) for an app. This is useful for tasks such as getting the latest version of an app so that an increment action can take place on CI, or checking that an upload has been successful.
25
+
24
26
  ## Usage
25
27
 
26
28
  To get started, first, [obtain an API token](https://appcenter.ms/settings/apitokens) in App Center. The API Token is used to authenticate with the App Center API in each call.
@@ -29,7 +31,6 @@ To get started, first, [obtain an API token](https://appcenter.ms/settings/apito
29
31
  appcenter_fetch_devices(
30
32
  api_token: "<appcenter token>",
31
33
  owner_name: "<appcenter account name of the owner of the app (username or organization URL name)>",
32
- owner_type: "user", # Default is user - set to organization for appcenter organizations
33
34
  app_name: "<appcenter app name>",
34
35
  destinations: "*", # Default is 'Collaborators', use '*' for all distribution groups
35
36
  devices_file: "devices.txt" # Default. If you customize, the extension must be .txt
@@ -47,6 +48,21 @@ appcenter_upload(
47
48
  )
48
49
  ```
49
50
 
51
+ ```ruby
52
+ appcenter_fetch_version_number(
53
+ api_token: "<appcenter token>",
54
+ owner_name: "<appcenter account name of the owner of the app (username or organization URL name)>",
55
+ app_name: "<appcenter app name (as seen in app URL)>",
56
+ version: "a specific version to get the last release for" # optional, don't set this value to get the last upload of all versions
57
+ )
58
+ ```
59
+
60
+ The `appcenter_fetch_version_number` returns a hash that contains the id, the version number, and the build number. The version corresponds to the `short_version` and the build number to the `version` known by App Center for a given release:
61
+ ```ruby
62
+ {"id"=>1, "version"=>"1.0.0", "build_number"=>"1.0.0.1234"} # iOS apps contain the full version plus build number due to the way that Apple use CFBundleVersion for this value
63
+ {"id"=>588, "version"=>"1.2.0", "build_number"=>"1615"}
64
+ ```
65
+
50
66
  ### Help
51
67
 
52
68
  Once installed, information and help for an action can be printed out with this command:
@@ -74,7 +90,6 @@ Here is the list of all existing parameters:
74
90
  | Key & Env Var | Description |
75
91
  |-----------------|--------------------|
76
92
  | `api_token` <br/> `APPCENTER_API_TOKEN` | API Token for App Center |
77
- | `owner_type` <br/> `APPCENTER_OWNER_TYPE` | Owner type, either 'user' or 'organization' (default: `user`) |
78
93
  | `owner_name` <br/> `APPCENTER_OWNER_NAME` | Owner name, as found in the App's URL in App Center |
79
94
  | `destinations` <br/> `APPCENTER_DISTRIBUTE_DESTINATIONS` | Comma separated list of distribution group names. Default is 'Collaborators', use '*' for all distribution groups |
80
95
  | `devices_file` <br/> `FL_REGISTER_DEVICES_FILE` | File to save the devices list to. Same environment variable as _fastlane_'s `register_devices` action |
@@ -88,7 +103,7 @@ Here is the list of all existing parameters:
88
103
  | `owner_name` <br/> `APPCENTER_OWNER_NAME` | Owner name as found in the App's URL in App Center |
89
104
  | `app_name` <br/> `APPCENTER_APP_NAME` | App name as found in the App's URL in App Center. If there is no app with such name, you will be prompted to create one |
90
105
  | `app_display_name` <br/> `APPCENTER_APP_DISPLAY_NAME` | App display name to use when creating a new app |
91
- | `app_os` <br/> `APPCENTER_APP_OS` | App OS. Used for new app creation, if app 'app_name' was not found |
106
+ | `app_os` <br/> `APPCENTER_APP_OS` | App OS can be Android, iOS, macOS, Windows, Custom. Used for new app creation, if app 'app_name' was not found |
92
107
  | `app_platform` <br/> `APPCENTER_APP_PLATFORM` | App Platform. Used for new app creation, if app 'app_name' was not found |
93
108
  | `file` <br/> `APPCENTER_DISTRIBUTE_FILE` | File path to the release build to publish |
94
109
  | `upload_build_only` <br/> `APPCENTER_DISTRIBUTE_UPLOAD_BUILD_ONLY` | Flag to upload only the build to App Center. Skips uploading symbols or mapping (default: `false`) |
@@ -96,7 +111,7 @@ Here is the list of all existing parameters:
96
111
  | `upload_dsym_only` <br/> `APPCENTER_DISTRIBUTE_UPLOAD_DSYM_ONLY` | Flag to upload only the dSYM file to App Center (default: `false`) |
97
112
  | `mapping` <br/> `APPCENTER_DISTRIBUTE_ANDROID_MAPPING` | Path to your Android mapping.txt |
98
113
  | `upload_mapping_only` <br/> `APPCENTER_DISTRIBUTE_UPLOAD_ANDROID_MAPPING_ONLY` | Flag to upload only the mapping.txt file to App Center (default: `false`) |
99
- | `destinations` <br/> `APPCENTER_DISTRIBUTE_DESTINATIONS` | Comma separated list of destination names. Both distribution groups and stores are supported. All names are required to be of the same destination type (default: `Collaborators`) |
114
+ | `destinations` <br/> `APPCENTER_DISTRIBUTE_DESTINATIONS` | Comma separated list of destination names, use '*' for all distribution groups if destination type is 'group'. Both distribution groups and stores are supported. All names are required to be of the same destination type (default: `Collaborators`) |
100
115
  | `destination_type` <br/> `APPCENTER_DISTRIBUTE_DESTINATION_TYPE` | Destination type of distribution destination. 'group' and 'store' are supported (default: `group`) |
101
116
  | `mandatory_update` <br/> `APPCENTER_DISTRIBUTE_MANDATORY_UPDATE` | Require users to update to this release. Ignored if destination type is 'store' (default: `false`) |
102
117
  | `notify_testers` <br/> `APPCENTER_DISTRIBUTE_NOTIFY_TESTERS` | Send email notification about release. Ignored if destination type is 'store' (default: `false`) |
@@ -105,10 +120,19 @@ Here is the list of all existing parameters:
105
120
  | `release_notes_link` <br/> `APPCENTER_DISTRIBUTE_RELEASE_NOTES_LINK` | Additional release notes link |
106
121
  | `build_number` <br/> `APPCENTER_DISTRIBUTE_BUILD_NUMBER` | The build number, required for macOS .pkg and .dmg builds, as well as Android ProGuard `mapping.txt` when using `upload_mapping_only` |
107
122
  | `version` <br/> `APPCENTER_DISTRIBUTE_VERSION` | The build version, required for .pkg, .dmg, .zip and .msi builds, as well as Android ProGuard `mapping.txt` when using `upload_mapping_only` |
108
- | `timeout` <br/> `APPCENTER_DISTRIBUTE_TIMEOUT` | Request timeout in seconds |
123
+ | `timeout` <br/> `APPCENTER_DISTRIBUTE_TIMEOUT` | Request timeout in seconds applied to individual HTTP requests. Some commands use multiple HTTP requests, large file uploads are also split in multiple HTTP requests |
109
124
  | `dsa_signature` <br/> `APPCENTER_DISTRIBUTE_DSA_SIGNATURE` | DSA signature of the macOS or Windows release for Sparkle update feed |
125
+ | `ed_signature` <br/> `APPCENTER_DISTRIBUTE_ED_SIGNATURE` | EdDSA signature of the macOS or Windows release for Sparkle update feed |
110
126
  | `strict` <br/> `APPCENTER_STRICT_MODE` | Strict mode, set to 'true' to fail early in case a potential error was detected |
111
127
 
128
+ #### `appcenter_fetch_version_number`
129
+
130
+ | Key & Env Var | Description |
131
+ |-----------------|--------------------|
132
+ | `api_token` <br/> `APPCENTER_API_TOKEN` | API Token for App Center |
133
+ | `owner_name` <br/> `APPCENTER_OWNER_NAME` | Owner name, as found in the App's URL in App Center |
134
+ | `app_name` <br/> `APPCENTER_APP_NAME` | App name as found in the App's URL in App Center. If there is no app with such name, you will be prompted to create one |
135
+ | `version` <br/> `APPCENTER_APP_VERSION` | App version to get the last release for instead of the last release of all versions |
112
136
 
113
137
  ## Example
114
138
 
@@ -162,4 +186,4 @@ Check out [SECURITY.md](SECURITY.md) for any security concern with this project.
162
186
 
163
187
  ## Contact
164
188
 
165
- We're on Twitter as [@vsappcenter](https://www.twitter.com/vsappcenter). Additionally you can reach out to us on the [App Center](https://appcenter.ms/apps) portal by using the blue Intercom button on the bottom right to start a conversation.
189
+ We're on Twitter as [@vsappcenter](https://www.twitter.com/vsappcenter). Additionally you can reach out to us on the [App Center](https://appcenter.ms/apps) portal. Open the "?" menu on the top right corner of screen, then use "Contact support" to file a support ticket. Our support team is there to answer your questions and help you solve your problems.
@@ -0,0 +1,103 @@
1
+ require "json"
2
+ require "net/http"
3
+ require "fastlane_core/ui/ui"
4
+
5
+ module Fastlane
6
+ UI = FastlaneCore::UI unless Fastlane.const_defined?("UI")
7
+
8
+ module Actions
9
+ class AppcenterFetchVersionNumberAction < Action
10
+ def self.description
11
+ "Fetches the latest version number of an app or the last build number of a version from App Center"
12
+ end
13
+
14
+ def self.authors
15
+ ["jspargo", "ShopKeep", "Qutaibah"]
16
+ end
17
+
18
+ def self.run(params)
19
+ api_token = params[:api_token]
20
+ app_name = params[:app_name]
21
+ owner_name = params[:owner_name]
22
+ version = params[:version]
23
+
24
+ releases = Helper::AppcenterHelper.fetch_releases(
25
+ api_token: api_token,
26
+ owner_name: owner_name,
27
+ app_name: app_name,
28
+ )
29
+
30
+ UI.abort_with_message!("No versions found for '#{app_name}' owned by #{owner_name}") unless releases
31
+
32
+ sorted_releases = releases
33
+
34
+ if version.nil?
35
+ sorted_releases = releases.sort_by { |release| release["id"] }
36
+ else
37
+ sorted_releases = releases.select { |release| release["short_version"] == version }.sort_by { |release| release["id"] }
38
+ end
39
+
40
+ latest_release = sorted_releases.last
41
+
42
+ if latest_release.nil?
43
+ if version.nil?
44
+ UI.user_error!("This app has no releases yet")
45
+ return nil
46
+ end
47
+ UI.user_error!("The provided version (#{version}) has no releases yet")
48
+ return nil
49
+ end
50
+
51
+ return {
52
+ "id" => latest_release["id"],
53
+ "version" => latest_release["short_version"],
54
+ "build_number" => latest_release["version"],
55
+ }
56
+ end
57
+
58
+ def self.available_options
59
+ [
60
+ FastlaneCore::ConfigItem.new(key: :api_token,
61
+ env_name: "APPCENTER_API_TOKEN",
62
+ description: "API Token for App Center Access",
63
+ verify_block: proc do |value|
64
+ UI.user_error!("No API token for App Center given, pass using `api_token: 'token'`") unless value && !value.empty?
65
+ end),
66
+ FastlaneCore::ConfigItem.new(key: :owner_name,
67
+ env_name: "APPCENTER_OWNER_NAME",
68
+ description: "Name of the owner of the application on App Center",
69
+ verify_block: proc do |value|
70
+ UI.user_error!("No owner name for App Center given, pass using `owner_name: 'owner name'`") unless value && !value.empty?
71
+ end),
72
+ FastlaneCore::ConfigItem.new(key: :app_name,
73
+ env_name: "APPCENTER_APP_NAME",
74
+ description: "Name of the application on App Center",
75
+ verify_block: proc do |value|
76
+ UI.user_error!("No app name for App Center given, pass using `app_name: 'app name'`") unless value && !value.empty?
77
+ end),
78
+ FastlaneCore::ConfigItem.new(key: :version,
79
+ env_name: "APPCENTER_APP_VERSION",
80
+ description: "The version to get the latest release for",
81
+ optional: true,
82
+ type: String),
83
+
84
+ ]
85
+ end
86
+
87
+ def self.is_supported?(platform)
88
+ [:ios, :android].include?(platform)
89
+ end
90
+
91
+ def self.get_apps(api_token)
92
+ host_uri = URI.parse("https://api.appcenter.ms")
93
+ http = Net::HTTP.new(host_uri.host, host_uri.port)
94
+ http.use_ssl = true
95
+ apps_request = Net::HTTP::Get.new("/v0.1/apps")
96
+ apps_request["X-API-Token"] = api_token
97
+ apps_response = http.request(apps_request)
98
+ return [] unless apps_response.kind_of?(Net::HTTPOK)
99
+ return JSON.parse(apps_response.body)
100
+ end
101
+ end
102
+ end
103
+ end
@@ -9,6 +9,23 @@ module Fastlane
9
9
  windows: %w(.appx .appxbundle .appxupload .msix .msixbundle .msixupload .zip .msi),
10
10
  custom: %w(.zip)
11
11
  }
12
+ CONTENT_TYPES = {
13
+ apk: "application/vnd.android.package-archive",
14
+ aab: "application/vnd.android.package-archive",
15
+ msi: "application/x-msi",
16
+ plist: "application/xml",
17
+ aetx: "application/c-x509-ca-cert",
18
+ cer: "application/pkix-cert",
19
+ xap: "application/x-silverlight-app",
20
+ appx: "application/x-appx",
21
+ appxbundle: "application/x-appxbundle",
22
+ appxupload: "application/x-appxupload",
23
+ appxsym: "application/x-appxupload",
24
+ msix: "application/x-msix",
25
+ msixbundle: "application/x-msixbundle",
26
+ msixupload: "application/x-msixupload",
27
+ msixsym: "application/x-msixupload",
28
+ }
12
29
  ALL_SUPPORTED_EXTENSIONS = SUPPORTED_EXTENSIONS.values.flatten.sort!.uniq!
13
30
  STORE_ONLY_EXTENSIONS = %w(.aab)
14
31
  STORE_SUPPORTED_EXTENSIONS = %w(.aab .apk .ipa)
@@ -22,6 +39,13 @@ module Fastlane
22
39
  end
23
40
 
24
41
  class AppcenterUploadAction < Action
42
+ def self.is_apple_build(file)
43
+ return false unless file
44
+
45
+ file_ext = Helper::AppcenterHelper.file_extname_full(file)
46
+ ((Constants::SUPPORTED_EXTENSIONS[:ios] + Constants::SUPPORTED_EXTENSIONS[:mac])).include? file_ext
47
+ end
48
+
25
49
  # run whole upload process for dSYM files
26
50
  def self.run_dsym_upload(params)
27
51
  values = params.values
@@ -35,8 +59,9 @@ module Fastlane
35
59
 
36
60
  dsym_path = nil
37
61
  if dsym
38
- # we can use dsym parameter only if build file is ipa
39
- dsym_path = dsym if !file || File.extname(file) == '.ipa'
62
+ # we can use dsym parameter for all apple builds
63
+ self.optional_error("dsym parameter can only be used with Apple builds (ios, mac)") unless !file || self.is_apple_build(file)
64
+ dsym_path = dsym
40
65
  else
41
66
  # if dsym is not set, but build is ipa - check default path
42
67
  if file && File.exist?(file) && File.extname(file) == '.ipa'
@@ -118,6 +143,7 @@ module Fastlane
118
143
  build_number = params[:build_number]
119
144
  version = params[:version]
120
145
  dsa_signature = params[:dsa_signature]
146
+ ed_signature = params[:ed_signature]
121
147
 
122
148
  if release_notes.length >= Constants::MAX_RELEASE_NOTES_LENGTH
123
149
  unless should_clip
@@ -145,6 +171,7 @@ module Fastlane
145
171
  self.optional_error("Can't distribute #{file_ext} to groups, please use `destination_type: 'store'`") if Constants::STORE_ONLY_EXTENSIONS.include? file_ext
146
172
  else
147
173
  self.optional_error("Can't distribute #{file_ext} to stores, please use `destination_type: 'group'`") unless Constants::STORE_SUPPORTED_EXTENSIONS.include? file_ext
174
+ UI.user_error!("The combination of `destinations: '*'` and `destination_type: 'store'` is invalid, please use `destination_type: 'group'` or explicitly specify the destinations") if destinations == "*"
148
175
  end
149
176
 
150
177
  release_upload_body = nil
@@ -171,27 +198,57 @@ module Fastlane
171
198
  File.delete zip_file
172
199
  end
173
200
  UI.message("Creating zip archive: #{zip_file}")
174
- file = Actions::ZipAction.run(path: file, output_path: zip_file)
201
+ file = Actions::ZipAction.run(path: file, output_path: zip_file, symlinks: true)
175
202
  end
176
203
 
177
204
  UI.message("Starting release upload...")
178
205
  upload_details = Helper::AppcenterHelper.create_release_upload(api_token, owner_name, app_name, release_upload_body)
179
206
  if upload_details
180
- upload_id = upload_details['upload_id']
181
- upload_url = upload_details['upload_url']
207
+ upload_id = upload_details['id']
208
+
209
+ UI.message("Setting Metadata...")
210
+ content_type = Constants::CONTENT_TYPES[File.extname(file)&.delete('.').downcase.to_sym] || "application/octet-stream"
211
+ set_metadata_url = "#{upload_details['upload_domain']}/upload/set_metadata/#{upload_details['package_asset_id']}?file_name=#{File.basename(file)}&file_size=#{File.size(file)}&token=#{upload_details['url_encoded_token']}&content_type=#{content_type}"
212
+ chunk_size = Helper::AppcenterHelper.set_release_upload_metadata(set_metadata_url, api_token, owner_name, app_name, upload_id, timeout)
213
+ UI.abort_with_message!("Upload aborted") unless chunk_size
182
214
 
183
215
  UI.message("Uploading release binary...")
184
- uploaded = Helper::AppcenterHelper.upload_build(api_token, owner_name, app_name, file, upload_id, upload_url, timeout)
216
+ upload_url = "#{upload_details['upload_domain']}/upload/upload_chunk/#{upload_details['package_asset_id']}?token=#{upload_details['url_encoded_token']}"
217
+ uploaded = Helper::AppcenterHelper.upload_build(api_token, owner_name, app_name, file, upload_id, upload_url, content_type, chunk_size, timeout)
218
+ UI.abort_with_message!("Upload aborted") unless uploaded
219
+
220
+ UI.message("Finishing release...")
221
+ finish_url = "#{upload_details['upload_domain']}/upload/finished/#{upload_details['package_asset_id']}?token=#{upload_details['url_encoded_token']}"
222
+ finished = Helper::AppcenterHelper.finish_release_upload(finish_url, api_token, owner_name, app_name, upload_id, timeout)
223
+ UI.abort_with_message!("Upload aborted") unless finished
224
+
225
+ UI.message("Waiting for release to be ready...")
226
+ release_status_url = "v0.1/apps/#{owner_name}/#{app_name}/uploads/releases/#{upload_id}"
227
+ release_id = Helper::AppcenterHelper.poll_for_release_id(api_token, release_status_url)
185
228
 
186
- if uploaded
187
- release_id = uploaded['release_id']
229
+ if release_id.is_a? Integer
188
230
  release_url = Helper::AppcenterHelper.get_release_url(owner_type, owner_name, app_name, release_id)
189
231
  UI.message("Release '#{release_id}' committed: #{release_url}")
190
232
 
191
233
  release = Helper::AppcenterHelper.update_release(api_token, owner_name, app_name, release_id, release_notes)
192
- Helper::AppcenterHelper.update_release_metadata(api_token, owner_name, app_name, release_id, dsa_signature)
193
-
194
- destinations_array = destinations.split(',')
234
+ Helper::AppcenterHelper.update_release_metadata(api_token, owner_name, app_name, release_id, dsa_signature, ed_signature)
235
+
236
+ destinations_array = []
237
+ if destinations == '*'
238
+ UI.message("Looking up all distribution groups for #{owner_name}/#{app_name}")
239
+ distribution_groups = Helper::AppcenterHelper.fetch_distribution_groups(
240
+ api_token: api_token,
241
+ owner_name: owner_name,
242
+ app_name: app_name
243
+ )
244
+
245
+ UI.abort_with_message!("Failed to list distribution groups for #{owner_name}/#{app_name}") unless distribution_groups
246
+
247
+ destinations_array = distribution_groups.map {|h| h['name'] }
248
+ else
249
+ destinations_array = destinations.split(',').map(&:strip)
250
+ end
251
+
195
252
  destinations_array.each do |destination_name|
196
253
  destination = Helper::AppcenterHelper.get_destination(api_token, owner_name, app_name, destination_type, destination_name)
197
254
  if destination
@@ -228,10 +285,11 @@ module Fastlane
228
285
  app_platform = params[:app_platform]
229
286
 
230
287
  platforms = {
231
- Android: %w[Java React-Native Xamarin],
232
- iOS: %w[Objective-C-Swift React-Native Xamarin],
288
+ Android: %w[Java React-Native Xamarin Unity],
289
+ iOS: %w[Objective-C-Swift React-Native Xamarin Unity],
233
290
  macOS: %w[Objective-C-Swift],
234
- Windows: %w[UWP WPF WinForms Unity]
291
+ Windows: %w[UWP WPF WinForms Unity],
292
+ Custom: %w[Custom]
235
293
  }
236
294
 
237
295
  begin
@@ -260,6 +318,30 @@ module Fastlane
260
318
  end
261
319
  end
262
320
 
321
+ def self.add_app_to_distribution_group_if_needed(params)
322
+ return unless params[:destination_type] == 'group' && params[:owner_type] == 'organization' && params[:destinations] != '*'
323
+
324
+ app_distribution_groups = Helper::AppcenterHelper.fetch_distribution_groups(
325
+ api_token: params[:api_token],
326
+ owner_name: params[:owner_name],
327
+ app_name: params[:app_name]
328
+ )
329
+
330
+ group_names = app_distribution_groups.map { |g| g['name'] }
331
+ destination_names = params[:destinations].split(',').map(&:strip)
332
+
333
+ destination_names.each do |destination_name|
334
+ unless group_names.include? destination_name
335
+ Helper::AppcenterHelper.add_new_app_to_distribution_group(
336
+ api_token: params[:api_token],
337
+ owner_name: params[:owner_name],
338
+ app_name: params[:app_name],
339
+ destination_name: destination_name
340
+ )
341
+ end
342
+ end
343
+ end
344
+
263
345
  def self.run(params)
264
346
  values = params.values
265
347
  upload_build_only = params[:upload_build_only]
@@ -270,10 +352,10 @@ module Fastlane
270
352
 
271
353
  # if app found or successfully created
272
354
  if self.get_or_create_app(params)
355
+ self.add_app_to_distribution_group_if_needed(params)
273
356
  release = self.run_release_upload(params) unless upload_dsym_only || upload_mapping_only
274
357
  params[:version] = release['short_version'] if release
275
358
  params[:build_number] = release['version'] if release
276
-
277
359
  self.run_dsym_upload(params) unless upload_mapping_only || upload_build_only
278
360
  self.run_mapping_upload(params) unless upload_dsym_only || upload_build_only
279
361
  end
@@ -344,7 +426,7 @@ module Fastlane
344
426
 
345
427
  FastlaneCore::ConfigItem.new(key: :app_os,
346
428
  env_name: "APPCENTER_APP_OS",
347
- description: "App OS. Used for new app creation, if app 'app_name' was not found",
429
+ description: "App OS can be Android, iOS, macOS, Windows, Custom. Used for new app creation, if app 'app_name' was not found",
348
430
  optional: true,
349
431
  type: String),
350
432
 
@@ -424,7 +506,7 @@ module Fastlane
424
506
  self.optional_error("Extension not supported: '#{file_ext}'. Supported formats for platform '#{platform}': #{accepted_formats.join ' '}") unless accepted_formats.include? file_ext
425
507
  end
426
508
  end),
427
-
509
+
428
510
  FastlaneCore::ConfigItem.new(key: :upload_build_only,
429
511
  env_name: "APPCENTER_DISTRIBUTE_UPLOAD_BUILD_ONLY",
430
512
  description: "Flag to upload only the build to App Center. Skips uploading symbols or mapping",
@@ -460,6 +542,7 @@ module Fastlane
460
542
  FastlaneCore::ConfigItem.new(key: :mapping,
461
543
  env_name: "APPCENTER_DISTRIBUTE_ANDROID_MAPPING",
462
544
  description: "Path to your Android mapping.txt",
545
+ default_value: (defined? SharedValues::GRADLE_MAPPING_TXT_OUTPUT_PATH) && Actions.lane_context[SharedValues::GRADLE_MAPPING_TXT_OUTPUT_PATH] || nil,
463
546
  optional: true,
464
547
  type: String,
465
548
  verify_block: proc do |value|
@@ -489,12 +572,11 @@ module Fastlane
489
572
 
490
573
  FastlaneCore::ConfigItem.new(key: :destinations,
491
574
  env_name: "APPCENTER_DISTRIBUTE_DESTINATIONS",
492
- description: "Comma separated list of destination names. Both distribution groups and stores are supported. All names are required to be of the same destination type",
575
+ description: "Comma separated list of destination names, use '*' for all distribution groups if destination type is 'group'. Both distribution groups and stores are supported. All names are required to be of the same destination type",
493
576
  default_value: Actions.lane_context[SharedValues::APPCENTER_DISTRIBUTE_DESTINATIONS] || "Collaborators",
494
577
  optional: true,
495
578
  type: String),
496
579
 
497
-
498
580
  FastlaneCore::ConfigItem.new(key: :destination_type,
499
581
  env_name: "APPCENTER_DISTRIBUTE_DESTINATION_TYPE",
500
582
  description: "Destination type of distribution destination. 'group' and 'store' are supported",
@@ -553,7 +635,7 @@ module Fastlane
553
635
 
554
636
  FastlaneCore::ConfigItem.new(key: :timeout,
555
637
  env_name: "APPCENTER_DISTRIBUTE_TIMEOUT",
556
- description: "Request timeout in seconds",
638
+ description: "Request timeout in seconds applied to individual HTTP requests. Some commands use multiple HTTP requests, large file uploads are also split in multiple HTTP requests",
557
639
  optional: true,
558
640
  type: Integer),
559
641
 
@@ -562,7 +644,13 @@ module Fastlane
562
644
  description: "DSA signature of the macOS or Windows release for Sparkle update feed",
563
645
  optional: true,
564
646
  type: String),
565
-
647
+
648
+ FastlaneCore::ConfigItem.new(key: :ed_signature,
649
+ env_name: "APPCENTER_DISTRIBUTE_ED_SIGNATURE",
650
+ description: "EdDSA signature of the macOS or Windows release for Sparkle update feed",
651
+ optional: true,
652
+ type: String),
653
+
566
654
  FastlaneCore::ConfigItem.new(key: :strict,
567
655
  env_name: "APPCENTER_STRICT_MODE",
568
656
  description: "Strict mode, set to 'true' to fail early in case a potential error was detected",
@@ -608,6 +696,16 @@ module Fastlane
608
696
  release_notes: "release notes",
609
697
  notify_testers: false
610
698
  )',
699
+ 'appcenter_upload(
700
+ api_token: "...",
701
+ owner_name: "appcenter_owner",
702
+ app_name: "testing_ios_app",
703
+ file: "./app-release.ipa",
704
+ destinations: "*",
705
+ destination_type: "group",
706
+ release_notes: "release notes",
707
+ notify_testers: false
708
+ )',
611
709
  'appcenter_upload(
612
710
  api_token: "...",
613
711
  owner_name: "appcenter_owner",