fastlane 2.167.0 → 2.172.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (130) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +76 -76
  3. data/cert/lib/cert/options.rb +3 -3
  4. data/deliver/lib/deliver/app_screenshot.rb +5 -7
  5. data/deliver/lib/deliver/app_screenshot_validator.rb +108 -0
  6. data/deliver/lib/deliver/commands_generator.rb +1 -1
  7. data/deliver/lib/deliver/loader.rb +123 -21
  8. data/deliver/lib/deliver/setup.rb +8 -3
  9. data/deliver/lib/deliver/upload_metadata.rb +6 -10
  10. data/deliver/lib/deliver/upload_screenshots.rb +1 -64
  11. data/fastlane/lib/fastlane/actions/{.download_dsyms.rb.swp → .update_fastlane.rb.swp} +0 -0
  12. data/fastlane/lib/fastlane/actions/add_git_tag.rb +12 -3
  13. data/fastlane/lib/fastlane/actions/artifactory.rb +36 -3
  14. data/fastlane/lib/fastlane/actions/build_app.rb +3 -1
  15. data/fastlane/lib/fastlane/actions/create_pull_request.rb +16 -1
  16. data/fastlane/lib/fastlane/actions/create_xcframework.rb +118 -0
  17. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
  18. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +1 -1
  19. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +4 -0
  20. data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +5 -1
  21. data/fastlane/lib/fastlane/actions/download_app_privacy_details_from_app_store.rb +142 -0
  22. data/fastlane/lib/fastlane/actions/download_dsyms.rb +0 -1
  23. data/fastlane/lib/fastlane/actions/git_commit.rb +6 -2
  24. data/fastlane/lib/fastlane/actions/github_api.rb +14 -3
  25. data/fastlane/lib/fastlane/actions/nexus_upload.rb +1 -0
  26. data/fastlane/lib/fastlane/actions/onesignal.rb +13 -3
  27. data/fastlane/lib/fastlane/actions/pod_push.rb +9 -0
  28. data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +9 -1
  29. data/fastlane/lib/fastlane/actions/register_device.rb +1 -1
  30. data/fastlane/lib/fastlane/actions/register_devices.rb +2 -1
  31. data/fastlane/lib/fastlane/actions/set_github_release.rb +21 -8
  32. data/fastlane/lib/fastlane/actions/slack.rb +4 -5
  33. data/fastlane/lib/fastlane/actions/slather.rb +2 -2
  34. data/fastlane/lib/fastlane/actions/spm.rb +2 -2
  35. data/fastlane/lib/fastlane/actions/swiftlint.rb +4 -4
  36. data/fastlane/lib/fastlane/actions/upload_app_privacy_details_to_app_store.rb +291 -0
  37. data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +3 -3
  38. data/fastlane/lib/fastlane/actions/xcode_install.rb +8 -5
  39. data/fastlane/lib/fastlane/cli_tools_distributor.rb +3 -0
  40. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +1 -1
  41. data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +3 -0
  42. data/fastlane/lib/fastlane/version.rb +1 -1
  43. data/fastlane/swift/Deliverfile.swift +2 -2
  44. data/fastlane/swift/DeliverfileProtocol.swift +2 -2
  45. data/fastlane/swift/Fastlane.swift +276 -54
  46. data/fastlane/swift/Gymfile.swift +2 -2
  47. data/fastlane/swift/GymfileProtocol.swift +15 -3
  48. data/fastlane/swift/Matchfile.swift +2 -2
  49. data/fastlane/swift/MatchfileProtocol.swift +4 -4
  50. data/fastlane/swift/Precheckfile.swift +2 -2
  51. data/fastlane/swift/PrecheckfileProtocol.swift +6 -2
  52. data/fastlane/swift/Scanfile.swift +2 -2
  53. data/fastlane/swift/ScanfileProtocol.swift +18 -2
  54. data/fastlane/swift/Screengrabfile.swift +2 -2
  55. data/fastlane/swift/ScreengrabfileProtocol.swift +2 -2
  56. data/fastlane/swift/Snapshotfile.swift +2 -2
  57. data/fastlane/swift/SnapshotfileProtocol.swift +15 -3
  58. data/fastlane_core/lib/fastlane_core/helper.rb +3 -3
  59. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +41 -16
  60. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +3 -4
  61. data/fastlane_core/lib/fastlane_core/project.rb +18 -5
  62. data/frameit/lib/frameit/device_types.rb +7 -1
  63. data/gym/lib/gym/generators/build_command_generator.rb +3 -0
  64. data/gym/lib/gym/options.rb +19 -3
  65. data/match/lib/match/encryption/openssl.rb +4 -2
  66. data/match/lib/match/module.rb +1 -1
  67. data/match/lib/match/options.rb +1 -1
  68. data/match/lib/match/runner.rb +1 -1
  69. data/match/lib/match/storage/git_storage.rb +14 -10
  70. data/precheck/lib/precheck/options.rb +6 -1
  71. data/precheck/lib/precheck/rule_processor.rb +1 -1
  72. data/precheck/lib/precheck/runner.rb +1 -1
  73. data/scan/lib/scan/options.rb +22 -1
  74. data/scan/lib/scan/runner.rb +7 -2
  75. data/scan/lib/scan/slack_poster.rb +4 -1
  76. data/scan/lib/scan/test_command_generator.rb +3 -0
  77. data/screengrab/lib/screengrab/runner.rb +2 -0
  78. data/sigh/lib/sigh/runner.rb +1 -1
  79. data/snapshot/lib/assets/SnapshotHelper.swift +6 -2
  80. data/snapshot/lib/snapshot/options.rb +17 -2
  81. data/snapshot/lib/snapshot/update.rb +1 -1
  82. data/spaceship/lib/spaceship/client.rb +14 -0
  83. data/spaceship/lib/spaceship/connect_api.rb +6 -0
  84. data/spaceship/lib/spaceship/connect_api/api_client.rb +1 -1
  85. data/spaceship/lib/spaceship/connect_api/models/age_rating_declaration.rb +3 -2
  86. data/spaceship/lib/spaceship/connect_api/models/app.rb +94 -54
  87. data/spaceship/lib/spaceship/connect_api/models/app_data_usage.rb +59 -0
  88. data/spaceship/lib/spaceship/connect_api/models/app_data_usage_category.rb +65 -0
  89. data/spaceship/lib/spaceship/connect_api/models/app_data_usage_data_protection.rb +27 -0
  90. data/spaceship/lib/spaceship/connect_api/models/app_data_usage_grouping.rb +18 -0
  91. data/spaceship/lib/spaceship/connect_api/models/app_data_usage_purposes.rb +37 -0
  92. data/spaceship/lib/spaceship/connect_api/models/app_data_usages_publish_state.rb +36 -0
  93. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +16 -10
  94. data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +8 -4
  95. data/spaceship/lib/spaceship/connect_api/models/app_preview.rb +15 -11
  96. data/spaceship/lib/spaceship/connect_api/models/app_preview_set.rb +13 -9
  97. data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +9 -7
  98. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +15 -11
  99. data/spaceship/lib/spaceship/connect_api/models/app_store_review_attachment.rb +7 -5
  100. data/spaceship/lib/spaceship/connect_api/models/app_store_review_detail.rb +6 -4
  101. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +62 -37
  102. data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +21 -14
  103. data/spaceship/lib/spaceship/connect_api/models/app_store_version_submission.rb +3 -2
  104. data/spaceship/lib/spaceship/connect_api/models/beta_app_review_submission.rb +3 -2
  105. data/spaceship/lib/spaceship/connect_api/models/beta_feedback.rb +6 -4
  106. data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +12 -2
  107. data/spaceship/lib/spaceship/connect_api/models/beta_tester.rb +12 -8
  108. data/spaceship/lib/spaceship/connect_api/models/build.rb +24 -16
  109. data/spaceship/lib/spaceship/connect_api/models/build_delivery.rb +3 -2
  110. data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +9 -6
  111. data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +6 -4
  112. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +12 -8
  113. data/spaceship/lib/spaceship/connect_api/models/device.rb +36 -4
  114. data/spaceship/lib/spaceship/connect_api/models/idfa_declaration.rb +6 -4
  115. data/spaceship/lib/spaceship/connect_api/models/profile.rb +12 -8
  116. data/spaceship/lib/spaceship/connect_api/models/reset_ratings_request.rb +3 -2
  117. data/spaceship/lib/spaceship/connect_api/models/sandbox_tester.rb +9 -6
  118. data/spaceship/lib/spaceship/connect_api/models/territory.rb +3 -2
  119. data/spaceship/lib/spaceship/connect_api/models/user.rb +6 -4
  120. data/spaceship/lib/spaceship/connect_api/models/user_invitation.rb +9 -6
  121. data/spaceship/lib/spaceship/connect_api/response.rb +3 -1
  122. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +12 -0
  123. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +103 -0
  124. data/spaceship/lib/spaceship/errors.rb +19 -0
  125. data/spaceship/lib/spaceship/tunes/iap_detail.rb +1 -1
  126. data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
  127. data/spaceship/lib/spaceship/two_step_or_factor_client.rb +19 -6
  128. data/supply/lib/supply/options.rb +1 -1
  129. data/supply/lib/supply/uploader.rb +3 -2
  130. metadata +45 -21
