fastlane 2.196.0 → 2.212.2
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/LICENSE +1 -1
- data/README.md +88 -81
- data/cert/lib/cert/runner.rb +19 -8
- data/deliver/lib/assets/ScreenshotsHelp +29 -6
- data/deliver/lib/deliver/app_screenshot.rb +30 -4
- data/deliver/lib/deliver/app_screenshot_iterator.rb +1 -1
- data/deliver/lib/deliver/options.rb +6 -2
- data/deliver/lib/deliver/runner.rb +88 -24
- data/deliver/lib/deliver/submit_for_review.rb +25 -3
- data/deliver/lib/deliver/upload_price_tier.rb +3 -1
- data/deliver/lib/deliver/upload_screenshots.rb +2 -2
- data/fastlane/lib/assets/AppfileTemplate +1 -1
- data/fastlane/lib/assets/AppfileTemplate.swift +1 -1
- data/fastlane/lib/fastlane/actions/badge.rb +1 -1
- data/fastlane/lib/fastlane/actions/changelog_from_git_commits.rb +1 -1
- data/fastlane/lib/fastlane/actions/danger.rb +14 -0
- data/fastlane/lib/fastlane/actions/docs/build_app.md +5 -5
- data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +19 -2
- data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/run_tests.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +1 -1
- data/fastlane/lib/fastlane/actions/download_dsyms.rb +62 -46
- data/fastlane/lib/fastlane/actions/ensure_git_status_clean.rb +15 -4
- data/fastlane/lib/fastlane/actions/ensure_xcode_version.rb +1 -1
- data/fastlane/lib/fastlane/actions/get_push_certificate.rb +1 -1
- data/fastlane/lib/fastlane/actions/get_version_number.rb +8 -3
- data/fastlane/lib/fastlane/actions/git_commit.rb +4 -6
- data/fastlane/lib/fastlane/actions/import_certificate.rb +1 -1
- data/fastlane/lib/fastlane/actions/notarize.rb +29 -11
- data/fastlane/lib/fastlane/actions/pod_lib_lint.rb +1 -1
- data/fastlane/lib/fastlane/actions/pod_push.rb +19 -1
- data/fastlane/lib/fastlane/actions/read_podspec.rb +1 -1
- data/fastlane/lib/fastlane/actions/run_tests.rb +19 -9
- data/fastlane/lib/fastlane/actions/set_github_release.rb +11 -5
- data/fastlane/lib/fastlane/actions/setup_ci.rb +13 -4
- data/fastlane/lib/fastlane/actions/trainer.rb +49 -0
- data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +31 -4
- data/fastlane/lib/fastlane/actions/update_info_plist.rb +1 -1
- data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +10 -1
- data/fastlane/lib/fastlane/actions/upload_symbols_to_sentry.rb +1 -1
- data/fastlane/lib/fastlane/actions/verify_build.rb +1 -1
- data/fastlane/lib/fastlane/actions/xcode_install.rb +5 -1
- data/fastlane/lib/fastlane/actions/xcode_select.rb +1 -1
- data/fastlane/lib/fastlane/actions/xcodebuild.rb +8 -2
- data/fastlane/lib/fastlane/actions/xcodes.rb +152 -0
- data/fastlane/lib/fastlane/actions/xcov.rb +5 -0
- data/fastlane/lib/fastlane/actions/xcversion.rb +17 -7
- data/fastlane/lib/fastlane/cli_tools_distributor.rb +5 -0
- data/fastlane/lib/fastlane/commands_generator.rb +2 -1
- data/fastlane/lib/fastlane/documentation/docs_generator.rb +17 -12
- data/fastlane/lib/fastlane/fast_file.rb +18 -5
- data/fastlane/lib/fastlane/features.rb +3 -0
- data/fastlane/lib/fastlane/helper/xcodebuild_formatter_helper.rb +9 -0
- data/fastlane/lib/fastlane/helper/xcodes_helper.rb +28 -0
- data/fastlane/lib/fastlane/helper/xcversion_helper.rb +0 -9
- data/fastlane/lib/fastlane/lane_manager.rb +1 -1
- data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +1 -1
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +5 -1
- data/fastlane/lib/fastlane/setup/setup_ios.rb +1 -1
- data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +1 -1
- data/fastlane/lib/fastlane/swift_lane_manager.rb +11 -3
- data/fastlane/lib/fastlane/swift_runner_upgrader.rb +54 -1
- data/fastlane/lib/fastlane/tools.rb +18 -1
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Actions.swift +1 -1
- data/fastlane/swift/Appfile.swift +2 -2
- data/fastlane/swift/ArgumentProcessor.swift +1 -1
- data/fastlane/swift/Atomic.swift +150 -0
- data/fastlane/swift/ControlCommand.swift +1 -1
- data/fastlane/swift/Deliverfile.swift +2 -2
- data/fastlane/swift/DeliverfileProtocol.swift +8 -4
- data/fastlane/swift/Fastlane.swift +570 -239
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +30 -20
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/xcshareddata/xcschemes/FastlaneRunner.xcscheme +1 -1
- data/fastlane/swift/Gymfile.swift +2 -2
- data/fastlane/swift/GymfileProtocol.swift +20 -8
- data/fastlane/swift/LaneFileProtocol.swift +2 -2
- data/fastlane/swift/MainProcess.swift +3 -3
- data/fastlane/swift/Matchfile.swift +2 -2
- data/fastlane/swift/MatchfileProtocol.swift +21 -5
- data/fastlane/swift/OptionalConfigValue.swift +1 -1
- data/fastlane/swift/Plugins.swift +1 -1
- data/fastlane/swift/Precheckfile.swift +2 -2
- data/fastlane/swift/PrecheckfileProtocol.swift +3 -3
- data/fastlane/swift/RubyCommand.swift +1 -1
- data/fastlane/swift/RubyCommandable.swift +1 -1
- data/fastlane/swift/Runner.swift +13 -9
- data/fastlane/swift/RunnerArgument.swift +1 -1
- data/fastlane/swift/Scanfile.swift +2 -2
- data/fastlane/swift/ScanfileProtocol.swift +31 -11
- data/fastlane/swift/Screengrabfile.swift +2 -2
- data/fastlane/swift/ScreengrabfileProtocol.swift +3 -3
- data/fastlane/swift/Snapshotfile.swift +2 -2
- data/fastlane/swift/SnapshotfileProtocol.swift +12 -8
- data/fastlane/swift/SocketClient.swift +9 -5
- data/fastlane/swift/SocketClientDelegateProtocol.swift +2 -2
- data/fastlane/swift/SocketResponse.swift +1 -1
- data/fastlane/swift/formatting/Brewfile.lock.json +46 -23
- data/fastlane/swift/main.swift +1 -1
- data/fastlane/swift/upgrade_manifest.json +1 -1
- data/fastlane_core/README.md +1 -0
- data/fastlane_core/lib/fastlane_core/cert_checker.rb +79 -17
- data/fastlane_core/lib/fastlane_core/device_manager.rb +5 -1
- data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +10 -5
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +409 -26
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +1 -0
- data/fastlane_core/lib/fastlane_core/project.rb +19 -2
- data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +7 -0
- data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +4 -2
- data/frameit/lib/frameit/device.rb +1 -1
- data/frameit/lib/frameit/device_types.rb +9 -0
- data/frameit/lib/frameit/editor.rb +16 -18
- data/frameit/lib/frameit/frame_downloader.rb +1 -1
- data/frameit/lib/frameit/trim_box.rb +6 -0
- data/gym/lib/gym/generators/build_command_generator.rb +70 -23
- data/gym/lib/gym/options.rb +30 -5
- data/match/lib/match/change_password.rb +2 -0
- data/match/lib/match/commands_generator.rb +2 -1
- data/match/lib/match/encryption/openssl.rb +1 -1
- data/match/lib/match/encryption.rb +3 -0
- data/match/lib/match/generator.rb +1 -0
- data/match/lib/match/importer.rb +10 -1
- data/match/lib/match/migrate.rb +4 -3
- data/match/lib/match/module.rb +54 -2
- data/match/lib/match/nuke.rb +114 -47
- data/match/lib/match/options.rb +22 -1
- data/match/lib/match/runner.rb +25 -6
- data/match/lib/match/setup.rb +1 -1
- data/match/lib/match/spaceship_ensure.rb +5 -2
- data/match/lib/match/storage/gitlab/client.rb +102 -0
- data/match/lib/match/storage/gitlab/secure_file.rb +65 -0
- data/match/lib/match/storage/gitlab_secure_files.rb +182 -0
- data/match/lib/match/storage/google_cloud_storage.rb +7 -6
- data/match/lib/match/storage/s3_storage.rb +3 -3
- data/match/lib/match/storage.rb +4 -0
- data/match/lib/match/table_printer.rb +2 -1
- data/match/lib/match/utils.rb +15 -2
- data/pem/lib/pem/manager.rb +30 -7
- data/pem/lib/pem/options.rb +9 -0
- data/pilot/lib/pilot/build_manager.rb +34 -14
- data/pilot/lib/pilot/options.rb +6 -1
- data/scan/lib/scan/detect_values.rb +6 -0
- data/scan/lib/scan/error_handler.rb +9 -0
- data/scan/lib/scan/options.rb +49 -9
- data/scan/lib/scan/runner.rb +171 -25
- data/scan/lib/scan/test_command_generator.rb +65 -5
- data/sigh/lib/sigh/download_all.rb +14 -2
- data/sigh/lib/sigh/module.rb +3 -1
- data/sigh/lib/sigh/options.rb +5 -0
- data/sigh/lib/sigh/runner.rb +12 -2
- data/snapshot/lib/assets/SnapshotHelper.swift +3 -3
- data/snapshot/lib/snapshot/latest_os_version.rb +2 -5
- data/snapshot/lib/snapshot/options.rb +24 -8
- data/snapshot/lib/snapshot/reports_generator.rb +1 -0
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +10 -3
- data/snapshot/lib/snapshot/test_command_generator.rb +37 -2
- data/spaceship/lib/spaceship/client.rb +71 -40
- data/spaceship/lib/spaceship/commands_generator.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/api_client.rb +10 -5
- data/spaceship/lib/spaceship/connect_api/models/actor.rb +26 -0
- data/spaceship/lib/spaceship/connect_api/models/app.rb +52 -6
- data/spaceship/lib/spaceship/connect_api/models/app_info.rb +1 -0
- data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +7 -0
- data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +27 -10
- data/spaceship/lib/spaceship/connect_api/models/build.rb +4 -2
- data/spaceship/lib/spaceship/connect_api/models/build_bundle.rb +68 -0
- data/spaceship/lib/spaceship/connect_api/models/build_bundle_file_sizes.rb +34 -0
- data/spaceship/lib/spaceship/connect_api/models/build_delivery.rb +2 -1
- data/spaceship/lib/spaceship/connect_api/models/certificate.rb +4 -0
- data/spaceship/lib/spaceship/connect_api/models/device.rb +47 -4
- data/spaceship/lib/spaceship/connect_api/models/profile.rb +4 -0
- data/spaceship/lib/spaceship/connect_api/models/resolution_center_message.rb +29 -0
- data/spaceship/lib/spaceship/connect_api/models/resolution_center_thread.rb +67 -0
- data/spaceship/lib/spaceship/connect_api/models/review_rejection.rb +19 -0
- data/spaceship/lib/spaceship/connect_api/models/review_submission.rb +86 -0
- data/spaceship/lib/spaceship/connect_api/models/review_submission_item.rb +40 -0
- data/spaceship/lib/spaceship/connect_api/models/user.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +19 -0
- data/spaceship/lib/spaceship/connect_api/response.rb +23 -6
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +33 -2
- data/spaceship/lib/spaceship/connect_api/token.rb +5 -2
- data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +124 -8
- data/spaceship/lib/spaceship/connect_api.rb +9 -0
- data/spaceship/lib/spaceship/errors.rb +34 -0
- data/spaceship/lib/spaceship/globals.rb +9 -0
- data/spaceship/lib/spaceship/hashcash.rb +52 -0
- data/spaceship/lib/spaceship/portal/certificate.rb +4 -3
- data/spaceship/lib/spaceship/spaceauth_runner.rb +1 -1
- data/spaceship/lib/spaceship/tunes/app_ratings.rb +6 -6
- data/spaceship/lib/spaceship/tunes/iap_families.rb +1 -1
- data/spaceship/lib/spaceship/tunes/tunes.rb +0 -1
- data/spaceship/lib/spaceship/tunes/tunes_client.rb +79 -21
- data/spaceship/lib/spaceship/two_step_or_factor_client.rb +11 -3
- data/spaceship/lib/spaceship.rb +1 -0
- data/supply/lib/supply/client.rb +2 -7
- data/supply/lib/supply/options.rb +8 -0
- data/supply/lib/supply/uploader.rb +6 -2
- data/trainer/lib/assets/junit.xml.erb +28 -0
- data/trainer/lib/trainer/commands_generator.rb +51 -0
- data/trainer/lib/trainer/junit_generator.rb +31 -0
- data/trainer/lib/trainer/module.rb +10 -0
- data/trainer/lib/trainer/options.rb +66 -0
- data/trainer/lib/trainer/test_parser.rb +398 -0
- data/trainer/lib/trainer/xcresult.rb +403 -0
- data/trainer/lib/trainer.rb +7 -0
- metadata +49 -24
- data/spaceship/lib/spaceship/connect_api/testflight/.testflight.rb.swp +0 -0
- data/spaceship/lib/spaceship/tunes/user_detail.rb +0 -15
@@ -12,11 +12,18 @@ module Fastlane
|
|
12
12
|
require 'net/http'
|
13
13
|
require 'date'
|
14
14
|
|
15
|
-
|
16
|
-
|
17
|
-
|
18
|
-
Spaceship::ConnectAPI.
|
19
|
-
|
15
|
+
if (api_token = Spaceship::ConnectAPI::Token.from(hash: params[:api_key], filepath: params[:api_key_path]))
|
16
|
+
UI.message("Creating authorization token for App Store Connect API")
|
17
|
+
Spaceship::ConnectAPI.token = api_token
|
18
|
+
elsif !Spaceship::ConnectAPI.token.nil?
|
19
|
+
UI.message("Using existing authorization token for App Store Connect API")
|
20
|
+
else
|
21
|
+
# Team selection passed though FASTLANE_ITC_TEAM_ID and FASTLANE_ITC_TEAM_NAME environment variables
|
22
|
+
# Prompts select team if multiple teams and none specified
|
23
|
+
UI.message("Login to App Store Connect (#{params[:username]})")
|
24
|
+
Spaceship::ConnectAPI.login(params[:username], use_portal: false, use_tunes: true)
|
25
|
+
UI.message("Login successful")
|
26
|
+
end
|
20
27
|
|
21
28
|
# Get App
|
22
29
|
app = Spaceship::ConnectAPI::App.find(params[:app_identifier])
|
@@ -68,10 +75,11 @@ module Fastlane
|
|
68
75
|
|
69
76
|
filter = { app: app.id }
|
70
77
|
filter["preReleaseVersion.platform"] = platform
|
71
|
-
|
72
|
-
|
78
|
+
filter["preReleaseVersion.version"] = version if version
|
79
|
+
filter["version"] = build_number if build_number
|
80
|
+
build_resp = Spaceship::ConnectAPI.get_builds(filter: filter, sort: "-uploadedDate", includes: "preReleaseVersion,buildBundles")
|
73
81
|
|
74
|
-
|
82
|
+
build_resp.all_pages_each do |build|
|
75
83
|
asc_app_version = build.app_version
|
76
84
|
asc_build_number = build.version
|
77
85
|
uploaded_date = DateTime.parse(build.uploaded_date)
|
@@ -93,7 +101,7 @@ module Fastlane
|
|
93
101
|
|
94
102
|
if after_uploaded_date && after_uploaded_date >= uploaded_date
|
95
103
|
UI.verbose("Upload date #{after_uploaded_date} not reached: #{uploaded_date}")
|
96
|
-
|
104
|
+
break
|
97
105
|
end
|
98
106
|
|
99
107
|
message = []
|
@@ -107,46 +115,37 @@ module Fastlane
|
|
107
115
|
end
|
108
116
|
|
109
117
|
UI.verbose("Build_version: #{asc_build_number} matches #{build_number}, grabbing dsym_url") if build_number
|
110
|
-
|
118
|
+
download_dsym(build: build, app: app, wait_for_dsym_processing: wait_for_dsym_processing, wait_timeout: wait_timeout, output_directory: output_directory)
|
111
119
|
end
|
112
120
|
end
|
113
121
|
|
114
|
-
def self.
|
122
|
+
def self.download_dsym(build: nil, app: nil, wait_for_dsym_processing: nil, wait_timeout: nil, output_directory: nil)
|
115
123
|
start = Time.now
|
116
|
-
|
124
|
+
dsym_urls = []
|
117
125
|
|
118
126
|
loop do
|
119
|
-
|
120
|
-
|
121
|
-
|
122
|
-
|
123
|
-
|
124
|
-
|
125
|
-
|
126
|
-
UI.
|
127
|
-
|
128
|
-
|
129
|
-
|
130
|
-
|
131
|
-
|
132
|
-
if !wait_for_dsym_processing || (Time.now - start) > wait_timeout
|
133
|
-
# In some cases, AppStoreConnect does not process the dSYMs, thus no error should be thrown.
|
134
|
-
UI.message("Could not find any dSYM for #{build_number} (#{train})")
|
135
|
-
else
|
136
|
-
UI.message("Waiting for dSYM file to appear...")
|
137
|
-
sleep(30)
|
138
|
-
next
|
139
|
-
end
|
127
|
+
build_bundles = build.build_bundles.select { |b| b.includes_symbols == true }
|
128
|
+
dsym_urls = build_bundles.map(&:dsym_url).compact
|
129
|
+
|
130
|
+
break if build_bundles.count == dsym_urls.count
|
131
|
+
|
132
|
+
if !wait_for_dsym_processing || (Time.now - start) > wait_timeout
|
133
|
+
# In some cases, AppStoreConnect does not process the dSYMs, thus no error should be thrown.
|
134
|
+
UI.message("Could not find any dSYM for #{build.version} (#{build.app_version})")
|
135
|
+
break
|
136
|
+
else
|
137
|
+
UI.message("Waiting for dSYM file to appear...")
|
138
|
+
sleep(30) unless FastlaneCore::Helper.is_test?
|
139
|
+
build = Spaceship::ConnectAPI::Build.get(build_id: build.id)
|
140
140
|
end
|
141
|
-
|
142
|
-
break
|
143
141
|
end
|
144
142
|
|
145
|
-
if
|
146
|
-
|
147
|
-
return if build_number
|
143
|
+
if dsym_urls.count == 0
|
144
|
+
UI.message("No dSYM URL for #{build.version} (#{build.app_version})")
|
148
145
|
else
|
149
|
-
|
146
|
+
dsym_urls.each do |url|
|
147
|
+
self.download(url, build, app, output_directory)
|
148
|
+
end
|
150
149
|
end
|
151
150
|
end
|
152
151
|
# rubocop:enable Metrics/PerceivedComplexity
|
@@ -154,7 +153,7 @@ module Fastlane
|
|
154
153
|
def self.get_latest_build!(app_id: nil, platform: nil)
|
155
154
|
filter = { app: app_id }
|
156
155
|
filter["preReleaseVersion.platform"] = platform
|
157
|
-
latest_build = Spaceship::ConnectAPI.get_builds(filter: filter, sort: "-uploadedDate", includes: "preReleaseVersion").first
|
156
|
+
latest_build = Spaceship::ConnectAPI.get_builds(filter: filter, sort: "-uploadedDate", includes: "preReleaseVersion,buildBundles").first
|
158
157
|
|
159
158
|
if latest_build.nil?
|
160
159
|
UI.user_error!("Could not find any build for platform #{platform}") if platform
|
@@ -164,18 +163,18 @@ module Fastlane
|
|
164
163
|
return latest_build
|
165
164
|
end
|
166
165
|
|
167
|
-
def self.download(download_url,
|
166
|
+
def self.download(download_url, build, app, output_directory)
|
168
167
|
result = self.download_file(download_url)
|
169
|
-
path = write_dsym(result, bundle_id,
|
170
|
-
UI.success("🔑 Successfully downloaded dSYM file for #{
|
168
|
+
path = write_dsym(result, app.bundle_id, build.app_version, build.version, output_directory)
|
169
|
+
UI.success("🔑 Successfully downloaded dSYM file for #{build.app_version} - #{build.version} to '#{path}'")
|
171
170
|
|
172
171
|
Actions.lane_context[SharedValues::DSYM_PATHS] ||= []
|
173
172
|
Actions.lane_context[SharedValues::DSYM_PATHS] << File.expand_path(path)
|
174
173
|
|
175
|
-
unless uploaded_date.nil?
|
176
|
-
Actions.lane_context[SharedValues::DSYM_LATEST_UPLOADED_DATE] ||= uploaded_date
|
174
|
+
unless build.uploaded_date.nil?
|
175
|
+
Actions.lane_context[SharedValues::DSYM_LATEST_UPLOADED_DATE] ||= build.uploaded_date
|
177
176
|
current_latest = Actions.lane_context[SharedValues::DSYM_LATEST_UPLOADED_DATE]
|
178
|
-
Actions.lane_context[SharedValues::DSYM_LATEST_UPLOADED_DATE] = [current_latest, uploaded_date].max
|
177
|
+
Actions.lane_context[SharedValues::DSYM_LATEST_UPLOADED_DATE] = [current_latest, build.uploaded_date].max
|
179
178
|
UI.verbose("Most recent build uploaded_date #{Actions.lane_context[SharedValues::DSYM_LATEST_UPLOADED_DATE]}")
|
180
179
|
end
|
181
180
|
end
|
@@ -234,6 +233,23 @@ module Fastlane
|
|
234
233
|
user ||= CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
|
235
234
|
|
236
235
|
[
|
236
|
+
FastlaneCore::ConfigItem.new(key: :api_key_path,
|
237
|
+
env_names: ["DOWNLOAD_DSYMS_API_KEY_PATH", "APP_STORE_CONNECT_API_KEY_PATH"],
|
238
|
+
description: "Path to your App Store Connect API Key JSON file (https://docs.fastlane.tools/app-store-connect-api/#using-fastlane-api-key-json-file)",
|
239
|
+
optional: true,
|
240
|
+
conflicting_options: [:api_key],
|
241
|
+
verify_block: proc do |value|
|
242
|
+
UI.user_error!("Couldn't find API key JSON file at path '#{value}'") unless File.exist?(value)
|
243
|
+
end),
|
244
|
+
FastlaneCore::ConfigItem.new(key: :api_key,
|
245
|
+
env_names: ["DOWNLOAD_DSYMS_API_KEY", "APP_STORE_CONNECT_API_KEY"],
|
246
|
+
description: "Your App Store Connect API Key information (https://docs.fastlane.tools/app-store-connect-api/#use-return-value-and-pass-in-as-an-option)",
|
247
|
+
type: Hash,
|
248
|
+
default_value: Fastlane::Actions.lane_context[Fastlane::Actions::SharedValues::APP_STORE_CONNECT_API_KEY],
|
249
|
+
default_value_dynamic: true,
|
250
|
+
optional: true,
|
251
|
+
sensitive: true,
|
252
|
+
conflicting_options: [:api_key_path]),
|
237
253
|
FastlaneCore::ConfigItem.new(key: :username,
|
238
254
|
short_option: "-u",
|
239
255
|
env_name: "DOWNLOAD_DSYMS_USERNAME",
|
@@ -8,8 +8,9 @@ module Fastlane
|
|
8
8
|
class EnsureGitStatusCleanAction < Action
|
9
9
|
def self.run(params)
|
10
10
|
if params[:ignored]
|
11
|
-
|
12
|
-
|
11
|
+
ignored_mode = params[:ignored]
|
12
|
+
ignored_mode = 'no' if ignored_mode == 'none'
|
13
|
+
repo_status = Actions.sh("git status --porcelain --ignored='#{ignored_mode}'")
|
13
14
|
else
|
14
15
|
repo_status = Actions.sh("git status --porcelain")
|
15
16
|
end
|
@@ -74,8 +75,18 @@ module Fastlane
|
|
74
75
|
type: Boolean),
|
75
76
|
FastlaneCore::ConfigItem.new(key: :ignored,
|
76
77
|
env_name: "FL_ENSURE_GIT_STATUS_CLEAN_IGNORED_FILE",
|
77
|
-
description:
|
78
|
-
|
78
|
+
description: [
|
79
|
+
"The handling mode of the ignored files. The available options are: `'traditional'`, `'none'` (default) and `'matching'`.",
|
80
|
+
"Specifying `'none'` to this parameter is the same as not specifying the parameter at all, which means that no ignored file will be used to check if the repo is dirty or not.",
|
81
|
+
"Specifying `'traditional'` or `'matching'` causes some ignored files to be used to check if the repo is dirty or not (more info in the official docs: https://git-scm.com/docs/git-status#Documentation/git-status.txt---ignoredltmodegt)"
|
82
|
+
].join(" "),
|
83
|
+
optional: true,
|
84
|
+
verify_block: proc do |value|
|
85
|
+
mode = value.to_s
|
86
|
+
modes = %w(traditional none matching)
|
87
|
+
|
88
|
+
UI.user_error!("Unsupported mode, must be: #{modes}") unless modes.include?(mode)
|
89
|
+
end)
|
79
90
|
]
|
80
91
|
end
|
81
92
|
|
@@ -75,7 +75,7 @@ module Fastlane
|
|
75
75
|
[
|
76
76
|
"If building your app requires a specific version of Xcode, you can invoke this command before using gym.",
|
77
77
|
"For example, to ensure that a beta version of Xcode is not accidentally selected to build, which would make uploading to TestFlight fail.",
|
78
|
-
"You can either manually provide a specific version using `version
|
78
|
+
"You can either manually provide a specific version using `version:` or you make use of the `.xcode-version` file.",
|
79
79
|
"Using the `strict` parameter, you can either verify the full set of version numbers strictly (i.e. `11.3.1`) or only a subset of them (i.e. `11.3` or `11`)."
|
80
80
|
].join("\n")
|
81
81
|
end
|
@@ -109,8 +109,10 @@ module Fastlane
|
|
109
109
|
options = plist_files.keys
|
110
110
|
selected = UI.select("What build configuration would you like to use?", options)
|
111
111
|
plist_file = plist_files[selected]
|
112
|
-
|
112
|
+
elsif plist_files_count > 0
|
113
113
|
plist_file = plist_files.values.first
|
114
|
+
else
|
115
|
+
return nil
|
114
116
|
end
|
115
117
|
|
116
118
|
# $(SRCROOT) is the path of where the XcodeProject is
|
@@ -131,9 +133,12 @@ module Fastlane
|
|
131
133
|
end
|
132
134
|
|
133
135
|
def self.get_version_number_from_plist!(plist_file)
|
136
|
+
return '$(MARKETING_VERSION)' if plist_file.nil?
|
137
|
+
|
134
138
|
plist = Xcodeproj::Plist.read_from_path(plist_file)
|
135
139
|
UI.user_error!("Unable to read plist: #{plist_file}") unless plist
|
136
140
|
|
141
|
+
return '${MARKETING_VERSION}' if plist["CFBundleShortVersionString"].nil?
|
137
142
|
plist["CFBundleShortVersionString"]
|
138
143
|
end
|
139
144
|
|
@@ -146,14 +151,14 @@ module Fastlane
|
|
146
151
|
end
|
147
152
|
|
148
153
|
def self.details
|
149
|
-
"This action will return the current version number set on your project."
|
154
|
+
"This action will return the current version number set on your project. It first looks in the plist and then for '$(MARKETING_VERSION)' in the build settings."
|
150
155
|
end
|
151
156
|
|
152
157
|
def self.available_options
|
153
158
|
[
|
154
159
|
FastlaneCore::ConfigItem.new(key: :xcodeproj,
|
155
160
|
env_name: "FL_VERSION_NUMBER_PROJECT",
|
156
|
-
description: "Path to the Xcode project to read version number from, or its containing directory, optional. If
|
161
|
+
description: "Path to the Xcode project to read version number from, or its containing directory, optional. If omitted, or if a directory is passed instead, it will use the first Xcode project found within the given directory, or the project root directory if none is passed",
|
157
162
|
optional: true,
|
158
163
|
verify_block: proc do |value|
|
159
164
|
UI.user_error!("Please pass the path to the project or its containing directory, not the workspace path") if value.end_with?(".xcworkspace")
|
@@ -2,22 +2,20 @@ module Fastlane
|
|
2
2
|
module Actions
|
3
3
|
class GitCommitAction < Action
|
4
4
|
def self.run(params)
|
5
|
-
paths = params[:path]
|
6
|
-
|
7
|
-
skip_git_hooks = params[:skip_git_hooks] ? '--no-verify' : ''
|
5
|
+
paths = params[:path]
|
6
|
+
skip_git_hooks = params[:skip_git_hooks] ? ['--no-verify'] : []
|
8
7
|
|
9
8
|
if params[:allow_nothing_to_commit]
|
10
9
|
# Here we check if the path passed in parameter contains any modification
|
11
10
|
# and we skip the `git commit` command if there is none.
|
12
11
|
# That means you can have other files modified that are not in the path parameter
|
13
12
|
# and still make use of allow_nothing_to_commit.
|
14
|
-
repo_clean = Actions.sh(
|
13
|
+
repo_clean = Actions.sh('git', 'status', *paths, '--porcelain').empty?
|
15
14
|
UI.success("Nothing to commit, working tree clean ✅.") if repo_clean
|
16
15
|
return if repo_clean
|
17
16
|
end
|
18
17
|
|
19
|
-
|
20
|
-
result = Actions.sh(command)
|
18
|
+
result = Actions.sh('git', 'commit', '-m', params[:message], *paths, *skip_git_hooks)
|
21
19
|
UI.success("Successfully committed \"#{params[:path]}\" 💾.")
|
22
20
|
return result
|
23
21
|
end
|
@@ -58,7 +58,7 @@ module Fastlane
|
|
58
58
|
|
59
59
|
def self.example_code
|
60
60
|
[
|
61
|
-
'import_certificate(certificate_path: "certs/
|
61
|
+
'import_certificate(certificate_path: "certs/AppleWWDRCA6.cer")',
|
62
62
|
'import_certificate(
|
63
63
|
certificate_path: "certs/dist.p12",
|
64
64
|
certificate_password: ENV["CERTIFICATE_PASSWORD"] || "default"
|
@@ -5,6 +5,7 @@ module Fastlane
|
|
5
5
|
def self.run(params)
|
6
6
|
package_path = params[:package]
|
7
7
|
bundle_id = params[:bundle_id]
|
8
|
+
skip_stapling = params[:skip_stapling]
|
8
9
|
try_early_stapling = params[:try_early_stapling]
|
9
10
|
print_log = params[:print_log]
|
10
11
|
verbose = params[:verbose]
|
@@ -38,13 +39,13 @@ module Fastlane
|
|
38
39
|
UI.user_error!('Could not read bundle identifier, provide as a parameter') unless bundle_id
|
39
40
|
|
40
41
|
if use_notarytool
|
41
|
-
notarytool(params, package_path, bundle_id,
|
42
|
+
notarytool(params, package_path, bundle_id, skip_stapling, print_log, verbose, api_key, compressed_package_path)
|
42
43
|
else
|
43
|
-
altool(params, package_path, bundle_id, try_early_stapling, print_log, verbose, api_key, compressed_package_path)
|
44
|
+
altool(params, package_path, bundle_id, try_early_stapling, skip_stapling, print_log, verbose, api_key, compressed_package_path)
|
44
45
|
end
|
45
46
|
end
|
46
47
|
|
47
|
-
def self.notarytool(params, package_path, bundle_id,
|
48
|
+
def self.notarytool(params, package_path, bundle_id, skip_stapling, print_log, verbose, api_key, compressed_package_path)
|
48
49
|
temp_file = nil
|
49
50
|
|
50
51
|
# Create authorization part of command with either API Key or Apple ID
|
@@ -89,10 +90,15 @@ module Fastlane
|
|
89
90
|
submission_id = notarization_info["id"]
|
90
91
|
UI.success("Successfully uploaded package to notarization service with request identifier #{submission_id}")
|
91
92
|
|
92
|
-
|
93
|
-
|
93
|
+
if skip_stapling
|
94
|
+
UI.success("Successfully notarized artifact")
|
95
|
+
else
|
96
|
+
UI.message('Stapling package')
|
94
97
|
|
95
|
-
|
98
|
+
self.staple(package_path, verbose)
|
99
|
+
|
100
|
+
UI.success("Successfully notarized and stapled package")
|
101
|
+
end
|
96
102
|
when 'Invalid'
|
97
103
|
UI.user_error!("Could not notarize package with message '#{notarization_info['statusSummary']}'")
|
98
104
|
else
|
@@ -102,7 +108,7 @@ module Fastlane
|
|
102
108
|
temp_file.delete if temp_file
|
103
109
|
end
|
104
110
|
|
105
|
-
def self.altool(params, package_path, bundle_id, try_early_stapling, print_log, verbose, api_key, compressed_package_path)
|
111
|
+
def self.altool(params, package_path, bundle_id, try_early_stapling, skip_stapling, print_log, verbose, api_key, compressed_package_path)
|
106
112
|
UI.message('Uploading package to notarization service, might take a while')
|
107
113
|
|
108
114
|
notarization_upload_command = "xcrun altool --notarize-app -t osx -f \"#{compressed_package_path || package_path}\" --primary-bundle-id #{bundle_id} --output-format xml"
|
@@ -133,7 +139,7 @@ module Fastlane
|
|
133
139
|
while notarization_info.empty? || (notarization_info['Status'] == 'in progress')
|
134
140
|
if notarization_info.empty?
|
135
141
|
UI.message('Waiting to query request status')
|
136
|
-
elsif try_early_stapling
|
142
|
+
elsif try_early_stapling && !skip_stapling
|
137
143
|
UI.message('Request in progress, trying early staple')
|
138
144
|
|
139
145
|
begin
|
@@ -182,11 +188,15 @@ module Fastlane
|
|
182
188
|
|
183
189
|
case notarization_info['Status']
|
184
190
|
when 'success'
|
185
|
-
|
191
|
+
if skip_stapling
|
192
|
+
UI.success("Successfully notarized artifact#{log_suffix}")
|
193
|
+
else
|
194
|
+
UI.message('Stapling package')
|
186
195
|
|
187
|
-
|
196
|
+
self.staple(package_path, verbose)
|
188
197
|
|
189
|
-
|
198
|
+
UI.success("Successfully notarized and stapled package#{log_suffix}")
|
199
|
+
end
|
190
200
|
when 'invalid'
|
191
201
|
UI.user_error!("Could not notarize package with message '#{notarization_info['Status Message']}'#{log_suffix}")
|
192
202
|
else
|
@@ -262,6 +272,14 @@ module Fastlane
|
|
262
272
|
env_name: 'FL_NOTARIZE_TRY_EARLY_STAPLING',
|
263
273
|
description: 'Whether to try early stapling while the notarization request is in progress',
|
264
274
|
optional: true,
|
275
|
+
conflicting_options: [:skip_stapling],
|
276
|
+
default_value: false,
|
277
|
+
type: Boolean),
|
278
|
+
FastlaneCore::ConfigItem.new(key: :skip_stapling,
|
279
|
+
env_name: 'FL_NOTARIZE_SKIP_STAPLING',
|
280
|
+
description: 'Do not staple the notarization ticket to the artifact; useful for single file executables and ZIP archives',
|
281
|
+
optional: true,
|
282
|
+
conflicting_options: [:try_early_stapling],
|
265
283
|
default_value: false,
|
266
284
|
type: Boolean),
|
267
285
|
FastlaneCore::ConfigItem.new(key: :bundle_id,
|
@@ -59,6 +59,14 @@ module Fastlane
|
|
59
59
|
command << "--synchronous"
|
60
60
|
end
|
61
61
|
|
62
|
+
if params[:no_overwrite]
|
63
|
+
command << "--no-overwrite"
|
64
|
+
end
|
65
|
+
|
66
|
+
if params[:local_only]
|
67
|
+
command << "--local-only"
|
68
|
+
end
|
69
|
+
|
62
70
|
result = Actions.sh(command.join(' '))
|
63
71
|
UI.success("Successfully pushed Podspec ⬆️ ")
|
64
72
|
return result
|
@@ -143,7 +151,17 @@ module Fastlane
|
|
143
151
|
description: "If validation depends on other recently pushed pods, synchronize",
|
144
152
|
optional: true,
|
145
153
|
type: Boolean,
|
146
|
-
env_name: "FL_POD_PUSH_SYNCHRONOUS")
|
154
|
+
env_name: "FL_POD_PUSH_SYNCHRONOUS"),
|
155
|
+
FastlaneCore::ConfigItem.new(key: :no_overwrite,
|
156
|
+
description: "Disallow pushing that would overwrite an existing spec",
|
157
|
+
optional: true,
|
158
|
+
type: Boolean,
|
159
|
+
env_name: "FL_POD_PUSH_NO_OVERWRITE"),
|
160
|
+
FastlaneCore::ConfigItem.new(key: :local_only,
|
161
|
+
description: "Does not perform the step of pushing REPO to its remote",
|
162
|
+
optional: true,
|
163
|
+
type: Boolean,
|
164
|
+
env_name: "FL_POD_PUSH_LOCAL_ONLY")
|
147
165
|
]
|
148
166
|
end
|
149
167
|
|
@@ -4,6 +4,7 @@ module Fastlane
|
|
4
4
|
SCAN_DERIVED_DATA_PATH = :SCAN_DERIVED_DATA_PATH
|
5
5
|
SCAN_GENERATED_PLIST_FILE = :SCAN_GENERATED_PLIST_FILE
|
6
6
|
SCAN_GENERATED_PLIST_FILES = :SCAN_GENERATED_PLIST_FILES
|
7
|
+
SCAN_GENERATED_XCRESULT_PATH = :SCAN_GENERATED_XCRESULT_PATH
|
7
8
|
SCAN_ZIP_BUILD_PRODUCTS_PATH = :SCAN_ZIP_BUILD_PRODUCTS_PATH
|
8
9
|
end
|
9
10
|
|
@@ -13,12 +14,12 @@ module Fastlane
|
|
13
14
|
manager = Scan::Manager.new
|
14
15
|
|
15
16
|
begin
|
16
|
-
manager.work(values)
|
17
|
+
results = manager.work(values)
|
17
18
|
|
18
19
|
zip_build_products_path = Scan.cache[:zip_build_products_path]
|
19
20
|
Actions.lane_context[SharedValues::SCAN_ZIP_BUILD_PRODUCTS_PATH] = zip_build_products_path if zip_build_products_path
|
20
21
|
|
21
|
-
return
|
22
|
+
return results
|
22
23
|
rescue FastlaneCore::Interface::FastlaneBuildFailure => ex
|
23
24
|
# Specifically catching FastlaneBuildFailure to prevent build/compile errors from being
|
24
25
|
# silenced when :fail_build is set to false
|
@@ -29,6 +30,12 @@ module Fastlane
|
|
29
30
|
raise ex
|
30
31
|
end
|
31
32
|
ensure
|
33
|
+
if Scan.cache && (result_bundle_path = Scan.cache[:result_bundle_path])
|
34
|
+
Actions.lane_context[SharedValues::SCAN_GENERATED_XCRESULT_PATH] = File.absolute_path(result_bundle_path)
|
35
|
+
else
|
36
|
+
Actions.lane_context[SharedValues::SCAN_GENERATED_XCRESULT_PATH] = nil
|
37
|
+
end
|
38
|
+
|
32
39
|
unless values[:derived_data_path].to_s.empty?
|
33
40
|
plist_files_before = manager.plist_files_before || []
|
34
41
|
|
@@ -49,6 +56,14 @@ module Fastlane
|
|
49
56
|
"More information: https://docs.fastlane.tools/actions/scan/"
|
50
57
|
end
|
51
58
|
|
59
|
+
def self.return_value
|
60
|
+
'Outputs hash of results with the following keys: :number_of_tests, :number_of_failures, :number_of_retries, :number_of_tests_excluding_retries, :number_of_failures_excluding_retries'
|
61
|
+
end
|
62
|
+
|
63
|
+
def self.return_type
|
64
|
+
:hash
|
65
|
+
end
|
66
|
+
|
52
67
|
def self.author
|
53
68
|
"KrauseFx"
|
54
69
|
end
|
@@ -56,13 +71,7 @@ module Fastlane
|
|
56
71
|
def self.available_options
|
57
72
|
require 'scan'
|
58
73
|
|
59
|
-
FastlaneCore::CommanderGenerator.new.generate(Scan::Options.available_options)
|
60
|
-
FastlaneCore::ConfigItem.new(key: :fail_build,
|
61
|
-
env_name: "SCAN_FAIL_BUILD",
|
62
|
-
description: "Should this step stop the build if the tests fail? Set this to false if you're using trainer",
|
63
|
-
type: Boolean,
|
64
|
-
default_value: true)
|
65
|
-
]
|
74
|
+
FastlaneCore::CommanderGenerator.new.generate(Scan::Options.available_options)
|
66
75
|
end
|
67
76
|
|
68
77
|
def self.output
|
@@ -70,6 +79,7 @@ module Fastlane
|
|
70
79
|
['SCAN_DERIVED_DATA_PATH', 'The path to the derived data'],
|
71
80
|
['SCAN_GENERATED_PLIST_FILE', 'The generated plist file'],
|
72
81
|
['SCAN_GENERATED_PLIST_FILES', 'The generated plist files'],
|
82
|
+
['SCAN_GENERATED_XCRESULT_PATH', 'The path to the generated .xcresult'],
|
73
83
|
['SCAN_ZIP_BUILD_PRODUCTS_PATH', 'The path to the zipped build products']
|
74
84
|
]
|
75
85
|
end
|
@@ -19,11 +19,12 @@ module Fastlane
|
|
19
19
|
|
20
20
|
payload = {
|
21
21
|
'tag_name' => params[:tag_name],
|
22
|
-
'name' => params[:name],
|
23
|
-
'body' => params[:description],
|
24
22
|
'draft' => !!params[:is_draft],
|
25
|
-
'prerelease' => !!params[:is_prerelease]
|
23
|
+
'prerelease' => !!params[:is_prerelease],
|
24
|
+
'generate_release_notes' => !!params[:is_generate_release_notes]
|
26
25
|
}
|
26
|
+
payload['name'] = params[:name] if params[:name]
|
27
|
+
payload['body'] = params[:description] if params[:description]
|
27
28
|
payload['target_commitish'] = params[:commitish] if params[:commitish]
|
28
29
|
|
29
30
|
GithubApiAction.run(
|
@@ -48,8 +49,7 @@ module Fastlane
|
|
48
49
|
UI.user_error!("You are not authorized to access #{repo_name}, please make sure you provided a valid API token (GITHUB_API_TOKEN)")
|
49
50
|
end,
|
50
51
|
'*' => proc do |result|
|
51
|
-
UI.
|
52
|
-
return nil
|
52
|
+
UI.user_error!("GitHub responded with #{result[:status]}:#{result[:body]}")
|
53
53
|
end
|
54
54
|
}
|
55
55
|
) do |result|
|
@@ -221,6 +221,12 @@ module Fastlane
|
|
221
221
|
optional: true,
|
222
222
|
default_value: false,
|
223
223
|
type: Boolean),
|
224
|
+
FastlaneCore::ConfigItem.new(key: :is_generate_release_notes,
|
225
|
+
env_name: "FL_SET_GITHUB_RELEASE_IS_GENERATE_RELEASE_NOTES",
|
226
|
+
description: "Whether the name and body of this release should be generated automatically",
|
227
|
+
optional: true,
|
228
|
+
default_value: false,
|
229
|
+
type: Boolean),
|
224
230
|
FastlaneCore::ConfigItem.new(key: :upload_assets,
|
225
231
|
env_name: "FL_SET_GITHUB_RELEASE_UPLOAD_ASSETS",
|
226
232
|
description: "Path to assets to be uploaded with the release",
|
@@ -12,7 +12,7 @@ module Fastlane
|
|
12
12
|
setup_output_paths
|
13
13
|
end
|
14
14
|
|
15
|
-
setup_keychain
|
15
|
+
setup_keychain(params)
|
16
16
|
end
|
17
17
|
|
18
18
|
def self.should_run?(params)
|
@@ -23,7 +23,7 @@ module Fastlane
|
|
23
23
|
params[:provider] || (Helper.is_circle_ci? ? 'circleci' : nil)
|
24
24
|
end
|
25
25
|
|
26
|
-
def self.setup_keychain
|
26
|
+
def self.setup_keychain(params)
|
27
27
|
unless Helper.mac?
|
28
28
|
UI.message("Skipping Keychain setup on non-macOS CI Agent")
|
29
29
|
return
|
@@ -43,7 +43,7 @@ module Fastlane
|
|
43
43
|
name: keychain_name,
|
44
44
|
default_keychain: true,
|
45
45
|
unlock: true,
|
46
|
-
timeout:
|
46
|
+
timeout: params[:timeout],
|
47
47
|
lock_when_sleeps: true,
|
48
48
|
password: "",
|
49
49
|
add_to_search_list: true
|
@@ -103,7 +103,12 @@ module Fastlane
|
|
103
103
|
# Validate both 'travis' and 'circleci' for backwards compatibility, even
|
104
104
|
# though only the latter receives special treatment by this action
|
105
105
|
UI.user_error!("A given CI provider '#{value}' is not supported. Available CI providers: 'travis', 'circleci'") unless ["travis", "circleci"].include?(value)
|
106
|
-
end)
|
106
|
+
end),
|
107
|
+
FastlaneCore::ConfigItem.new(key: :timeout,
|
108
|
+
env_name: "FL_SETUP_CI_TIMEOUT",
|
109
|
+
description: "Set a custom timeout in seconds for keychain. Set `0` if you want to specify 'no time-out'",
|
110
|
+
type: Integer,
|
111
|
+
default_value: 3600)
|
107
112
|
]
|
108
113
|
end
|
109
114
|
|
@@ -119,6 +124,10 @@ module Fastlane
|
|
119
124
|
[
|
120
125
|
'setup_ci(
|
121
126
|
provider: "circleci"
|
127
|
+
)',
|
128
|
+
'setup_ci(
|
129
|
+
provider: "circleci",
|
130
|
+
timeout: 0
|
122
131
|
)'
|
123
132
|
]
|
124
133
|
end
|