fastlane 2.206.2 → 2.207.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (53) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +94 -94
  3. data/deliver/lib/deliver/runner.rb +31 -35
  4. data/deliver/lib/deliver/upload_price_tier.rb +3 -1
  5. data/deliver/lib/deliver/upload_screenshots.rb +1 -1
  6. data/fastlane/lib/fastlane/actions/update_info_plist.rb +1 -1
  7. data/fastlane/lib/fastlane/actions/upload_symbols_to_sentry.rb +1 -1
  8. data/fastlane/lib/fastlane/actions/xcodebuild.rb +8 -2
  9. data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +1 -1
  10. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +5 -1
  11. data/fastlane/lib/fastlane/version.rb +1 -1
  12. data/fastlane/swift/Deliverfile.swift +1 -1
  13. data/fastlane/swift/DeliverfileProtocol.swift +1 -1
  14. data/fastlane/swift/Fastlane.swift +14 -2
  15. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/joshholtz.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  16. data/fastlane/swift/Gymfile.swift +1 -1
  17. data/fastlane/swift/GymfileProtocol.swift +1 -1
  18. data/fastlane/swift/Matchfile.swift +1 -1
  19. data/fastlane/swift/MatchfileProtocol.swift +5 -1
  20. data/fastlane/swift/Precheckfile.swift +1 -1
  21. data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
  22. data/fastlane/swift/Scanfile.swift +1 -1
  23. data/fastlane/swift/ScanfileProtocol.swift +1 -1
  24. data/fastlane/swift/Screengrabfile.swift +1 -1
  25. data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
  26. data/fastlane/swift/Snapshotfile.swift +1 -1
  27. data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
  28. data/fastlane/swift/SocketClient.swift +1 -1
  29. data/fastlane/swift/formatting/Brewfile.lock.json +21 -16
  30. data/fastlane_core/lib/fastlane_core/project.rb +19 -2
  31. data/frameit/lib/frameit/device_types.rb +2 -0
  32. data/match/lib/match/.module.rb.swp +0 -0
  33. data/match/lib/match/.nuke.rb.swp +0 -0
  34. data/match/lib/match/encryption.rb +3 -0
  35. data/match/lib/match/importer.rb +1 -0
  36. data/match/lib/match/module.rb +53 -1
  37. data/match/lib/match/nuke.rb +3 -40
  38. data/match/lib/match/options.rb +6 -0
  39. data/match/lib/match/runner.rb +5 -1
  40. data/match/lib/match/spaceship_ensure.rb +4 -2
  41. data/match/lib/match/storage/gitlab/client.rb +86 -0
  42. data/match/lib/match/storage/gitlab/secure_file.rb +66 -0
  43. data/match/lib/match/storage/gitlab_secure_files.rb +179 -0
  44. data/match/lib/match/storage.rb +4 -0
  45. data/scan/lib/scan/detect_values.rb +6 -0
  46. data/sigh/lib/sigh/download_all.rb +14 -2
  47. data/sigh/lib/sigh/module.rb +3 -1
  48. data/sigh/lib/sigh/runner.rb +7 -0
  49. data/snapshot/lib/snapshot/reports_generator.rb +1 -0
  50. data/spaceship/lib/spaceship/connect_api/models/app.rb +4 -2
  51. data/spaceship/lib/spaceship/connect_api/models/profile.rb +4 -0
  52. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +18 -8
  53. metadata +27 -22