@@ -115,8 +115,8 @@ module Fastlane
115
115
  is_string: false),
116
116
  FastlaneCore::ConfigItem.new(key: :default_payloads,
117
117
  env_name: "FL_SLACK_DEFAULT_PAYLOADS",
118
- description: "Remove some of the default payloads. More information about the available payloads on GitHub",
119
- optional: true,
118
+ description: "Specifies default payloads to include. Pass an empty array to suppress all the default payloads",
119
+ default_value: ['lane', 'test_result', 'git_branch', 'git_author', 'last_git_commit', 'last_git_commit_hash'],
120
120
  type: Array),
121
121
  FastlaneCore::ConfigItem.new(key: :attachment_properties,
122
122
  env_name: "FL_SLACK_ATTACHMENT_PROPERTIES",
@@ -159,8 +159,7 @@ module Fastlane
159
159
  "Build Date" => Time.new.to_s,
160
160
  "Built by" => "Jenkins",
161
161
  },
162
- default_payloads: [:git_branch, :git_author], # Optional, lets you specify an allowlist of default payloads to include. Pass an empty array to suppress all the default payloads.
163
- # Don\'t add this key, or pass nil, if you want all the default payloads. The available default payloads are: `lane`, `test_result`, `git_branch`, `git_author`, `last_git_commit`, `last_git_commit_hash`.
162
+ default_payloads: [:git_branch, :git_author], # Optional, lets you specify default payloads to include. Pass an empty array to suppress all the default payloads.
164
163
  attachment_properties: { # Optional, lets you specify any other properties available for attachments in the slack API (see https://api.slack.com/docs/attachments).
165
164
  # This hash is deep merged with the existing properties set using the other properties above. This allows your own fields properties to be appended to the existing fields that were created using the `payload` property for instance.
166
165
  thumb_url: "http://example.com/path/to/thumb.png",
@@ -188,7 +187,7 @@ module Fastlane
188
187
 
189
188
  def self.generate_slack_attachments(options)
190
189
  color = (options[:success] ? 'good' : 'danger')
191
- should_add_payload = ->(payload_name) { options[:default_payloads].nil? || options[:default_payloads].map(&:to_sym).include?(payload_name.to_sym) }
190
+ should_add_payload = ->(payload_name) { options[:default_payloads].map(&:to_sym).include?(payload_name.to_sym) }
192
191
 
193
192
  slack_attachment = {
194
193
  fallback: options[:message],
@@ -272,8 +272,8 @@ module Fastlane
272
272
  FastlaneCore::ConfigItem.new(key: :binary_basename,
273
273
  env_name: "FL_SLATHER_BINARY_BASENAME",
274
274
  description: "Basename of the binary file, this should match the name of your bundle excluding its extension (i.e. YourApp [for YourApp.app bundle])",
275
- is_string: false,
276
- default_value: false),
275
+ type: Array,
276
+ optional: true),
277
277
  FastlaneCore::ConfigItem.new(key: :binary_file,
278
278
  env_name: "FL_SLATHER_BINARY_FILE",
279
279
  description: "Binary file name to be used for code coverage",
@@ -11,7 +11,7 @@ module Fastlane
11
11
  cmd << "--disable-sandbox" if params[:disable_sandbox]
12
12
  cmd << "--verbose" if params[:verbose]
13
13
  cmd << params[:command] if package_commands.include?(params[:command])
14
- cmd << "--enable-code-coverage" if params[:enable_code_coverage] && params[:command] == 'generate-xcodeproj'
14
+ cmd << "--enable-code-coverage" if params[:enable_code_coverage] && (params[:command] == 'generate-xcodeproj' || params[:command] == 'test')
15
15
  if params[:xcconfig]
16
16
  cmd << "--xcconfig-overrides #{params[:xcconfig]}"
17
17
  end
@@ -47,7 +47,7 @@ module Fastlane
47
47
  end),
48
48
  FastlaneCore::ConfigItem.new(key: :enable_code_coverage,
49
49
  env_name: "FL_SPM_ENABLE_CODE_COVERAGE",
50
- description: "Enables code coverage for the generated Xcode project when using the generate-xcodeproj command",
50
+ description: "Enables code coverage for the generated Xcode project when using the 'generate-xcodeproj' and the 'test' command",
51
51
  is_string: false,
52
52
  optional: true),
53
53
  FastlaneCore::ConfigItem.new(key: :build_path,
@@ -139,13 +139,13 @@ module Fastlane
139
139
  optional: true),
140
140
  FastlaneCore::ConfigItem.new(key: :reporter,
141
141
  env_name: "FL_SWIFTLINT_REPORTER",
142
- description: "Choose output reporter. Available: xcode, json, csv, checkstyle, junit, html, \
143
- emoji, sonarqube, markdown, github-actions-logging",
142
+ description: "Choose output reporter. Available: xcode, json, csv, checkstyle, codeclimate, \
143
+ junit, html, emoji, sonarqube, markdown, github-actions-logging",
144
144
  is_string: true,
145
145
  optional: true,
146
146
  verify_block: proc do |value|
147
- available = ['xcode', 'json', 'csv', 'checkstyle', 'junit', 'html', 'emoji', 'sonarqube', 'markdown', 'github-actions-logging']
148
- UI.user_error!("Available values are '#{available.join("', '")}'") unless available.include?(value)
147
+ available = ['xcode', 'json', 'csv', 'checkstyle', 'codeclimate', 'junit', 'html', 'emoji', 'sonarqube', 'markdown', 'github-actions-logging']
148
+ UI.warning("Known 'reporter' values are '#{available.join("', '")}'. If you're receiving errors from swiftlint related to the reporter, make sure the reporter identifier you're using is correct and it's supported by your version of swiftlint.") unless available.include?(value)
149
149
  end),
150
150
  FastlaneCore::ConfigItem.new(key: :quiet,
151
151
  env_name: "FL_SWIFTLINT_QUIET",
@@ -0,0 +1,291 @@
1
+ module Fastlane
2
+ module Actions
3
+ class UploadAppPrivacyDetailsToAppStoreAction < Action
4
+ DEFAULT_PATH = Fastlane::Helper.fastlane_enabled_folder_path
5
+ DEFAULT_FILE_NAME = "app_privacy_details.json"
6
+
7
+ def self.run(params)
8
+ require 'spaceship'
9
+
10
+ # Prompts select team if multiple teams and none specified
11
+ UI.message("Login to App Store Connect (#{params[:username]})")
12
+ Spaceship::ConnectAPI.login(params[:username], use_portal: false, use_tunes: true, tunes_team_id: params[:team_id], team_name: params[:team_name])
13
+ UI.message("Login successful")
14
+
15
+ # Get App
16
+ app = Spaceship::ConnectAPI::App.find(params[:app_identifier])
17
+ unless app
18
+ UI.user_error!("Could not find app with bundle identifier '#{params[:app_identifier]}' on account #{params[:username]}")
19
+ end
20
+
21
+ # Attempt to load JSON file
22
+ usages_config = load_json_file(params)
23
+
24
+ # Start interactive questions to generate and save JSON file
25
+ unless usages_config
26
+ usages_config = ask_interactive_questions_for_json
27
+
28
+ if params[:skip_json_file_saving]
29
+ UI.message("Skipping JSON file saving...")
30
+ else
31
+ json = JSON.pretty_generate(usages_config)
32
+ path = output_path(params)
33
+
34
+ UI.message("Writing file to #{path}")
35
+ File.write(path, json)
36
+ end
37
+ end
38
+
39
+ # Process JSON file to save app data usages to API
40
+ if params[:skip_upload]
41
+ UI.message("Skipping uploading of data... (so you can verify your JSON file)")
42
+ else
43
+ upload_app_data_usages(params, app, usages_config)
44
+ end
45
+ end
46
+
47
+ def self.load_json_file(params)
48
+ path = params[:json_path]
49
+ return nil if path.nil?
50
+ return JSON.parse(File.read(path))
51
+ end
52
+
53
+ def self.output_path(params)
54
+ path = params[:output_json_path]
55
+ return File.absolute_path(path)
56
+ end
57
+
58
+ def self.ask_interactive_questions_for_json(show_intro = true)
59
+ if show_intro
60
+ UI.important("You did not provide a JSON file for updating the app data usages")
61
+ UI.important("fastlane will now run you through interactive question to generate the JSON file")
62
+ UI.important("")
63
+ UI.important("This JSON file can be saved in source control and used in this action with the :json_file option")
64
+
65
+ unless UI.confirm("Ready to start?")
66
+ UI.user_error!("Cancelled")
67
+ end
68
+ end
69
+
70
+ # Fetch categories and purposes used for generating interactive questions
71
+ categories = Spaceship::ConnectAPI::AppDataUsageCategory.all(includes: "grouping")
72
+ purposes = Spaceship::ConnectAPI::AppDataUsagePurpose.all
73
+
74
+ json = []
75
+
76
+ unless UI.confirm("Are you collecting data?")
77
+ json << {
78
+ "data_protections" => [Spaceship::ConnectAPI::AppDataUsageDataProtection::ID::DATA_NOT_COLLECTED]
79
+ }
80
+
81
+ return json
82
+ end
83
+
84
+ categories.each do |category|
85
+ # Ask if using category
86
+ next unless UI.confirm("Collect data for #{category.id}?")
87
+
88
+ purpose_names = purposes.map(&:id).join(', ')
89
+ UI.message("How will this data be used? You'll be offered with #{purpose_names}")
90
+
91
+ # Ask purposes
92
+ selected_purposes = []
93
+ loop do
94
+ purposes.each do |purpose|
95
+ selected_purposes << purpose if UI.confirm("Used for #{purpose.id}?")
96
+ end
97
+
98
+ break unless selected_purposes.empty?
99
+ break unless UI.confirm("No purposes selected. Do you want to try again?")
100
+ end
101
+
102
+ # Skip asking protections if purposes were skipped
103
+ next if selected_purposes.empty?
104
+
105
+ # Ask protections
106
+ is_linked_to_user = UI.confirm("Is #{category.id} linked to the user?")
107
+ is_used_for_tracking = UI.confirm("Is #{category.id} used for tracking purposes?")
108
+
109
+ # Map answers to values for API requests
110
+ protection_id = is_linked_to_user ? Spaceship::ConnectAPI::AppDataUsageDataProtection::ID::DATA_LINKED_TO_YOU : Spaceship::ConnectAPI::AppDataUsageDataProtection::ID::DATA_NOT_LINKED_TO_YOU
111
+ tracking_id = is_used_for_tracking ? Spaceship::ConnectAPI::AppDataUsageDataProtection::ID::DATA_USED_TO_TRACK_YOU : nil
112
+
113
+ json << {
114
+ "category" => category.id,
115
+ "purposes" => selected_purposes.map(&:id).sort.uniq,
116
+ "data_protections" => [
117
+ protection_id, tracking_id
118
+ ].compact.sort.uniq
119
+ }
120
+ end
121
+
122
+ json.sort_by! { |c| c["category"] }
123
+
124
+ # Recursively call this method if no categories were selected for data collection
125
+ if json.empty?
126
+ UI.error("No categories were selected for data collection.")
127
+ json = ask_interactive_questions_for_json(false)
128
+ end
129
+
130
+ return json
131
+ end
132
+
133
+ def self.upload_app_data_usages(params, app, usages_config)
134
+ UI.message("Preparing to upload App Data Usage")
135
+
136
+ # Delete all existing usages for new ones
137
+ all_usages = Spaceship::ConnectAPI::AppDataUsage.all(app_id: app.id, includes: "category,grouping,purpose,dataProtection", limit: 500)
138
+ all_usages.each(&:delete!)
139
+
140
+ usages_config.each do |usage_config|
141
+ category = usage_config["category"]
142
+ purposes = usage_config["purposes"] || []
143
+ data_protections = usage_config["data_protections"] || []
144
+
145
+ # There will not be any purposes if "not collecting data"
146
+ # However, an AppDataUsage still needs to be created for not collecting data
147
+ # Creating an array with nil so that purposes can be iterated over and
148
+ # that AppDataUsage can be created
149
+ purposes = [nil] if purposes.empty?
150
+
151
+ purposes.each do |purpose|
152
+ data_protections.each do |data_protection|
153
+ if data_protection == Spaceship::ConnectAPI::AppDataUsageDataProtection::ID::DATA_NOT_COLLECTED
154
+ UI.message("Setting #{data_protection}")
155
+ else
156
+ UI.message("Setting #{category} and #{purpose} to #{data_protection}")
157
+ end
158
+
159
+ Spaceship::ConnectAPI::AppDataUsage.create(
160
+ app_id: app.id,
161
+ app_data_usage_category_id: category,
162
+ app_data_usage_protection_id: data_protection,
163
+ app_data_usage_purpose_id: purpose
164
+ )
165
+ end
166
+ end
167
+ end
168
+
169
+ # Publish
170
+ if params[:skip_publish]
171
+ UI.message("Skipping app data usage publishing... (so you can verify on App Store Connect)")
172
+ else
173
+ publish_state = Spaceship::ConnectAPI::AppDataUsagesPublishState.get(app_id: app.id)
174
+ if publish_state.published
175
+ UI.important("App data usage is already published")
176
+ else
177
+ UI.important("App data usage not published! Going to publish...")
178
+ publish_state.publish!
179
+ UI.important("App data usage is now published")
180
+ end
181
+ end
182
+ end
183
+
184
+ def self.description
185
+ "Upload App Privacy Details for an app in App Store Connect"
186
+ end
187
+
188
+ def self.available_options
189
+ user = CredentialsManager::AppfileConfig.try_fetch_value(:itunes_connect_id)
190
+ user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
191
+
192
+ [
193
+ FastlaneCore::ConfigItem.new(key: :username,
194
+ env_name: "FASTLANE_USER",
195
+ description: "Your Apple ID Username for App Store Connect",
196
+ default_value: user,
197
+ default_value_dynamic: true),
198
+ FastlaneCore::ConfigItem.new(key: :app_identifier,
199
+ env_name: "UPLOAD_APP_PRIVACY_DETAILS_TO_APP_STORE_APP_IDENTIFIER",
200
+ description: "The bundle identifier of your app",
201
+ code_gen_sensitive: true,
202
+ default_value: CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier),
203
+ default_value_dynamic: true),
204
+ FastlaneCore::ConfigItem.new(key: :team_id,
205
+ env_name: "FASTLANE_ITC_TEAM_ID",
206
+ description: "The ID of your App Store Connect team if you're in multiple teams",
207
+ optional: true,
208
+ is_string: false, # as we also allow integers, which we convert to strings anyway
209
+ code_gen_sensitive: true,
210
+ default_value: CredentialsManager::AppfileConfig.try_fetch_value(:itc_team_id),
211
+ default_value_dynamic: true),
212
+ FastlaneCore::ConfigItem.new(key: :team_name,
213
+ env_name: "FASTLANE_ITC_TEAM_NAME",
214
+ description: "The name of your App Store Connect team if you're in multiple teams",
215
+ optional: true,
216
+ code_gen_sensitive: true,
217
+ default_value: CredentialsManager::AppfileConfig.try_fetch_value(:itc_team_name),
218
+ default_value_dynamic: true),
219
+
220
+ # JSON paths
221
+ FastlaneCore::ConfigItem.new(key: :json_path,
222
+ env_name: "UPLOAD_APP_PRIVACY_DETAILS_TO_APP_STORE_JSON_PATH",
223
+ description: "Path to the app usage data JSON",
224
+ is_string: true,
225
+ optional: true,
226
+ verify_block: proc do |value|
227
+ UI.user_error!("Could not find JSON file at path '#{File.expand_path(value)}'") unless File.exist?(value)
228
+ UI.user_error!("'#{value}' doesn't seem to be a JSON file") unless FastlaneCore::Helper.json_file?(File.expand_path(value))
229
+ end),
230
+ FastlaneCore::ConfigItem.new(key: :output_json_path,
231
+ env_name: "UPLOAD_APP_PRIVACY_DETAILS_TO_APP_STORE_OUTPUT_JSON_PATH",
232
+ description: "Path to the app usage data JSON file generated by interactive questions",
233
+ conflicting_options: [:skip_json_file_saving],
234
+ default_value: File.join(DEFAULT_PATH, DEFAULT_FILE_NAME)),
235
+
236
+ # Skipping options
237
+ FastlaneCore::ConfigItem.new(key: :skip_json_file_saving,
238
+ env_name: "UPLOAD_APP_PRIVACY_DETAILS_TO_APP_STORE_OUTPUT_SKIP_JSON_FILE_SAVING",
239
+ description: "Whether to skip the saving of the JSON file",
240
+ conflicting_options: [:skip_output_json_path],
241
+ type: Boolean,
242
+ default_value: false),
243
+ FastlaneCore::ConfigItem.new(key: :skip_upload,
244
+ env_name: "UPLOAD_APP_PRIVACY_DETAILS_TO_APP_STORE_OUTPUT_SKIP_UPLOAD",
245
+ description: "Whether to skip the upload and only create the JSON file with interactive questions",
246
+ conflicting_options: [:skip_publish],
247
+ type: Boolean,
248
+ default_value: false),
249
+ FastlaneCore::ConfigItem.new(key: :skip_publish,
250
+ env_name: "UPLOAD_APP_PRIVACY_DETAILS_TO_APP_STORE_OUTPUT_SKIP_PUBLISH",
251
+ description: "Whether to skip the publishing",
252
+ conflicting_options: [:skip_upload],
253
+ type: Boolean,
254
+ default_value: false)
255
+ ]
256
+ end
257
+
258
+ def self.author
259
+ "joshdholtz"
260
+ end
261
+
262
+ def self.is_supported?(platform)
263
+ [:ios, :mac, :tvos].include?(platform)
264
+ end
265
+
266
+ def self.details
267
+ "Upload App Privacy Details for an app in App Store Connect. For more detail information, view https://docs.fastlane.tools/uploading-app-privacy-details"
268
+ end
269
+
270
+ def self.example_code
271
+ [
272
+ 'upload_app_privacy_details_to_app_store(
273
+ username: "your@email.com",
274
+ team_name: "Your Team",
275
+ app_identifier: "com.your.bundle"
276
+ )',
277
+ 'upload_app_privacy_details_to_app_store(
278
+ username: "your@email.com",
279
+ team_name: "Your Team",
280
+ app_identifier: "com.your.bundle",
281
+ json_path: "fastlane/app_data_usages.json"
282
+ )'
283
+ ]
284
+ end
285
+
286
+ def self.category
287
+ :production
288
+ end
289
+ end
290
+ end
291
+ end
@@ -9,9 +9,9 @@ module Fastlane
9
9
 
