fastlane 2.240.0 → 2.241.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 +4 -4
- data/README.md +57 -177
- data/bin/fastlane +4 -2
- data/credentials_manager/README.md +1 -1
- data/credentials_manager/lib/credentials_manager/account_manager.rb +6 -2
- data/deliver/lib/deliver/app_screenshot.rb +0 -4
- data/deliver/lib/deliver/commands_generator.rb +1 -1
- data/deliver/lib/deliver/detect_values.rb +3 -1
- data/deliver/lib/deliver/download_screenshots.rb +8 -1
- data/deliver/lib/deliver/sync_screenshots.rb +27 -28
- data/deliver/lib/deliver/upload_app_clip_default_experience_header_images.rb +3 -3
- data/deliver/lib/deliver/upload_metadata.rb +12 -16
- data/deliver/lib/deliver/upload_screenshots.rb +12 -14
- data/docs/README.md +25 -0
- data/fastlane/lib/assets/TeamTable.md.erb +28 -0
- data/fastlane/lib/fastlane/actions/appaloosa.rb +2 -1
- data/fastlane/lib/fastlane/actions/appium.rb +1 -1
- data/fastlane/lib/fastlane/actions/apteligent.rb +8 -1
- data/fastlane/lib/fastlane/actions/build_and_upload_to_appetize.rb +1 -1
- data/fastlane/lib/fastlane/actions/clean_build_artifacts.rb +3 -0
- data/fastlane/lib/fastlane/actions/danger.rb +5 -5
- data/fastlane/lib/fastlane/actions/docs/build_app.md +1 -2
- data/fastlane/lib/fastlane/actions/docs/create_app_online.md +1 -2
- data/fastlane/lib/fastlane/actions/docs/get_certificates.md +0 -2
- data/fastlane/lib/fastlane/actions/docs/get_push_certificate.md +1 -3
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +13 -3
- data/fastlane/lib/fastlane/actions/ensure_no_debug_code.rb +2 -2
- data/fastlane/lib/fastlane/actions/get_managed_play_store_publishing_rights.rb +1 -0
- data/fastlane/lib/fastlane/actions/github_api.rb +1 -2
- data/fastlane/lib/fastlane/actions/hg_commit_version_bump.rb +1 -1
- data/fastlane/lib/fastlane/actions/increment_build_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/increment_version_number.rb +1 -1
- data/fastlane/lib/fastlane/actions/install_xcode_plugin.rb +16 -6
- data/fastlane/lib/fastlane/actions/lcov.rb +9 -2
- data/fastlane/lib/fastlane/actions/nexus_upload.rb +16 -4
- data/fastlane/lib/fastlane/actions/notification.rb +3 -2
- data/fastlane/lib/fastlane/actions/oclint.rb +8 -8
- data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +9 -4
- data/fastlane/lib/fastlane/actions/register_device.rb +1 -1
- data/fastlane/lib/fastlane/actions/say.rb +2 -4
- data/fastlane/lib/fastlane/actions/set_pod_key.rb +3 -3
- data/fastlane/lib/fastlane/actions/sonar.rb +16 -16
- data/fastlane/lib/fastlane/actions/sourcedocs.rb +8 -8
- data/fastlane/lib/fastlane/actions/splunkmint.rb +8 -1
- data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +1 -1
- data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +5 -2
- data/fastlane/lib/fastlane/actions/upload_to_testflight.rb +5 -2
- data/fastlane/lib/fastlane/actions/verify_build.rb +1 -4
- data/fastlane/lib/fastlane/actions/verify_pod_keys.rb +3 -1
- data/fastlane/lib/fastlane/actions/xcode_server_get_assets.rb +20 -19
- data/fastlane/lib/fastlane/actions/xcodebuild.rb +5 -6
- data/fastlane/lib/fastlane/actions/zip.rb +2 -1
- data/fastlane/lib/fastlane/auto_complete.rb +1 -1
- data/fastlane/lib/fastlane/cli_tools_distributor.rb +14 -0
- data/fastlane/lib/fastlane/documentation/markdown_docs_generator.rb +23 -0
- data/fastlane/lib/fastlane/environment_printer.rb +12 -25
- data/fastlane/lib/fastlane/fast_file.rb +2 -1
- data/fastlane/lib/fastlane/fastlane_require.rb +5 -1
- data/fastlane/lib/fastlane/helper/sh_helper.rb +16 -6
- data/fastlane/lib/fastlane/new_action.rb +1 -1
- data/fastlane/lib/fastlane/plugins/plugin_fetcher.rb +1 -1
- data/fastlane/lib/fastlane/plugins/plugin_info_collector.rb +1 -1
- data/fastlane/lib/fastlane/plugins/plugin_manager.rb +36 -4
- data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +1 -1
- data/fastlane/lib/fastlane/plugins/template/.github/workflows/test.yml +1 -1
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +3 -7
- data/fastlane/lib/fastlane/swift_lane_manager.rb +22 -4
- data/fastlane/lib/fastlane/version.rb +3 -2
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/DeliverfileProtocol.swift +1 -1
- data/fastlane/swift/Fastlane.swift +55 -9
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/GymfileProtocol.swift +1 -1
- data/fastlane/swift/MainProcess.swift +190 -20
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +10 -3
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/PrecheckfileProtocol.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/ScanfileProtocol.swift +8 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/ScreengrabfileProtocol.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane/swift/SnapshotfileProtocol.swift +1 -1
- data/fastlane/swift/formatting/Rakefile +1 -0
- data/fastlane/swift/main.swift +4 -1
- data/fastlane_core/README.md +1 -1
- data/fastlane_core/lib/fastlane_core/analytics/analytics_event_builder.rb +1 -17
- data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +23 -8
- data/fastlane_core/lib/fastlane_core/device_manager.rb +2 -2
- data/fastlane_core/lib/fastlane_core/helper.rb +34 -5
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +0 -14
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +31 -28
- data/fastlane_core/lib/fastlane_core/languages.rb +0 -1
- data/fastlane_core/lib/fastlane_core/print_table.rb +5 -2
- data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +10 -19
- data/fastlane_core/lib/fastlane_core/secrets.rb +77 -0
- data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +3 -3
- data/fastlane_core/lib/fastlane_core/ui/github_issue_inspector_reporter.rb +1 -1
- data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +2 -1
- data/fastlane_core/lib/fastlane_core.rb +1 -0
- data/frameit/lib/frameit/device.rb +1 -1
- data/frameit/lib/frameit/frame_downloader.rb +2 -0
- data/frameit/lib/frameit/runner.rb +3 -2
- data/frameit/lib/frameit/screenshot.rb +0 -1
- data/gym/lib/gym/generators/build_command_generator.rb +4 -4
- data/gym/lib/gym/generators/package_command_generator_xcode7.rb +3 -3
- data/gym/lib/gym/runner.rb +1 -1
- data/internal/README.md +1 -1
- data/match/lib/match/encryption/openssl.rb +6 -2
- data/match/lib/match/generator.rb +1 -0
- data/match/lib/match/options.rb +13 -5
- data/match/lib/match/runner.rb +30 -3
- data/match/lib/match/storage/git_storage.rb +43 -7
- data/match/lib/match/storage/gitlab/secure_file.rb +2 -1
- data/match/lib/match/storage/interface.rb +8 -5
- data/pem/lib/pem/module.rb +0 -4
- data/precheck/lib/precheck/rule_processor.rb +1 -0
- data/produce/lib/produce/developer_center.rb +49 -2
- data/produce/lib/produce/itunes_connect.rb +1 -1
- data/produce/lib/produce/module.rb +21 -0
- data/produce/lib/produce/options.rb +17 -0
- data/produce/lib/produce/service.rb +3 -5
- data/produce/lib/produce.rb +0 -1
- data/scan/lib/scan/options.rb +7 -0
- data/scan/lib/scan/runner.rb +1 -1
- data/scan/lib/scan/test_command_generator.rb +12 -9
- data/scan/lib/scan/test_result_parser.rb +1 -0
- data/scan/lib/scan/xcpretty_reporter_options_generator.rb +2 -2
- data/screengrab/lib/screengrab/page.html.erb +12 -7
- data/screengrab/lib/screengrab/reports_generator.rb +1 -1
- data/sigh/lib/assets/resign.sh +17 -0
- data/sigh/lib/sigh/local_manage.rb +1 -1
- data/sigh/lib/sigh/options.rb +5 -0
- data/sigh/lib/sigh/resign.rb +3 -3
- data/sigh/lib/sigh/runner.rb +6 -1
- data/snapshot/lib/snapshot/page.html.erb +17 -12
- data/snapshot/lib/snapshot/reports_generator.rb +1 -1
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +1 -1
- data/snapshot/lib/snapshot.rb +0 -2
- data/spaceship/README.md +2 -3
- data/spaceship/lib/spaceship/base.rb +3 -1
- data/spaceship/lib/spaceship/client.rb +65 -47
- data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +13 -2
- data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +6 -0
- data/spaceship/lib/spaceship/connect_api/models/profile.rb +7 -5
- data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +25 -0
- data/spaceship/lib/spaceship/du/upload_file.rb +1 -1
- data/spaceship/lib/spaceship/errors.rb +7 -1
- data/spaceship/lib/spaceship/globals.rb +2 -2
- data/spaceship/lib/spaceship/portal/merchant.rb +127 -2
- data/spaceship/lib/spaceship/portal/portal_client.rb +58 -0
- data/spaceship/lib/spaceship/portal/ui/select_team.rb +0 -2
- data/spaceship/lib/spaceship/portal/website_push.rb +8 -2
- data/spaceship/lib/spaceship/test_flight/client.rb +0 -22
- data/spaceship/lib/spaceship/test_flight.rb +0 -1
- data/spaceship/lib/spaceship/two_step_or_factor_client.rb +11 -0
- data/supply/lib/supply/options.rb +1 -0
- data/supply/lib/supply.rb +0 -1
- metadata +75 -43
- data/produce/lib/produce/available_default_languages.rb +0 -62
- data/snapshot/lib/snapshot/screenshot_flatten.rb +0 -20
- data/snapshot/lib/snapshot/screenshot_rotate.rb +0 -36
- data/spaceship/lib/spaceship/test_flight/app_test_info.rb +0 -40
- data/supply/lib/supply/apk_listing.rb +0 -14
- /data/fastlane/lib/assets/{custom_action_template.rb → custom_action_template.rb.template} +0 -0
|
@@ -25,7 +25,7 @@ module Fastlane
|
|
|
25
25
|
UI.message("Downloading root certificate from (#{ROOT_CERTIFICATE_URL}) to path '#{params[:certificate]}'")
|
|
26
26
|
require 'open-uri'
|
|
27
27
|
File.open(params[:certificate], "w:ASCII-8BIT") do |file|
|
|
28
|
-
file.write(URI.open(
|
|
28
|
+
file.write(URI.parse(ROOT_CERTIFICATE_URL).open("rb").read)
|
|
29
29
|
end
|
|
30
30
|
end
|
|
31
31
|
|
|
@@ -10,8 +10,11 @@ module Fastlane
|
|
|
10
10
|
begin
|
|
11
11
|
config.load_configuration_file("Deliverfile")
|
|
12
12
|
config[:screenshots_path] ||= Actions.lane_context[SharedValues::SNAPSHOT_SCREENSHOTS_PATH] if Actions.lane_context[SharedValues::SNAPSHOT_SCREENSHOTS_PATH]
|
|
13
|
-
|
|
14
|
-
config
|
|
13
|
+
# The build from gym wins over the newest *.ipa/*.pkg in the current directory, the options' default
|
|
14
|
+
unless config.specified?(:ipa) || config.specified?(:pkg)
|
|
15
|
+
config[:ipa] = Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] if Actions.lane_context[SharedValues::IPA_OUTPUT_PATH]
|
|
16
|
+
config[:pkg] = Actions.lane_context[SharedValues::PKG_OUTPUT_PATH] if Actions.lane_context[SharedValues::PKG_OUTPUT_PATH]
|
|
17
|
+
end
|
|
15
18
|
|
|
16
19
|
# Only set :api_key from SharedValues if :api_key_path isn't set (conflicting options)
|
|
17
20
|
unless config[:api_key_path]
|
|
@@ -11,9 +11,12 @@ module Fastlane
|
|
|
11
11
|
values[:changelog] ||= changelog if changelog
|
|
12
12
|
|
|
13
13
|
unless distribute_only
|
|
14
|
-
|
|
14
|
+
# The build from gym wins over the newest *.ipa/*.pkg in the current directory, the options' default
|
|
15
|
+
unless values.specified?(:ipa) || values.specified?(:pkg)
|
|
16
|
+
values[:ipa] = Actions.lane_context[SharedValues::IPA_OUTPUT_PATH] if Actions.lane_context[SharedValues::IPA_OUTPUT_PATH]
|
|
17
|
+
values[:pkg] = Actions.lane_context[SharedValues::PKG_OUTPUT_PATH] if Actions.lane_context[SharedValues::PKG_OUTPUT_PATH]
|
|
18
|
+
end
|
|
15
19
|
values[:ipa] = File.expand_path(values[:ipa]) if values[:ipa]
|
|
16
|
-
values[:pkg] ||= Actions.lane_context[SharedValues::PKG_OUTPUT_PATH]
|
|
17
20
|
values[:pkg] = File.expand_path(values[:pkg]) if values[:pkg]
|
|
18
21
|
end
|
|
19
22
|
|
|
@@ -69,10 +69,7 @@ module Fastlane
|
|
|
69
69
|
provision_profile_path = "#{app_path}/embedded.mobileprovision"
|
|
70
70
|
UI.user_error!("Unable to find embedded profile in #{provision_profile_path}") unless File.exist?(provision_profile_path)
|
|
71
71
|
|
|
72
|
-
|
|
73
|
-
UI.user_error!("Unable to extract profile") unless $? == 0
|
|
74
|
-
|
|
75
|
-
plist = Plist.parse_xml(profile)
|
|
72
|
+
plist = FastlaneCore::ProvisioningProfile.parse(provision_profile_path)
|
|
76
73
|
|
|
77
74
|
values['app_name'] = plist['AppIDName']
|
|
78
75
|
values['provisioning_uuid'] = plist['UUID']
|
|
@@ -29,7 +29,9 @@ module Fastlane
|
|
|
29
29
|
end
|
|
30
30
|
|
|
31
31
|
def self.value(key, target)
|
|
32
|
-
|
|
32
|
+
command = ["pod", "keys", "get", key]
|
|
33
|
+
command << target unless target.to_s.empty?
|
|
34
|
+
value = `#{command.shelljoin}`
|
|
33
35
|
value.split("]").last.strip
|
|
34
36
|
end
|
|
35
37
|
|
|
@@ -20,12 +20,8 @@ module Fastlane
|
|
|
20
20
|
password = params[:password]
|
|
21
21
|
trust_self_signed_certs = params[:trust_self_signed_certs]
|
|
22
22
|
|
|
23
|
-
# setup (not)trusting self signed certificates.
|
|
24
23
|
# it's normal to have a self signed certificate on your Xcode Server
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
# create Xcode Server config
|
|
28
|
-
xcs = XcodeServer.new(host, username, password)
|
|
24
|
+
xcs = XcodeServer.new(host, username, password, ssl_verify_peer: !trust_self_signed_certs)
|
|
29
25
|
bots = xcs.fetch_all_bots
|
|
30
26
|
|
|
31
27
|
UI.important("Fetched #{bots.count} Bots from Xcode Server at #{host}.")
|
|
@@ -106,10 +102,11 @@ module Fastlane
|
|
|
106
102
|
end
|
|
107
103
|
|
|
108
104
|
class XcodeServer
|
|
109
|
-
def initialize(host, username, password)
|
|
105
|
+
def initialize(host, username, password, ssl_verify_peer: true)
|
|
110
106
|
@host = host.start_with?('https://') ? host : "https://#{host}"
|
|
111
107
|
@username = username
|
|
112
108
|
@password = password
|
|
109
|
+
@ssl_verify_peer = ssl_verify_peer
|
|
113
110
|
end
|
|
114
111
|
|
|
115
112
|
def fetch_all_bots
|
|
@@ -129,18 +126,18 @@ module Fastlane
|
|
|
129
126
|
# create a temp folder and a file, stream the download into it
|
|
130
127
|
Dir.mktmpdir do |dir|
|
|
131
128
|
temp_file = File.join(dir, "tmp_download.#{rand(1_000_000)}")
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
|
|
136
|
-
|
|
137
|
-
|
|
129
|
+
response = File.open(temp_file, 'w') do |f|
|
|
130
|
+
streamer = lambda do |chunk, remaining_bytes, total_bytes|
|
|
131
|
+
if remaining_bytes && total_bytes
|
|
132
|
+
UI.important("Downloading: #{100 - (100 * remaining_bytes.to_f / total_bytes.to_f).to_i}%")
|
|
133
|
+
else
|
|
134
|
+
UI.error(chunk.to_s)
|
|
135
|
+
end
|
|
136
|
+
f.write(chunk)
|
|
138
137
|
end
|
|
139
|
-
f.write(chunk)
|
|
140
|
-
end
|
|
141
138
|
|
|
142
|
-
|
|
143
|
-
|
|
139
|
+
self.get_endpoint("/integrations/#{integration_id}/assets", streamer)
|
|
140
|
+
end
|
|
144
141
|
|
|
145
142
|
UI.user_error!("Integration doesn't have any assets (it probably never ran).") if response.status == 500
|
|
146
143
|
UI.user_error!("Failed to fetch Assets zip for Integration #{integration_id} from Xcode Server at #{@host}, response: #{response.status}: #{response.body}") if response.status != 200
|
|
@@ -199,9 +196,9 @@ module Fastlane
|
|
|
199
196
|
headers = self.headers || {}
|
|
200
197
|
|
|
201
198
|
if response_block
|
|
202
|
-
response = Excon.get(url, response_block: response_block, headers: headers)
|
|
199
|
+
response = Excon.get(url, response_block: response_block, headers: headers, ssl_verify_peer: @ssl_verify_peer)
|
|
203
200
|
else
|
|
204
|
-
response = Excon.get(url, headers: headers)
|
|
201
|
+
response = Excon.get(url, headers: headers, ssl_verify_peer: @ssl_verify_peer)
|
|
205
202
|
end
|
|
206
203
|
|
|
207
204
|
return response
|
|
@@ -305,7 +302,11 @@ module Fastlane
|
|
|
305
302
|
end
|
|
306
303
|
|
|
307
304
|
def self.category
|
|
308
|
-
:
|
|
305
|
+
:deprecated
|
|
306
|
+
end
|
|
307
|
+
|
|
308
|
+
def self.deprecated_notes
|
|
309
|
+
"Xcode Server is no longer supported since Xcode 14 ([Xcode 14 Release Notes](https://developer.apple.com/documentation/xcode-release-notes/xcode-14-release-notes))."
|
|
309
310
|
end
|
|
310
311
|
end
|
|
311
312
|
end
|
|
@@ -260,7 +260,7 @@ module Fastlane
|
|
|
260
260
|
xcpretty_command = "#{xcpretty_command} --utf" if xcpretty_utf
|
|
261
261
|
end
|
|
262
262
|
|
|
263
|
-
pipe_command = "| tee
|
|
263
|
+
pipe_command = "| tee #{File.join(buildlog_path, 'xcodebuild.log').shellescape} #{xcpretty_command}"
|
|
264
264
|
|
|
265
265
|
FileUtils.mkdir_p buildlog_path
|
|
266
266
|
UI.message("For a more detailed xcodebuild log open #{buildlog_path}/xcodebuild.log")
|
|
@@ -293,7 +293,7 @@ module Fastlane
|
|
|
293
293
|
|
|
294
294
|
# If raw_buildlog and some reports had to be created, create xcpretty reports from the build log
|
|
295
295
|
if raw_buildlog && xcpretty_args.include?('--report')
|
|
296
|
-
output_result = Actions.sh "set -o pipefail && cat
|
|
296
|
+
output_result = Actions.sh "set -o pipefail && cat #{File.join(buildlog_path, 'xcodebuild.log').shellescape} | xcpretty #{xcpretty_args} > /dev/null"
|
|
297
297
|
end
|
|
298
298
|
|
|
299
299
|
output_result
|
|
@@ -349,11 +349,10 @@ module Fastlane
|
|
|
349
349
|
end.compact
|
|
350
350
|
end
|
|
351
351
|
|
|
352
|
-
#
|
|
353
|
-
#
|
|
354
|
-
# interprets these as sub-commands instead of passing value into xcodebuild
|
|
352
|
+
# Escapes what sh interprets inside double quotes, so the value reaches xcodebuild unchanged.
|
|
353
|
+
# xcodebuild expands $(VAR), ${VAR} and $VAR itself, from build settings and the environment.
|
|
355
354
|
def self.clean_build_setting_value(value)
|
|
356
|
-
value.to_s.gsub(
|
|
355
|
+
value.to_s.gsub(/[\\"$`]/) { |char| "\\#{char}" }
|
|
357
356
|
end
|
|
358
357
|
|
|
359
358
|
def self.detect_workspace
|
|
@@ -103,7 +103,8 @@ module Fastlane
|
|
|
103
103
|
FastlaneCore::ConfigItem.new(key: :password,
|
|
104
104
|
env_name: "FL_ZIP_PASSWORD",
|
|
105
105
|
description: "Encrypt the contents of the zip archive using a password",
|
|
106
|
-
optional: true
|
|
106
|
+
optional: true,
|
|
107
|
+
sensitive: true),
|
|
107
108
|
FastlaneCore::ConfigItem.new(key: :symlinks,
|
|
108
109
|
env_name: "FL_ZIP_SYMLINKS",
|
|
109
110
|
description: "Store symbolic links as such in the zip archive",
|
|
@@ -45,7 +45,7 @@ module Fastlane
|
|
|
45
45
|
custom_commands = options.custom.to_s.split(',')
|
|
46
46
|
|
|
47
47
|
Fastlane::SHELLS.each do |shell_name|
|
|
48
|
-
open("#{fastlane_conf_dir}/completions/completion.#{shell_name}", 'a') do |file|
|
|
48
|
+
File.open("#{fastlane_conf_dir}/completions/completion.#{shell_name}", 'a') do |file|
|
|
49
49
|
default_line_prefix = Helper.bundler? ? "bundle exec " : ""
|
|
50
50
|
|
|
51
51
|
file.puts(self.get_auto_complete_line(shell_name, "#{default_line_prefix}fastlane"))
|
|
@@ -53,6 +53,7 @@ module Fastlane
|
|
|
53
53
|
# We want to avoid printing output other than the version number if we are running `fastlane -v`
|
|
54
54
|
unless running_version_command? || running_init_command?
|
|
55
55
|
print_bundle_exec_warning(is_slow: (Time.now - before_import_time > 3))
|
|
56
|
+
print_running_version
|
|
56
57
|
end
|
|
57
58
|
|
|
58
59
|
# Try to check UTF-8 with `locale`, fallback to environment variables
|
|
@@ -179,6 +180,19 @@ module Fastlane
|
|
|
179
180
|
}[tool_name] || tool_name
|
|
180
181
|
end
|
|
181
182
|
|
|
183
|
+
# Which fastlane a log comes from: `fastlane env`, run later by hand, can describe another install. See #29938.
|
|
184
|
+
def print_running_version
|
|
185
|
+
source = FastlaneCore::Helper.install_method
|
|
186
|
+
if ARGV.include?("--verbose")
|
|
187
|
+
require "fastlane/environment_printer"
|
|
188
|
+
location = FastlaneCore::Helper.bundler? ? ENV["BUNDLE_GEMFILE"] : $PROGRAM_NAME
|
|
189
|
+
# Dir.home rather than ENV['HOME'], which does not match the paths Ruby gives on Windows
|
|
190
|
+
source += ": #{EnvironmentPrinter.anonymized_path(location.to_s, Dir.home)}"
|
|
191
|
+
end
|
|
192
|
+
|
|
193
|
+
UI.message("fastlane #{Fastlane::VERSION} (Ruby #{RUBY_VERSION}, #{source})")
|
|
194
|
+
end
|
|
195
|
+
|
|
182
196
|
def print_bundle_exec_warning(is_slow: false)
|
|
183
197
|
return if FastlaneCore::Helper.bundler? # user is already using bundler
|
|
184
198
|
return if FastlaneCore::Env.truthy?('SKIP_SLOW_FASTLANE_WARNING') # user disabled the warnings
|
|
@@ -193,9 +193,32 @@ module Fastlane
|
|
|
193
193
|
FileUtils.cp(current_asset_path, File.join(docs_dir, "img", "actions", File.basename(current_asset_path)))
|
|
194
194
|
end
|
|
195
195
|
|
|
196
|
+
# Generate the team table (docs/generated/team-table.md) from team.json
|
|
197
|
+
generate_team_table(docs_dir)
|
|
198
|
+
|
|
196
199
|
UI.success("Generated new docs on path #{target_path}")
|
|
197
200
|
end
|
|
198
201
|
|
|
202
|
+
def generate_team_table(docs_dir)
|
|
203
|
+
team_json_path = File.expand_path(File.join(Fastlane::ROOT, "..", "internal", "team.json"))
|
|
204
|
+
unless File.exist?(team_json_path)
|
|
205
|
+
UI.message("Skipping team table generation, could not find #{team_json_path}")
|
|
206
|
+
return
|
|
207
|
+
end
|
|
208
|
+
|
|
209
|
+
File.write(File.join(docs_dir, "generated", "team-table.md"), self.class.render_team(team_json_path))
|
|
210
|
+
end
|
|
211
|
+
|
|
212
|
+
# Also used by the `generate_team_table` rake task, so it must not depend on fastlane being loaded
|
|
213
|
+
def self.render_team(team_json_path)
|
|
214
|
+
require 'erb'
|
|
215
|
+
require 'json'
|
|
216
|
+
|
|
217
|
+
team, alumni = JSON.parse(File.read(team_json_path)).to_a.shuffle.partition { |_, user| !user['alumni'] }
|
|
218
|
+
template = File.expand_path("../../assets/TeamTable.md.erb", __dir__)
|
|
219
|
+
ERB.new(File.read(template), trim_mode: '-').result(binding)
|
|
220
|
+
end
|
|
221
|
+
|
|
199
222
|
private
|
|
200
223
|
|
|
201
224
|
def readable_category_name(category_symbol)
|
|
@@ -252,34 +252,21 @@ module Fastlane
|
|
|
252
252
|
def self.print_fastlane_files
|
|
253
253
|
env_output = "### fastlane files:\n\n"
|
|
254
254
|
|
|
255
|
-
|
|
256
|
-
|
|
257
|
-
|
|
258
|
-
|
|
259
|
-
|
|
255
|
+
{
|
|
256
|
+
"Fastfile" => FastlaneCore::FastlaneFolder.fastfile_path,
|
|
257
|
+
"Appfile" => CredentialsManager::AppfileConfig.default_path
|
|
258
|
+
}.each do |name, path|
|
|
259
|
+
if path && File.exist?(path)
|
|
260
|
+
env_output << "**#{name}** found at `#{path}`\n"
|
|
261
|
+
else
|
|
262
|
+
env_output << "**No #{name} found**\n"
|
|
263
|
+
end
|
|
260
264
|
env_output << "\n"
|
|
261
|
-
env_output << "```ruby\n"
|
|
262
|
-
env_output << File.read(fastlane_path, encoding: "utf-8")
|
|
263
|
-
env_output << "\n```\n"
|
|
264
|
-
env_output << "</details>"
|
|
265
|
-
else
|
|
266
|
-
env_output << "**No Fastfile found**\n"
|
|
267
265
|
end
|
|
268
|
-
env_output << "\n\n"
|
|
269
266
|
|
|
270
|
-
|
|
271
|
-
|
|
272
|
-
|
|
273
|
-
env_output << "<summary>`#{appfile_path}`</summary>\n"
|
|
274
|
-
env_output << "\n"
|
|
275
|
-
env_output << "```ruby\n"
|
|
276
|
-
env_output << File.read(appfile_path, encoding: "utf-8")
|
|
277
|
-
env_output << "\n```\n"
|
|
278
|
-
env_output << "</details>"
|
|
279
|
-
else
|
|
280
|
-
env_output << "**No Appfile found**\n"
|
|
281
|
-
end
|
|
282
|
-
env_output << "\n\n"
|
|
267
|
+
env_output << "The contents of these files are not included, as they may contain secrets. "
|
|
268
|
+
env_output << "If they are relevant to your issue, please add the parts that are, with any sensitive values removed.\n"
|
|
269
|
+
env_output << "\n"
|
|
283
270
|
env_output
|
|
284
271
|
end
|
|
285
272
|
|
|
@@ -314,6 +314,7 @@ module Fastlane
|
|
|
314
314
|
# it would defeat the caching's purpose.
|
|
315
315
|
command += ['--depth', '1'] unless is_eligible_for_caching
|
|
316
316
|
command += ['--branch', branch] unless branch == 'HEAD'
|
|
317
|
+
FastlaneCore::Secrets.register(git_extra_headers, name: :git_extra_headers)
|
|
317
318
|
git_extra_headers.each do |header|
|
|
318
319
|
command += ['--config', "http.extraHeader=#{header}"]
|
|
319
320
|
end
|
|
@@ -329,7 +330,7 @@ module Fastlane
|
|
|
329
330
|
# Update the repo and try again before failing
|
|
330
331
|
UI.message("Updating git repo...")
|
|
331
332
|
Helper.with_env_values('GIT_TERMINAL_PROMPT' => '0') do
|
|
332
|
-
Actions.sh("cd #{clone_folder.shellescape} && git checkout #{branch} && git reset --hard && git pull --all")
|
|
333
|
+
Actions.sh("cd #{clone_folder.shellescape} && git checkout #{branch.shellescape} && git reset --hard && git pull --all")
|
|
333
334
|
end
|
|
334
335
|
|
|
335
336
|
checkout_param = find_tag(folder: clone_folder, version: version, remote: false)
|
|
@@ -27,7 +27,11 @@ module Fastlane
|
|
|
27
27
|
UI.important("Installing Ruby gem '#{gem_name}'...")
|
|
28
28
|
|
|
29
29
|
spec_name = self.find_gem_name(gem_name)
|
|
30
|
-
|
|
30
|
+
if spec_name != gem_name
|
|
31
|
+
message = "Could not find gem '#{gem_name}' on RubyGems"
|
|
32
|
+
message += ". Did you mean '#{spec_name}'? Fix the name in your Fastfile" if spec_name
|
|
33
|
+
UI.user_error!(message)
|
|
34
|
+
end
|
|
31
35
|
|
|
32
36
|
return if Helper.test?
|
|
33
37
|
|
|
@@ -8,12 +8,13 @@ module Fastlane
|
|
|
8
8
|
# When running this in tests, it will return the actual command instead of executing it
|
|
9
9
|
# @param log [Boolean] should fastlane print out the executed command
|
|
10
10
|
# @param error_callback [Block] a callback invoked with the command output if there is a non-zero exit status
|
|
11
|
-
|
|
12
|
-
|
|
11
|
+
# @param stdin [String] data written to the command's standard input, which is then closed; it is never printed
|
|
12
|
+
def self.sh(*command, log: true, error_callback: nil, stdin: nil, &b)
|
|
13
|
+
sh_control_output(*command, print_command: log, print_command_output: log, error_callback: error_callback, stdin: stdin, &b)
|
|
13
14
|
end
|
|
14
15
|
|
|
15
|
-
def self.sh_no_action(*command, log: true, error_callback: nil, &b)
|
|
16
|
-
sh_control_output(*command, print_command: log, print_command_output: log, error_callback: error_callback, &b)
|
|
16
|
+
def self.sh_no_action(*command, log: true, error_callback: nil, stdin: nil, &b)
|
|
17
|
+
sh_control_output(*command, print_command: log, print_command_output: log, error_callback: error_callback, stdin: stdin, &b)
|
|
17
18
|
end
|
|
18
19
|
|
|
19
20
|
# @param command The command to be executed (variadic)
|
|
@@ -25,7 +26,7 @@ module Fastlane
|
|
|
25
26
|
# @yieldparam [String] result The complete output to stdout and stderr of the completed command
|
|
26
27
|
# @yieldparam [String] cmd A shell command equivalent to the arguments passed
|
|
27
28
|
# rubocop: disable Metrics/PerceivedComplexity
|
|
28
|
-
def self.sh_control_output(*command, print_command: true, print_command_output: true, error_callback: nil)
|
|
29
|
+
def self.sh_control_output(*command, print_command: true, print_command_output: true, error_callback: nil, stdin: nil)
|
|
29
30
|
print_command = print_command_output = true if $troubleshoot
|
|
30
31
|
# Set the encoding first, the user might have set it wrong
|
|
31
32
|
previous_encoding = [Encoding.default_external, Encoding.default_internal]
|
|
@@ -52,7 +53,15 @@ module Fastlane
|
|
|
52
53
|
# sh "ls", "-la", "/Applications/Xcode 7.3.1.app"
|
|
53
54
|
# sh({ "FOO" => "Hello" }, "echo $FOO")
|
|
54
55
|
sanitized_output = false
|
|
55
|
-
Open3.popen2e(*command) do |
|
|
56
|
+
Open3.popen2e(*command) do |command_stdin, io, thread|
|
|
57
|
+
# From a thread, so a command that writes a lot before reading its input cannot block on a full pipe
|
|
58
|
+
writer = stdin && Thread.new do
|
|
59
|
+
command_stdin.write(stdin)
|
|
60
|
+
rescue Errno::EPIPE
|
|
61
|
+
# The command exited without reading all of it; its exit status says what happened
|
|
62
|
+
ensure
|
|
63
|
+
command_stdin.close
|
|
64
|
+
end
|
|
56
65
|
io.sync = true
|
|
57
66
|
io.each do |line|
|
|
58
67
|
if print_command_output
|
|
@@ -64,6 +73,7 @@ module Fastlane
|
|
|
64
73
|
result << line
|
|
65
74
|
end
|
|
66
75
|
exit_status = thread.value
|
|
76
|
+
writer&.join
|
|
67
77
|
end
|
|
68
78
|
|
|
69
79
|
UI.important("Command output wasn't valid UTF-8 and was sanitized. Please report the issue.") if sanitized_output
|
|
@@ -18,7 +18,7 @@ module Fastlane
|
|
|
18
18
|
end
|
|
19
19
|
|
|
20
20
|
def self.generate_action(name)
|
|
21
|
-
template = File.read("#{Fastlane::ROOT}/lib/assets/custom_action_template.rb")
|
|
21
|
+
template = File.read("#{Fastlane::ROOT}/lib/assets/custom_action_template.rb.template")
|
|
22
22
|
template.gsub!('[[NAME]]', name)
|
|
23
23
|
template.gsub!('[[NAME_UP]]', name.upcase)
|
|
24
24
|
template.gsub!('[[NAME_CLASS]]', name.fastlane_class + 'Action')
|
|
@@ -14,7 +14,7 @@ module Fastlane
|
|
|
14
14
|
loop do
|
|
15
15
|
url = "https://rubygems.org/api/v1/search.json?query=#{PluginManager.plugin_prefix}&page=#{page}"
|
|
16
16
|
FastlaneCore::UI.verbose("RubyGems API Request: #{url}")
|
|
17
|
-
results = JSON.parse(URI.
|
|
17
|
+
results = JSON.parse(URI.parse(url).open.read)
|
|
18
18
|
break if results.count == 0
|
|
19
19
|
|
|
20
20
|
plugins += results.collect do |current|
|
|
@@ -66,6 +66,15 @@ module Fastlane
|
|
|
66
66
|
end
|
|
67
67
|
end
|
|
68
68
|
|
|
69
|
+
# Returns the fastlane plugins the given gem depends on, directly or through other gems
|
|
70
|
+
def plugins_required_by(gem_name)
|
|
71
|
+
rubygem = Bundler.rubygems.find_name(gem_name).first
|
|
72
|
+
return [] unless rubygem
|
|
73
|
+
collect_bundler_runtime_dependencies([], rubygem).map(&:name).keep_if do |current|
|
|
74
|
+
current.start_with?(self.class.plugin_prefix)
|
|
75
|
+
end
|
|
76
|
+
end
|
|
77
|
+
|
|
69
78
|
# Check if a plugin is added as dependency to either the
|
|
70
79
|
# Gemfile or the Pluginfile
|
|
71
80
|
def plugin_is_added_as_dependency?(plugin_name)
|
|
@@ -159,7 +168,7 @@ module Fastlane
|
|
|
159
168
|
require 'open-uri'
|
|
160
169
|
url = "https://rubygems.org/api/v1/gems/#{gem_name}.json"
|
|
161
170
|
begin
|
|
162
|
-
JSON.parse(URI.
|
|
171
|
+
JSON.parse(URI.parse(url).open.read)
|
|
163
172
|
rescue
|
|
164
173
|
nil
|
|
165
174
|
end
|
|
@@ -278,11 +287,12 @@ module Fastlane
|
|
|
278
287
|
# fastlane-plugin-[plugin_name]
|
|
279
288
|
# This will make sure to load the action
|
|
280
289
|
# and all its helpers
|
|
281
|
-
|
|
290
|
+
# @param plugins [Array] the plugins to load, the available plugins by default
|
|
291
|
+
def load_plugins(print_table: true, plugins: nil)
|
|
282
292
|
UI.verbose("Checking if there are any plugins that should be loaded...")
|
|
283
293
|
|
|
284
294
|
loaded_plugins = false
|
|
285
|
-
available_plugins.each do |gem_name|
|
|
295
|
+
(plugins || available_plugins).each do |gem_name|
|
|
286
296
|
UI.verbose("Loading '#{gem_name}' plugin")
|
|
287
297
|
begin
|
|
288
298
|
# BEFORE requiring the gem, we get a list of loaded actions
|
|
@@ -306,7 +316,7 @@ module Fastlane
|
|
|
306
316
|
end
|
|
307
317
|
end
|
|
308
318
|
|
|
309
|
-
if !loaded_plugins && self.pluginfile_content.to_s.include?(PluginManager.plugin_prefix)
|
|
319
|
+
if plugins.nil? && !loaded_plugins && self.pluginfile_content.to_s.include?(PluginManager.plugin_prefix)
|
|
310
320
|
UI.error("It seems like you wanted to load some plugins, however they couldn't be loaded")
|
|
311
321
|
UI.error("Please follow the troubleshooting guide: #{TROUBLESHOOTING_URL}")
|
|
312
322
|
end
|
|
@@ -317,6 +327,12 @@ module Fastlane
|
|
|
317
327
|
print_plugin_information(self.plugin_references) unless skip_print_plugin_info
|
|
318
328
|
end
|
|
319
329
|
|
|
330
|
+
# Loads the plugins the given gem depends on that are not loaded yet
|
|
331
|
+
def load_plugins_required_by(gem_name, print_table: true)
|
|
332
|
+
plugins = plugins_required_by(gem_name) - self.plugin_references.keys
|
|
333
|
+
load_plugins(print_table: print_table, plugins: plugins) unless plugins.empty?
|
|
334
|
+
end
|
|
335
|
+
|
|
320
336
|
# Prints a table all the plugins that were loaded
|
|
321
337
|
def print_plugin_information(references)
|
|
322
338
|
no_action_found = false
|
|
@@ -395,5 +411,21 @@ module Fastlane
|
|
|
395
411
|
actions: references
|
|
396
412
|
}
|
|
397
413
|
end
|
|
414
|
+
|
|
415
|
+
private
|
|
416
|
+
|
|
417
|
+
# recursively collect runtime dependencies
|
|
418
|
+
def collect_bundler_runtime_dependencies(collection, source)
|
|
419
|
+
# Compare by name: one gem can be required with different version constraints
|
|
420
|
+
known = collection.map(&:name)
|
|
421
|
+
runtime_deps = source.dependencies.select { |d| d.type == :runtime && !known.include?(d.name) }.uniq(&:name)
|
|
422
|
+
collection.concat(runtime_deps)
|
|
423
|
+
runtime_deps.each do |d|
|
|
424
|
+
collect_bundler_runtime_dependencies(collection, d.to_spec)
|
|
425
|
+
rescue Gem::MissingSpecError
|
|
426
|
+
# ignoring unresolvable dependencies
|
|
427
|
+
end
|
|
428
|
+
collection
|
|
429
|
+
end
|
|
398
430
|
end
|
|
399
431
|
end
|
|
@@ -15,7 +15,7 @@ Gem::Specification.new do |spec|
|
|
|
15
15
|
spec.files = Dir["lib/**/*"] + %w(README.md LICENSE)
|
|
16
16
|
spec.require_paths = ['lib']
|
|
17
17
|
spec.metadata['rubygems_mfa_required'] = 'true'
|
|
18
|
-
spec.required_ruby_version = '>=
|
|
18
|
+
spec.required_ruby_version = '>= <%= Fastlane::MINIMUM_RUBY %>'
|
|
19
19
|
|
|
20
20
|
# Don't add a dependency to fastlane or fastlane_re
|
|
21
21
|
# since this would cause a circular dependency
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
---
|
|
2
|
+
plugins:
|
|
3
|
+
- rubocop-performance
|
|
2
4
|
require:
|
|
3
5
|
- rubocop/require_tools
|
|
4
|
-
- rubocop-performance
|
|
5
6
|
AllCops:
|
|
6
|
-
TargetRubyVersion: 3.1
|
|
7
7
|
SuggestExtensions: false
|
|
8
8
|
NewCops: enable
|
|
9
9
|
Include:
|
|
@@ -13,11 +13,9 @@ AllCops:
|
|
|
13
13
|
- "*/lib/assets/*Template"
|
|
14
14
|
- "*/lib/assets/*TemplateAndroid"
|
|
15
15
|
Exclude:
|
|
16
|
-
- "**/lib/assets/custom_action_template.rb"
|
|
17
16
|
- "./vendor/**/*"
|
|
18
17
|
- "**/lib/assets/DefaultFastfileTemplate"
|
|
19
18
|
- "**/lib/assets/MatchfileTemplate"
|
|
20
|
-
- "**/spec/fixtures/broken_files/broken_file.rb"
|
|
21
19
|
- "**/*.provisionprofile"
|
|
22
20
|
Lint/ErbNewArguments:
|
|
23
21
|
Enabled: false
|
|
@@ -140,7 +138,7 @@ Lint/UnusedMethodArgument:
|
|
|
140
138
|
Lint/ParenthesesAsGroupedExpression:
|
|
141
139
|
Exclude:
|
|
142
140
|
- "**/spec/**/*"
|
|
143
|
-
Naming/
|
|
141
|
+
Naming/PredicatePrefix:
|
|
144
142
|
Enabled: false
|
|
145
143
|
Style/PerlBackrefs:
|
|
146
144
|
Enabled: false
|
|
@@ -149,8 +147,6 @@ Layout/SpaceAroundOperators:
|
|
|
149
147
|
- "**/spec/actions_specs/xcodebuild_spec.rb"
|
|
150
148
|
Naming/FileName:
|
|
151
149
|
Exclude:
|
|
152
|
-
- "**/Dangerfile"
|
|
153
|
-
- "**/Brewfile"
|
|
154
150
|
- "**/Gemfile"
|
|
155
151
|
- "**/Podfile"
|
|
156
152
|
- "**/Rakefile"
|
|
@@ -3,6 +3,10 @@ require_relative 'swift_runner_upgrader.rb'
|
|
|
3
3
|
|
|
4
4
|
module Fastlane
|
|
5
5
|
class SwiftLaneManager < LaneManagerBase
|
|
6
|
+
# The runner protocol version this fastlane ships, see main.swift
|
|
7
|
+
RUNNER_PROTOCOL_VERSION = 1
|
|
8
|
+
RUNNER_PROTOCOL_VERSION_REGEX = /FastlaneRunnerProtocolVersion \[(\d+)\]/
|
|
9
|
+
|
|
6
10
|
# @param lane_name The name of the lane to execute
|
|
7
11
|
# @param parameters [Hash] The parameters passed from the command line to the lane
|
|
8
12
|
def self.cruise_lane(lane, parameters = nil, disable_runner_upgrades: false, swift_server_port: nil)
|
|
@@ -26,6 +30,7 @@ module Fastlane
|
|
|
26
30
|
end
|
|
27
31
|
|
|
28
32
|
self.ensure_runner_built!
|
|
33
|
+
self.warn_if_runner_outdated
|
|
29
34
|
swift_server_port ||= 2000
|
|
30
35
|
socket_thread = self.start_socket_thread(port: swift_server_port)
|
|
31
36
|
sleep(0.250) while socket_thread[:ready].nil?
|
|
@@ -229,6 +234,17 @@ module Fastlane
|
|
|
229
234
|
end
|
|
230
235
|
end
|
|
231
236
|
|
|
237
|
+
# The protocol version compiled into the built runner, 0 for runners from before it had one
|
|
238
|
+
def self.runner_protocol_version
|
|
239
|
+
File.binread(FastlaneCore::FastlaneFolder.swift_runner_path)[RUNNER_PROTOCOL_VERSION_REGEX, 1].to_i
|
|
240
|
+
end
|
|
241
|
+
|
|
242
|
+
def self.warn_if_runner_outdated
|
|
243
|
+
return if runner_protocol_version >= RUNNER_PROTOCOL_VERSION
|
|
244
|
+
|
|
245
|
+
UI.important("Your FastlaneRunner is outdated for this version of fastlane. Run a lane outside CI, without `disable_runner_upgrades`, to update it, then commit the changes.")
|
|
246
|
+
end
|
|
247
|
+
|
|
232
248
|
def self.ensure_runner_built!
|
|
233
249
|
UI.verbose("Checking for new user-provided tool configuration files")
|
|
234
250
|
# if self.link_user_configs_to_project returns true, that means we need to rebuild the runner
|
|
@@ -236,11 +252,13 @@ module Fastlane
|
|
|
236
252
|
|
|
237
253
|
if FastlaneCore::FastlaneFolder.swift_runner_built?
|
|
238
254
|
runner_last_modified_age = File.mtime(FastlaneCore::FastlaneFolder.swift_runner_path).to_i
|
|
239
|
-
|
|
255
|
+
# The Fastfile, and the runner's own files, which an upgrade or a pull can change without touching the Fastfile
|
|
256
|
+
sources = [FastlaneCore::FastlaneFolder.fastfile_path] + Dir[File.join(FastlaneCore::FastlaneFolder.swift_folder_path, '**', '*.swift')]
|
|
257
|
+
changed = sources.find { |source| File.mtime(source).to_i > runner_last_modified_age }
|
|
240
258
|
|
|
241
|
-
if
|
|
242
|
-
# It's older than
|
|
243
|
-
UI.verbose("Found changes to
|
|
259
|
+
if changed
|
|
260
|
+
# It's older than one of its sources, so build it again
|
|
261
|
+
UI.verbose("Found changes to #{changed}, setting re-build runner flag")
|
|
244
262
|
runner_needs_building = true
|
|
245
263
|
end
|
|
246
264
|
else
|
|
@@ -1,8 +1,9 @@
|
|
|
1
1
|
module Fastlane
|
|
2
|
-
VERSION = '2.
|
|
2
|
+
VERSION = '2.241.0'.freeze
|
|
3
3
|
SUMMARY = "The easiest way to build and release mobile apps.".freeze
|
|
4
4
|
DESCRIPTION = "The easiest way to automate beta deployments and releases for your iOS and Android apps".freeze
|
|
5
5
|
MINIMUM_XCODE_RELEASE = "7.0".freeze
|
|
6
|
-
RUBOCOP_REQUIREMENT = '1.
|
|
6
|
+
RUBOCOP_REQUIREMENT = '1.91.0'.freeze
|
|
7
|
+
MINIMUM_RUBY = '3.2.0'.freeze
|
|
7
8
|
SUGGESTED_MINIMUM_RUBY = '3.3.0'.freeze
|
|
8
9
|
end
|