@@ -0,0 +1,86 @@
1
+ require 'net/http/post/multipart'
2
+ require 'securerandom'
3
+
4
+ require_relative '../../module'
5
+ require_relative './secure_file'
6
+
7
+ module Match
8
+ module Storage
9
+ class GitLab
10
+ class Client
11
+ def initialize(api_v4_url:, project_id:, job_token: nil, private_token: nil)
12
+ @job_token = job_token
13
+ @private_token = private_token
14
+ @api_v4_url = api_v4_url
15
+ @project_id = project_id
16
+
17
+ UI.important("JOB_TOKEN and PRIVATE_TOKEN both defined, using JOB_TOKEN to execute this job.") if @job_token && @private_token
18
+ end
19
+
20
+ def base_url
21
+ return "#{@api_v4_url}/projects/#{CGI.escape(@project_id)}/secure_files"
22
+ end
23
+
24
+ def authentication_key
25
+ if @job_token
26
+ return "JOB-TOKEN"
27
+ elsif @private_token
28
+ return "PRIVATE-TOKEN"
29
+ end
30
+ end
31
+
32
+ def authentication_value
33
+ if @job_token
34
+ return @job_token
35
+ elsif @private_token
36
+ return @private_token
37
+ end
38
+ end
39
+
40
+ def files
41
+ @files ||= begin
42
+ url = URI.parse(base_url)
43
+
44
+ request = Net::HTTP::Get.new(url.request_uri)
45
+
46
+ res = execute_request(url, request)
47
+
48
+ data = []
49
+
50
+ JSON.parse(res.body).each do |file|
51
+ data << SecureFile.new(client: self, file: file)
52
+ end
53
+
54
+ data
55
+ end
56
+ end
57
+
58
+ def find_file_by_name(name)
59
+ files.select { |secure_file| secure_file.file.name == name }.first
60
+ end
61
+
62
+ def upload_file(current_file, target_file)
63
+ url = URI.parse(base_url)
64
+
65
+ File.open(current_file) do |file|
66
+ request = Net::HTTP::Post::Multipart.new(
67
+ url.path,
68
+ "file" => UploadIO.new(file, "application/octet-stream"),
69
+ "name" => target_file
70
+ )
71
+
72
+ execute_request(url, request)
73
+ end
74
+ end
75
+
76
+ def execute_request(url, request)
77
+ request[authentication_key] = authentication_value
78
+
79
+ http = Net::HTTP.new(url.host, url.port)
80
+ http.use_ssl = url.instance_of?(URI::HTTPS)
81
+ http.request(request)
82
+ end
83
+ end
84
+ end
85
+ end
86
+ end
@@ -0,0 +1,66 @@
1
+ require 'open-uri'
2
+
3
+ require_relative '../../module'
4
+
5
+ module Match
6
+ module Storage
7
+ class GitLab
8
+ class SecureFile
9
+ attr_reader :client, :file
10
+
11
+ def initialize(file:, client:)
12
+ @file = OpenStruct.new(file)
13
+ @client = client
14
+ end
15
+
16
+ def file_url
17
+ "#{@client.base_url}/#{@file.id}"
18
+ end
19
+
20
+ def create_subfolders(working_directory)
21
+ FileUtils.mkdir_p("#{working_directory}/#{destination_file_path}")
22
+ end
23
+
24
+ def destination_file_path
25
+ filename = @file.name.split('/').last
26
+
27
+ @file.name.gsub(filename, '').gsub(%r{^/}, '')
28
+ end
29
+
30
+ def valid_checksum?(file)
31
+ Digest::SHA256.hexdigest(File.read(file)) == @file.checksum
32
+ end
33
+
34
+ def download(working_directory)
35
+ url = URI("#{file_url}/download")
36
+
37
+ begin
38
+ destination_file = "#{working_directory}/#{@file.name}"
39
+
40
+ create_subfolders(working_directory)
41
+ File.open(destination_file, "wb") do |saved_file|
42
+ URI.open(url, "rb", { @client.authentication_key => @client.authentication_value }) do |data|
43
+ saved_file.write(data.read)
44
+ end
45
+
46
+ # Set file mode to read-only
47
+ FileUtils.chmod('u=r,go-r', destination_file)
48
+ end
49
+
50
+ UI.crash!("Checksum validation failed for #{@file.name}") unless valid_checksum?(destination_file)
51
+ rescue OpenURI::HTTPError => msg
52
+ UI.error("Unable to download #{@file.name} - #{msg}")
53
+ end
54
+ end
55
+
56
+ def delete
57
+ url = URI(file_url)
58
+
59
+ request = Net::HTTP::Delete.new(url.request_uri)
60
+
61
+ @client.execute_request(url, request)
62
+ end
63
+ end
64
+ end
65
+ end
66
+ end
@@ -0,0 +1,179 @@
1
+ require 'fastlane_core/command_executor'
2
+ require 'fastlane_core/configuration/configuration'
3
+ require 'net/http/post/multipart'
4
+
5
+ require_relative './gitlab/client'
6
+ require_relative './gitlab/secure_file'
7
+
8
+ require_relative '../options'
9
+ require_relative '../module'
10
+ require_relative '../spaceship_ensure'
11
+ require_relative './interface'
12
+
13
+ module Match
14
+ module Storage
15
+ # Store the code signing identities in GitLab Secure Files
16
+ class GitLabSecureFiles < Interface
17
+ attr_reader :gitlab_client
18
+ attr_reader :readonly
19
+ attr_reader :username
20
+ attr_reader :team_id
21
+ attr_reader :team_name
22
+ attr_reader :api_key_path
23
+ attr_reader :api_key
24
+
25
+ def self.configure(params)
26
+ api_v4_url = params[:api_v4_url] || ENV['CI_API_V4_URL'] || 'https://gitlab.com/api/v4'
27
+ project_id = params[:gitlab_project] || ENV['GITLAB_PROJECT'] || ENV['CI_PROJECT_ID']
28
+ job_token = params[:job_token] || ENV['CI_JOB_TOKEN']
29
+ private_token = params[:private_token] || ENV['PRIVATE_TOKEN']
30
+
31
+ if params[:git_url].to_s.length > 0
32
+ UI.important("Looks like you still define a `git_url` somewhere, even though")
33
+ UI.important("you use GitLab Secure Files. You can remove the `git_url`")
34
+ UI.important("from your Matchfile and Fastfile")
35
+ UI.message("The above is just a warning, fastlane will continue as usual now...")
36
+ end
37
+
38
+ return self.new(
39
+ api_v4_url: api_v4_url,
40
+ project_id: project_id,
41
+ job_token: job_token,
42
+ private_token: private_token,
43
+ readonly: params[:readonly],
44
+ username: params[:username],
45
+ team_id: params[:team_id],
46
+ team_name: params[:team_name],
47
+ api_key_path: params[:api_key_path],
48
+ api_key: params[:api_key]
49
+ )
50
+ end
51
+
52
+ def initialize(api_v4_url: nil,
53
+ project_id: nil,
54
+ job_token: nil,
55
+ private_token: nil,
56
+ readonly: nil,
57
+ username: nil,
58
+ team_id: nil,
59
+ team_name: nil,
60
+ api_key_path: nil,
61
+ api_key: nil)
62
+
63
+ @readonly = readonly
64
+ @username = username
65
+ @team_id = team_id
66
+ @team_name = team_name
67
+ @api_key_path = api_key_path
68
+ @api_key = api_key
69
+
70
+ @job_token = job_token
71
+ @private_token = private_token
72
+ @api_v4_url = api_v4_url
73
+ @project_id = project_id
74
+ @gitlab_client = GitLab::Client.new(job_token: job_token, private_token: private_token, project_id: project_id, api_v4_url: api_v4_url)
75
+
76
+ UI.message("Initializing match for GitLab project #{@project_id}")
77
+ end
78
+
79
+ # To make debugging easier, we have a custom exception here
80
+ def prefixed_working_directory
81
+ # We fall back to "*", which means certificates and profiles
82
+ # from all teams that use this bucket would be installed. This is not ideal, but
83
+ # unless the user provides a `team_id`, we can't know which one to use
84
+ # This only happens if `readonly` is activated, and no `team_id` was provided
85
+ @_folder_prefix ||= currently_used_team_id
86
+ if @_folder_prefix.nil?
87
+ # We use a `@_folder_prefix` variable, to keep state between multiple calls of this
88
+ # method, as the value won't change. This way the warning is only printed once
89
+ UI.important("Looks like you run `match` in `readonly` mode, and didn't provide a `team_id`. This will still work, however it is recommended to provide a `team_id` in your Appfile or Matchfile")
90
+ @_folder_prefix = "*"
91
+ end
92
+ return File.join(working_directory, @_folder_prefix)
93
+ end
94
+
95
+ def download
96
+ # Check if we already have a functional working_directory
97
+ return if @working_directory
98
+
99
+ # No existing working directory, creating a new one now
100
+ self.working_directory = Dir.mktmpdir
101
+
102
+ @gitlab_client.files.each do |secure_file|
103
+ secure_file.download(self.working_directory)
104
+ end
105
+
106
+ UI.verbose("Successfully downloaded all Secure Files from GitLab to #{self.working_directory}")
107
+ end
108
+
109
+ def currently_used_team_id
110
+ if self.readonly
111
+ # In readonly mode, we still want to see if the user provided a team_id
112
+ # see `prefixed_working_directory` comments for more details
113
+ return self.team_id
114
+ else
115
+ UI.user_error!("The `team_id` option is required. fastlane cannot automatically determine portal team id via the App Store Connect API (yet)") if self.team_id.to_s.empty?
116
+
117
+ spaceship = SpaceshipEnsure.new(self.username, self.team_id, self.team_name, api_token)
118
+ return spaceship.team_id
119
+ end
120
+ end
121
+
122
+ def api_token
123
+ api_token = Spaceship::ConnectAPI::Token.from(hash: self.api_key, filepath: self.api_key_path)
124
+ api_token ||= Spaceship::ConnectAPI.token
125
+ return api_token
126
+ end
127
+
128
+ # Returns a short string describing + identifing the current
129
+ # storage backend. This will be printed when nuking a storage
130
+ def human_readable_description
131
+ "GitLab Secure Files Storage [#{self.project_id}]"
132
+ end
133
+
134
+ def upload_files(files_to_upload: [], custom_message: nil)
135
+ # `files_to_upload` is an array of files that need to be uploaded to GitLab Secure Files
136
+ # Those doesn't mean they're new, it might just be they're changed
137
+ # Either way, we'll upload them using the same technique
138
+
139
+ files_to_upload.each do |current_file|
140
+ # Go from
141
+ # "/var/folders/px/bz2kts9n69g8crgv4jpjh6b40000gn/T/d20181026-96528-1av4gge/profiles/development/Development_me.mobileprovision"
142
+ # to
143
+ # "profiles/development/Development_me.mobileprovision"
144
+ #
145
+
146
+ # We also remove the trailing `/`
147
+ target_file = current_file.gsub(self.working_directory + "/", "")
148
+ UI.verbose("Uploading '#{target_file}' to GitLab Secure Files...")
149
+ @gitlab_client.upload_file(current_file, target_file)
150
+ end
151
+ end
152
+
153
+ def delete_files(files_to_delete: [], custom_message: nil)
154
+ files_to_delete.each do |current_file|
155
+ target_path = current_file.gsub(self.working_directory + "/", "")
156
+
157
+ secure_file = @gitlab_client.find_file_by_name(target_path)
158
+ UI.message("Deleting '#{target_path}' from GitLab Secure Files...")
159
+ secure_file.delete
160
+ end
161
+ end
162
+
163
+ def skip_docs
164
+ false
165
+ end
166
+
167
+ def list_files(file_name: "", file_ext: "")
168
+ Dir[File.join(working_directory, self.team_id, "**", file_name, "*.#{file_ext}")]
169
+ end
170
+
171
+ # Implement this for the `fastlane match init` command
172
+ # This method must return the content of the Matchfile
173
+ # that should be generated
174
+ def generate_matchfile_content(template: nil)
175
+ return "gitlab_project(\"#{self.project_id}\")"
176
+ end
177
+ end
178
+ end
179
+ end
@@ -2,6 +2,7 @@ require_relative 'storage/interface'
2
2
  require_relative 'storage/git_storage'