10
10
  begin
11
11
  config.load_configuration_file("Deliverfile")
12
- config[:screenshots_path] = Actions.lane_context[SharedValues::SNAPSHOT_SCREENSHOTS_PATH] if Actions.lane_context[SharedValues::SNAPSHOT_SCREENSHOTS_PATH]
13
- config[:ipa] = Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] if Actions.lane_context[SharedValues::IPA_OUTPUT_PATH]
14
- config[:pkg] = Actions.lane_context[SharedValues::PKG_OUTPUT_PATH] if Actions.lane_context[SharedValues::PKG_OUTPUT_PATH]
12
+ config[:screenshots_path] ||= Actions.lane_context[SharedValues::SNAPSHOT_SCREENSHOTS_PATH] if Actions.lane_context[SharedValues::SNAPSHOT_SCREENSHOTS_PATH]
13
+ config[:ipa] ||= Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] if Actions.lane_context[SharedValues::IPA_OUTPUT_PATH]
14
+ config[:pkg] ||= Actions.lane_context[SharedValues::PKG_OUTPUT_PATH] if Actions.lane_context[SharedValues::PKG_OUTPUT_PATH]
15
15
  config[:api_key] ||= Actions.lane_context[SharedValues::APP_STORE_CONNECT_API_KEY]
16
16
 
17
17
  return config if Helper.test?
@@ -17,7 +17,7 @@ module Fastlane
17
17
  if installer.installed?(params[:version])
18
18
  UI.success("Xcode #{params[:version]} is already installed ✨")
19
19
  else
20
- installer.install_version(params[:version], true, true, true, true)
20
+ installer.install_version(params[:version], true, true, true, true, nil, true, nil, params[:download_retry_attempts])
21
21
  end
22
22
 
23
23
  xcode = installer.installed_versions.find { |x| x.version == params[:version] }
@@ -49,9 +49,7 @@ module Fastlane
49
49
  [
50
50
  FastlaneCore::ConfigItem.new(key: :version,
51
51
  env_name: "FL_XCODE_VERSION",
52
- description: "The version number of the version of Xcode to install",
53
- verify_block: proc do |value|
54
- end),
52
+ description: "The version number of the version of Xcode to install"),
55
53
  FastlaneCore::ConfigItem.new(key: :username,
56
54
  short_option: "-u",
57
55
  env_name: "XCODE_INSTALL_USER",
@@ -65,7 +63,12 @@ module Fastlane
65
63
  optional: true,
66
64
  code_gen_sensitive: true,
67
65
  default_value: CredentialsManager::AppfileConfig.try_fetch_value(:team_id),
68
- default_value_dynamic: true)
66
+ default_value_dynamic: true),
67
+ FastlaneCore::ConfigItem.new(key: :download_retry_attempts,
68
+ env_name: "XCODE_INSTALL_DOWNLOAD_RETRY_ATTEMPTS",
69
+ description: "Number of times the download will be retried in case of failure",
70
+ type: Integer,
71
+ default_value: 3)
69
72
  ]