3
3
  require_relative 'storage/google_cloud_storage'
4
4
  require_relative 'storage/s3_storage'
5
+ require_relative 'storage/gitlab_secure_files'
5
6
 
6
7
  module Match
7
8
  module Storage
@@ -16,6 +17,9 @@ module Match
16
17
  },
17
18
  "s3" => lambda { |params|
18
19
  return Storage::S3Storage.configure(params)
20
+ },
21
+ "gitlab_secure_files" => lambda { |params|
22
+ return Storage::GitLabSecureFiles.configure(params)
19
23
  }
20
24
  }
21
25
  end
@@ -209,6 +209,12 @@ module Scan
209
209
 
210
210
  def self.detect_destination
211
211
  if Scan.config[:destination]
212
+ # No need to show below warnings message(s) for xcode13+, because
213
+ # Apple recommended to have destination in all xcodebuild commands
214
+ # otherwise, Apple will generate warnings in console logs
215
+ # see: https://github.com/fastlane/fastlane/issues/19579
216
+ return if Helper.xcode_at_least?("13.0")
217
+
212
218
  UI.important("It's not recommended to set the `destination` value directly")
213
219
  UI.important("Instead use the other options available in `fastlane scan --help`")
214
220
  UI.important("Using your value '#{Scan.config[:destination]}' for now")
@@ -40,12 +40,26 @@ module Sigh
40
40
  Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DEVELOPMENT,
41
41
  Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DIRECT
42
42
  ]
43
+
44
+ # As of 2022-06-25, only available with Apple ID auth
45
+ if Spaceship::ConnectAPI.token
46
+ UI.important("Skipping #{Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_INHOUSE}... only available with Apple ID auth")
47
+ else
48
+ profile_types << Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_INHOUSE
49
+ end
43
50
  when 'catalyst'
44
51
  profile_types = [
45
52
  Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_STORE,
46
53
  Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DEVELOPMENT,
47
54
  Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DIRECT
48
55
  ]
56
+
57
+ # As of 2022-06-25, only available with Apple ID auth
58
+ if Spaceship::ConnectAPI.token
59
+ UI.important("Skipping #{Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_INHOUSE}... only available with Apple ID auth")
60
+ else
61
+ profile_types << Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_INHOUSE
62
+ end
49
63
  when 'tvos'
50
64
  profile_types = [
51
65
  Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_STORE,
@@ -55,8 +69,6 @@ module Sigh
55
69
  ]
56
70
  end
57
71
 
58
- # Filtering on 'profileType' seems to be undocumented as of 2020-07-30
59
- # but works on both web session and official API
60
72
  profiles = Spaceship::ConnectAPI::Profile.all(filter: { profileType: profile_types.join(",") }, includes: "bundleId")