70
73
  end
71
74
 
@@ -71,6 +71,9 @@ module Fastlane
71
71
  # Disabling colors if environment variable set
72
72
  require 'fastlane_core/ui/disable_colors' if FastlaneCore::Helper.colors_disabled?
73
73
 
74
+ # Set interactive environment variable for spaceship (which can't require fastlane_core)
75
+ ENV["FASTLANE_IS_INTERACTIVE"] = FastlaneCore::UI.interactive?.to_s
76
+
74
77
  ARGV.unshift("spaceship") if ARGV.first == "spaceauth"
75
78
  tool_name = ARGV.first ? ARGV.first.downcase : nil
76
79
 
@@ -122,7 +122,7 @@ Layout/SpaceAroundOperators:
122
122
  Exclude:
123
123
  - "**/spec/actions_specs/xcodebuild_spec.rb"
124
124
  AllCops:
125
- TargetRubyVersion: 2.0
125
+ TargetRubyVersion: 2.4
126
126
  Include:
127
127
  - "*/lib/assets/*Template"
128
128
  - "*/lib/assets/*TemplateAndroid"
@@ -79,6 +79,7 @@ module Fastlane
79
79
  available_external_actions = Fastlane.external_actions || []
80
80
  available_actions = []
81
81
  ActionsList.all_actions do |action|
82
+ next unless action.respond_to?(:action_name)
82
83
  available_actions << action.action_name unless available_external_actions.include?(action)
83
84
  end
84
85
 
@@ -108,6 +109,7 @@ module Fastlane
108
109
  # Excludes all actions that aren't pluign actions (including external actions)
109
110
  available_actions = []
110
111
  ActionsList.all_actions do |action|
112
+ next unless action.respond_to?(:action_name)
111
113
  available_actions << action.action_name unless available_plugins.include?(action)
112
114
  end
113
115
 
@@ -151,6 +153,7 @@ module Fastlane
151
153
 
152
154
  tool_details = []
153
155
  ActionsList.all_actions do |action|
156
+ next unless action.respond_to?(:action_name)
154
157
  next if self.actions_not_supported.include?(action.action_name)
155
158
 
156
159
  swift_function = process_action(action: action)