61
73
  download_profiles(profiles)
62
74
  end
@@ -24,7 +24,9 @@ module Sigh
24
24
  Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_ADHOC
25
25
  "AdHoc"
26
26
  when Spaceship::ConnectAPI::Profile::ProfileType::IOS_APP_INHOUSE,
27
- Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_INHOUSE
27
+ Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_INHOUSE,
28
+ Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_INHOUSE,
29
+ Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_INHOUSE
28
30
  "InHouse"
29
31
  when Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DIRECT,
30
32
  Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DIRECT
@@ -82,10 +82,12 @@ module Sigh
82
82
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::TVOS_APP_DEVELOPMENT if Sigh.config[:development]
83
83
  when "macos"
84
84
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_STORE
85
+ @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_INHOUSE if Spaceship::ConnectAPI.client.in_house?
85
86
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DEVELOPMENT if Sigh.config[:development]
86
87
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_DIRECT if Sigh.config[:developer_id]
87
88
  when "catalyst"
88
89
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_STORE
90
+ @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_INHOUSE if Spaceship::ConnectAPI.client.in_house?
89
91
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DEVELOPMENT if Sigh.config[:development]
90
92
  @profile_type = Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_DIRECT if Sigh.config[:developer_id]
91
93
  end
@@ -254,6 +256,11 @@ module Sigh
254
256
  Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPER_ID_APPLICATION,
255
257
  Spaceship::ConnectAPI::Certificate::CertificateType::DEVELOPER_ID_APPLICATION_G2
256
258
  ]
259
+ elsif profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_APP_INHOUSE || profile_type == Spaceship::ConnectAPI::Profile::ProfileType::MAC_CATALYST_APP_INHOUSE
260
+ # Enterprise accounts don't have access to Apple Distribution certificates
261
+ types = [
262
+ Spaceship::ConnectAPI::Certificate::CertificateType::MAC_APP_DISTRIBUTION
263
+ ]
257
264
  else
258
265
  types = [
259
266
  Spaceship::ConnectAPI::Certificate::CertificateType::DISTRIBUTION,
@@ -132,6 +132,7 @@ module Snapshot
132
132
  'iPad Pro (12.9-inch)' => 'iPad Pro (12.9-inch)',
133
133
  'iPad Pro (12.9 inch)' => 'iPad Pro (12.9-inch)', # iOS 10.3.1 simulator
134
134
  'iPad Pro' => 'iPad Pro (12.9-inch)', # iOS 9.3 simulator
135
+ 'iPod touch (7th generation)' => 'iPod touch (7th generation)',
135
136
  'Apple TV 1080p' => 'Apple TV',
136
137
  'Apple TV 4K (at 1080p)' => 'Apple TV 4K (at 1080p)',
137
138
  'Apple TV 4K' => 'Apple TV 4K',
@@ -101,10 +101,12 @@ module Spaceship
101
101
  return client.get_app(app_id: app_id, includes: includes).first
102
102
  end
103
103
 
104
- def update(client: nil, attributes: nil, app_price_tier_id: nil, territory_ids: nil)
104
+ # Updates app attributes, price tier and availability of an app in territories
105
+ # Check Tunes patch_app method for explanation how to use territory_ids parameter with allow_removing_from_sale to remove app from sale
106
+ def update(client: nil, attributes: nil, app_price_tier_id: nil, territory_ids: nil, allow_removing_from_sale: false)
105
107
  client ||= Spaceship::ConnectAPI
106
108
  attributes = reverse_attr_mapping(attributes)
107
- return client.patch_app(app_id: id, attributes: attributes, app_price_tier_id: app_price_tier_id, territory_ids: territory_ids)
109
+ return client.patch_app(app_id: id, attributes: attributes, app_price_tier_id: app_price_tier_id, territory_ids: territory_ids, allow_removing_from_sale: allow_removing_from_sale)
108
110
  end
109
111
 
110
112
  #
@@ -51,6 +51,10 @@ module Spaceship
51
51
  MAC_CATALYST_APP_DEVELOPMENT = "MAC_CATALYST_APP_DEVELOPMENT"
52
52
  MAC_CATALYST_APP_STORE = "MAC_CATALYST_APP_STORE"
53
53
  MAC_CATALYST_APP_DIRECT = "MAC_CATALYST_APP_DIRECT"
54
+
55
+ # As of 2022-06-25, only available with Apple ID auth
56
+ MAC_APP_INHOUSE = "MAC_APP_INHOUSE"
57
+ MAC_CATALYST_APP_INHOUSE = "MAC_CATALYST_APP_INHOUSE"
54
58
  end
55
59
 
56
60
  def self.type
@@ -134,7 +134,15 @@ module Spaceship
134
134
  tunes_request_client.post("apps", body)
135
135
  end
136
136
 
137
- def patch_app(app_id: nil, attributes: {}, app_price_tier_id: nil, territory_ids: nil)
137
+ # Updates app attributes, price tier, visibility in regions or countries.
138
+ # Use territory_ids with allow_removing_from_sale to remove app from sale
139
+ # @param territory_ids updates app visibility in regions or countries.
140
+ # Possible values:
141
+ # empty array will remove app from sale if allow_removing_from_sale is true,
142
+ # array with territory ids will set availability to territories with those ids,
143
+ # nil will leave app availability on AppStore as is
144
+ # @param allow_removing_from_sale allows for removing app from sale when territory_ids is an empty array
145
+ def patch_app(app_id: nil, attributes: {}, app_price_tier_id: nil, territory_ids: nil, allow_removing_from_sale: false)
138
146
  relationships = {}
139
147
  included = []
140
148
 
@@ -173,13 +181,15 @@ module Spaceship
173
181
  end
174
182
 
175
183
  # Territories
176
- territories_data = (territory_ids || []).map do |id|
177
- { type: "territories", id: id }
178
- end
179
- unless territories_data.empty?
180
- relationships[:availableTerritories] = {
181
- data: territories_data
182
- }
184
+ unless territory_ids.nil?
185
+ territories_data = territory_ids.map do |id|
186
+ { type: "territories", id: id }
187
+ end
188
+ if !territories_data.empty? || allow_removing_from_sale
189
+ relationships[:availableTerritories] = {
190
+ data: territories_data
191
+ }
192
+ end
183
193
  end
184
194
 
185
195
  # Data
metadata CHANGED
@@ -1,39 +1,39 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: fastlane
3
3
  version: !ruby/object:Gem::Version
4
- version: 2.206.2
4
+ version: 2.207.0
5
5
  platform: ruby
6
6
  authors:
7
- - Łukasz Grabowski
8
- - Jérôme Lacoste
9
- - Iulian Onofrei
10
- - Manu Wallner
7
+ - Max Ott
11
8
  - Daniel Jankowski
12
- - Jan Piotrowski
13
- - Jorge Revuelta H
9
+ - Manish Rathi
10
+ - Stefan Natchev
14
11
  - Felix Krause
15
- - Luka Mirosevic
16
- - Kohki Miki
17
- - Joshua Liebowitz
12
+ - Iulian Onofrei
18
13
  - Danielle Tomlinson
19
- - Satoshi Namai
20
- - Max Ott
21
- - Josh Holtz
22
- - Olivier Halligon
23
- - Matthew Ellis
24
- - Aaron Brager
25
- - Maksym Grebenets
26
14
  - Fumiya Nakamura
27
- - Jimmy Dee
15
+ - Josh Holtz
16
+ - Kohki Miki
17
+ - Jorge Revuelta H
18
+ - Manu Wallner
28
19
  - Roger Oba
29
- - Manish Rathi
20
+ - Satoshi Namai
21
+ - Joshua Liebowitz
22
+ - Maksym Grebenets
23
+ - Aaron Brager
24
+ - Jérôme Lacoste
25
+ - Łukasz Grabowski
26
+ - Matthew Ellis
27
+ - Luka Mirosevic
28
+ - Olivier Halligon
30
29
  - Helmut Januschka
31
- - Stefan Natchev
30
+ - Jan Piotrowski
31
+ - Jimmy Dee
32
32
  - Andrew McBurney
33
33
  autorequire:
34
34
  bindir: bin
35
35
  cert_chain: []
36
- date: 2022-05-25 00:00:00.000000000 Z
36
+ date: 2022-06-30 00:00:00.000000000 Z
37
37
  dependencies:
38
38
  - !ruby/object:Gem::Dependency
39
39
  name: xcodeproj
@@ -1501,6 +1501,8 @@ files:
1501
1501
  - match/lib/assets/MatchfileTemplate.swift
1502
1502
  - match/lib/assets/READMETemplate.md
1503
1503
  - match/lib/match.rb
1504
+ - match/lib/match/.module.rb.swp
1505
+ - match/lib/match/.nuke.rb.swp
1504
1506
  - match/lib/match/change_password.rb
1505
1507
  - match/lib/match/commands_generator.rb
1506
1508
  - match/lib/match/encryption.rb
@@ -1517,6 +1519,9 @@ files:
1517
1519
  - match/lib/match/spaceship_ensure.rb
1518
1520
  - match/lib/match/storage.rb
1519
1521
  - match/lib/match/storage/git_storage.rb
1522
+ - match/lib/match/storage/gitlab/client.rb
1523
+ - match/lib/match/storage/gitlab/secure_file.rb
1524
+ - match/lib/match/storage/gitlab_secure_files.rb
1520
1525
  - match/lib/match/storage/google_cloud_storage.rb
1521
1526
  - match/lib/match/storage/interface.rb
1522
1527
  - match/lib/match/storage/s3_storage.rb
@@ -1893,7 +1898,7 @@ required_ruby_version: !ruby/object:Gem::Requirement
1893
1898
  requirements:
1894
1899
  - - ">="
1895
1900
  - !ruby/object:Gem::Version
1896
- version: '2.5'
1901
+ version: '2.6'
1897
1902
  required_rubygems_version: !ruby/object:Gem::Requirement
1898
1903
  requirements:
1899
1904
  - - ">="