fastlane 2.138.0 → 2.143.0
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 +75 -62
- data/cert/lib/cert/options.rb +12 -5
- data/cert/lib/cert/runner.rb +13 -0
- data/deliver/lib/deliver/options.rb +2 -2
- data/deliver/lib/deliver/runner.rb +13 -2
- data/deliver/lib/deliver/submit_for_review.rb +7 -1
- data/fastlane/lib/fastlane/action.rb +2 -2
- data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.slack.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/.update_project_provisioning.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/README.md +2 -0
- data/fastlane/lib/fastlane/actions/app_store_build_number.rb +13 -5
- data/fastlane/lib/fastlane/actions/build_app.rb +157 -6
- data/fastlane/lib/fastlane/actions/build_ios_app.rb +28 -132
- data/fastlane/lib/fastlane/actions/build_mac_app.rb +46 -0
- data/fastlane/lib/fastlane/actions/cocoapods.rb +2 -2
- data/fastlane/lib/fastlane/actions/create_pull_request.rb +71 -2
- data/fastlane/lib/fastlane/actions/docs/{build_ios_app.md → build_app.md} +1 -1
- data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +22 -6
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +20 -4
- data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +10 -0
- data/fastlane/lib/fastlane/actions/ensure_git_branch.rb +1 -1
- data/fastlane/lib/fastlane/actions/ensure_xcode_version.rb +35 -7
- data/fastlane/lib/fastlane/actions/frame_screenshots.rb +2 -1
- data/fastlane/lib/fastlane/actions/get_github_release.rb +3 -0
- data/fastlane/lib/fastlane/actions/gradle.rb +43 -2
- data/fastlane/lib/fastlane/actions/gym.rb +3 -7
- data/fastlane/lib/fastlane/actions/import_from_git.rb +4 -0
- data/fastlane/lib/fastlane/actions/last_git_tag.rb +14 -5
- data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +9 -3
- data/fastlane/lib/fastlane/actions/notarize.rb +183 -0
- data/fastlane/lib/fastlane/actions/run_tests.rb +5 -22
- data/fastlane/lib/fastlane/actions/s3.rb +5 -291
- data/fastlane/lib/fastlane/actions/set_github_release.rb +1 -1
- data/fastlane/lib/fastlane/actions/setup_ci.rb +14 -8
- data/fastlane/lib/fastlane/actions/spm.rb +8 -0
- data/fastlane/lib/fastlane/actions/swiftlint.rb +17 -2
- data/fastlane/lib/fastlane/actions/update_plist.rb +37 -2
- data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +13 -3
- data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +1 -0
- data/fastlane/lib/fastlane/actions/upload_to_play_store_internal_app_sharing.rb +78 -0
- data/fastlane/lib/fastlane/fast_file.rb +13 -3
- data/fastlane/lib/fastlane/helper/adb_helper.rb +1 -1
- data/fastlane/lib/fastlane/helper/s3_client_helper.rb +56 -0
- data/fastlane/lib/fastlane/plugins/plugin_manager.rb +1 -1
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +2 -0
- data/fastlane/lib/fastlane/runner.rb +23 -18
- data/fastlane/lib/fastlane/server/socket_server_action_command_executor.rb +1 -1
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/DeliverfileProtocol.swift +3 -3
- data/fastlane/swift/Fastlane.swift +429 -50
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/GymfileProtocol.swift +17 -1
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +23 -3
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/RubyCommand.swift +1 -1
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/ScanfileProtocol.swift +21 -1
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane/swift/SnapshotfileProtocol.swift +9 -1
- data/fastlane_core/lib/fastlane_core/build_watcher.rb +6 -2
- data/fastlane_core/lib/fastlane_core/cert_checker.rb +28 -0
- data/fastlane_core/lib/fastlane_core/device_manager.rb +20 -0
- data/fastlane_core/lib/fastlane_core/helper.rb +7 -1
- data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +1 -0
- data/fastlane_core/lib/fastlane_core/keychain_importer.rb +2 -0
- data/fastlane_core/lib/fastlane_core/project.rb +27 -0
- data/frameit/lib/frameit/commands_generator.rb +25 -0
- data/frameit/lib/frameit/config_parser.rb +31 -9
- data/frameit/lib/frameit/device.rb +90 -0
- data/frameit/lib/frameit/device_types.rb +121 -5
- data/frameit/lib/frameit/editor.rb +31 -40
- data/frameit/lib/frameit/offsets.rb +8 -1
- data/frameit/lib/frameit/options.rb +81 -54
- data/frameit/lib/frameit/runner.rb +17 -7
- data/frameit/lib/frameit/screenshot.rb +35 -47
- data/frameit/lib/frameit/template_finder.rb +15 -12
- data/gym/lib/gym/code_signing_mapping.rb +32 -3
- data/gym/lib/gym/detect_values.rb +34 -2
- data/gym/lib/gym/generators/build_command_generator.rb +1 -0
- data/gym/lib/gym/generators/package_command_generator.rb +4 -0
- data/gym/lib/gym/generators/package_command_generator_xcode7.rb +47 -17
- data/gym/lib/gym/module.rb +8 -0
- data/gym/lib/gym/options.rb +25 -1
- data/gym/lib/gym/runner.rb +64 -24
- data/match/lib/match/change_password.rb +1 -1
- data/match/lib/match/encryption.rb +4 -0
- data/match/lib/match/encryption/openssl.rb +1 -1
- data/match/lib/match/generator.rb +17 -3
- data/match/lib/match/importer.rb +2 -2
- data/match/lib/match/module.rb +5 -2
- data/match/lib/match/nuke.rb +59 -17
- data/match/lib/match/options.rb +38 -15
- data/match/lib/match/runner.rb +24 -8
- data/match/lib/match/setup.rb +1 -1
- data/match/lib/match/spaceship_ensure.rb +19 -9
- data/match/lib/match/storage.rb +4 -0
- data/match/lib/match/storage/git_storage.rb +5 -2
- data/match/lib/match/storage/google_cloud_storage.rb +2 -2
- data/match/lib/match/storage/s3_storage.rb +162 -0
- data/pilot/lib/pilot/.manager.rb.swp +0 -0
- data/pilot/lib/pilot/build_manager.rb +55 -15
- data/pilot/lib/pilot/options.rb +3 -1
- data/scan/lib/scan/detect_values.rb +6 -1
- data/scan/lib/scan/manager.rb +18 -1
- data/scan/lib/scan/options.rb +28 -1
- data/scan/lib/scan/runner.rb +11 -3
- data/scan/lib/scan/slack_poster.rb +1 -1
- data/scan/lib/scan/test_command_generator.rb +9 -5
- data/screengrab/lib/screengrab/runner.rb +31 -18
- data/snapshot/lib/snapshot/fixes/simulator_shared_pasteboard.rb +16 -0
- data/snapshot/lib/snapshot/options.rb +12 -1
- data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +13 -0
- data/spaceship/lib/spaceship/connect_api/.DS_Store +0 -0
- data/spaceship/lib/spaceship/connect_api/models/beta_feedback.rb +4 -0
- data/spaceship/lib/spaceship/connect_api/models/build.rb +4 -0
- data/spaceship/lib/spaceship/connect_api/models/build_beta_detail.rb +5 -0
- data/spaceship/lib/spaceship/connect_api/models/certificate.rb +2 -0
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +6 -0
- data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
- data/spaceship/lib/spaceship/portal/app.rb +11 -2
- data/spaceship/lib/spaceship/tunes/iap.rb +11 -11
- data/spaceship/lib/spaceship/tunes/iap_detail.rb +7 -3
- data/spaceship/lib/spaceship/tunes/iap_families.rb +12 -1
- data/spaceship/lib/spaceship/tunes/iap_family_details.rb +26 -17
- data/spaceship/lib/spaceship/tunes/iap_status.rb +5 -1
- data/spaceship/lib/spaceship/tunes/tunes_client.rb +2 -2
- data/supply/lib/supply/client.rb +26 -0
- data/supply/lib/supply/uploader.rb +28 -0
- metadata +64 -20
@@ -73,8 +73,11 @@ module Match
|
|
73
73
|
self.working_directory = Dir.mktmpdir
|
74
74
|
|
75
75
|
command = "git clone #{self.git_url.shellescape} #{self.working_directory.shellescape}"
|
76
|
-
|
77
|
-
|
76
|
+
# HTTP headers are supposed to be be case insensitive but
|
77
|
+
# Bitbucket requires `Authorization: Basic` and `Authorization Bearer` to work
|
78
|
+
# https://github.com/fastlane/fastlane/pull/15928
|
79
|
+
command << " -c http.extraheader='Authorization: Basic #{self.git_basic_authorization}'" unless self.git_basic_authorization.nil?
|
80
|
+
command << " -c http.extraheader='Authorization: Bearer #{self.git_bearer_authorization}'" unless self.git_bearer_authorization.nil?
|
78
81
|
|
79
82
|
if self.shallow_clone
|
80
83
|
command << " --depth 1 --no-single-branch"
|
@@ -181,7 +181,7 @@ module Match
|
|
181
181
|
end
|
182
182
|
|
183
183
|
def generate_matchfile_content
|
184
|
-
return "
|
184
|
+
return "google_cloud_bucket_name(\"#{self.bucket_name}\")"
|
185
185
|
end
|
186
186
|
|
187
187
|
private
|
@@ -349,7 +349,7 @@ module Match
|
|
349
349
|
UI.message("\t\t 1. Click on your bucket to open it".cyan)
|
350
350
|
UI.message("\t\t 2. Click 'Permissions'".cyan)
|
351
351
|
UI.message("\t\t 3. Click 'Add members'".cyan)
|
352
|
-
UI.message("\t\t 4. Enter the
|
352
|
+
UI.message("\t\t 4. Enter the service account email address".cyan)
|
353
353
|
UI.message("\t\t 5. Set the role to 'Storage Admin'".cyan)
|
354
354
|
UI.message("\t\t 6. Click 'Save'".cyan)
|
355
355
|
UI.message("")
|
@@ -0,0 +1,162 @@
|
|
1
|
+
require 'fastlane_core/command_executor'
|
2
|
+
require 'fastlane_core/configuration/configuration'
|
3
|
+
require 'fastlane/helper/s3_client_helper'
|
4
|
+
|
5
|
+
require_relative '../options'
|
6
|
+
require_relative '../module'
|
7
|
+
require_relative '../spaceship_ensure'
|
8
|
+
require_relative './interface'
|
9
|
+
|
10
|
+
module Match
|
11
|
+
module Storage
|
12
|
+
# Store the code signing identities on AWS S3
|
13
|
+
class S3Storage < Interface
|
14
|
+
attr_reader :s3_bucket
|
15
|
+
attr_reader :s3_region
|
16
|
+
attr_reader :s3_client
|
17
|
+
attr_reader :readonly
|
18
|
+
attr_reader :username
|
19
|
+
attr_reader :team_id
|
20
|
+
attr_reader :team_name
|
21
|
+
|
22
|
+
def self.configure(params)
|
23
|
+
s3_region = params[:s3_region]
|
24
|
+
s3_access_key = params[:s3_access_key]
|
25
|
+
s3_secret_access_key = params[:s3_secret_access_key]
|
26
|
+
s3_bucket = params[:s3_bucket]
|
27
|
+
|
28
|
+
if params[:git_url].to_s.length > 0
|
29
|
+
UI.important("Looks like you still define a `git_url` somewhere, even though")
|
30
|
+
UI.important("you use S3 Storage. You can remove the `git_url`")
|
31
|
+
UI.important("from your Matchfile and Fastfile")
|
32
|
+
UI.message("The above is just a warning, fastlane will continue as usual now...")
|
33
|
+
end
|
34
|
+
|
35
|
+
return self.new(
|
36
|
+
s3_region: s3_region,
|
37
|
+
s3_access_key: s3_access_key,
|
38
|
+
s3_secret_access_key: s3_secret_access_key,
|
39
|
+
s3_bucket: s3_bucket,
|
40
|
+
readonly: params[:readonly],
|
41
|
+
username: params[:username],
|
42
|
+
team_id: params[:team_id],
|
43
|
+
team_name: params[:team_name]
|
44
|
+
)
|
45
|
+
end
|
46
|
+
|
47
|
+
def initialize(s3_region: nil,
|
48
|
+
s3_access_key: nil,
|
49
|
+
s3_secret_access_key: nil,
|
50
|
+
s3_bucket: nil,
|
51
|
+
readonly: nil,
|
52
|
+
username: nil,
|
53
|
+
team_id: nil,
|
54
|
+
team_name: nil)
|
55
|
+
@s3_bucket = s3_bucket
|
56
|
+
@s3_region = s3_region
|
57
|
+
@s3_client = Fastlane::Helper::S3ClientHelper.new(access_key: s3_access_key, secret_access_key: s3_secret_access_key, region: s3_region)
|
58
|
+
@readonly = readonly
|
59
|
+
@username = username
|
60
|
+
@team_id = team_id
|
61
|
+
@team_name = team_name
|
62
|
+
end
|
63
|
+
|
64
|
+
# To make debugging easier, we have a custom exception here
|
65
|
+
def prefixed_working_directory
|
66
|
+
# We fall back to "*", which means certificates and profiles
|
67
|
+
# from all teams that use this bucket would be installed. This is not ideal, but
|
68
|
+
# unless the user provides a `team_id`, we can't know which one to use
|
69
|
+
# This only happens if `readonly` is activated, and no `team_id` was provided
|
70
|
+
@_folder_prefix ||= currently_used_team_id
|
71
|
+
if @_folder_prefix.nil?
|
72
|
+
# We use a `@_folder_prefix` variable, to keep state between multiple calls of this
|
73
|
+
# method, as the value won't change. This way the warning is only printed once
|
74
|
+
UI.important("Looks like you run `match` in `readonly` mode, and didn't provide a `team_id`. This will still work, however it is recommended to provide a `team_id` in your Appfile or Matchfile")
|
75
|
+
@_folder_prefix = "*"
|
76
|
+
end
|
77
|
+
return File.join(working_directory, @_folder_prefix)
|
78
|
+
end
|
79
|
+
|
80
|
+
# Call this method for the initial clone/download of the
|
81
|
+
# user's certificates & profiles
|
82
|
+
# As part of this method, the `self.working_directory` attribute
|
83
|
+
# will be set
|
84
|
+
def download
|
85
|
+
# Check if we already have a functional working_directory
|
86
|
+
return if @working_directory && Dir.exist?(@working_directory)
|
87
|
+
|
88
|
+
# No existing working directory, creating a new one now
|
89
|
+
self.working_directory = Dir.mktmpdir
|
90
|
+
|
91
|
+
s3_client.find_bucket!(s3_bucket).objects.each do |object|
|
92
|
+
file_path = object.public_url.to_s.split("s3.amazonaws.com/").last
|
93
|
+
download_path = File.join(self.working_directory, file_path)
|
94
|
+
|
95
|
+
FileUtils.mkdir_p(File.expand_path("..", download_path))
|
96
|
+
UI.verbose("Downloading file from S3 '#{file_path}' on bucket #{self.s3_bucket}")
|
97
|
+
|
98
|
+
object.download_file(download_path)
|
99
|
+
end
|
100
|
+
UI.verbose("Successfully downloaded files from S3 to #{self.working_directory}")
|
101
|
+
end
|
102
|
+
|
103
|
+
# Returns a short string describing + identifing the current
|
104
|
+
# storage backend. This will be printed when nuking a storage
|
105
|
+
def human_readable_description
|
106
|
+
return "S3 Bucket [#{s3_bucket}] on region #{s3_region}"
|
107
|
+
end
|
108
|
+
|
109
|
+
def upload_files(files_to_upload: [], custom_message: nil)
|
110
|
+
# `files_to_upload` is an array of files that need to be uploaded to S3
|
111
|
+
# Those doesn't mean they're new, it might just be they're changed
|
112
|
+
# Either way, we'll upload them using the same technique
|
113
|
+
|
114
|
+
files_to_upload.each do |current_file|
|
115
|
+
# Go from
|
116
|
+
# "/var/folders/px/bz2kts9n69g8crgv4jpjh6b40000gn/T/d20181026-96528-1av4gge/profiles/development/Development_me.mobileprovision"
|
117
|
+
# to
|
118
|
+
# "profiles/development/Development_me.mobileprovision"
|
119
|
+
#
|
120
|
+
|
121
|
+
target_path = current_file.gsub(self.working_directory + "/", "")
|
122
|
+
UI.verbose("Uploading '#{target_path}' to S3 Storage...")
|
123
|
+
|
124
|
+
body = File.read(current_file)
|
125
|
+
acl = 'private'
|
126
|
+
s3_url = s3_client.upload_file(s3_bucket, target_path, body, acl)
|
127
|
+
UI.verbose("Uploaded '#{s3_url}' to S3 Storage.")
|
128
|
+
end
|
129
|
+
end
|
130
|
+
|
131
|
+
def delete_files(files_to_delete: [], custom_message: nil)
|
132
|
+
files_to_delete.each do |file_name|
|
133
|
+
s3_client.delete_file(s3_bucket, file_name)
|
134
|
+
end
|
135
|
+
end
|
136
|
+
|
137
|
+
def skip_docs
|
138
|
+
false
|
139
|
+
end
|
140
|
+
|
141
|
+
# Implement this for the `fastlane match init` command
|
142
|
+
# This method must return the content of the Matchfile
|
143
|
+
# that should be generated
|
144
|
+
def generate_matchfile_content(template: nil)
|
145
|
+
return "s3_bucket(\"#{self.s3_bucket}\")"
|
146
|
+
end
|
147
|
+
|
148
|
+
private
|
149
|
+
|
150
|
+
def currently_used_team_id
|
151
|
+
if self.readonly
|
152
|
+
# In readonly mode, we still want to see if the user provided a team_id
|
153
|
+
# see `prefixed_working_directory` comments for more details
|
154
|
+
return self.team_id
|
155
|
+
else
|
156
|
+
spaceship = SpaceshipEnsure.new(self.username, self.team_id, self.team_name)
|
157
|
+
return spaceship.team_id
|
158
|
+
end
|
159
|
+
end
|
160
|
+
end
|
161
|
+
end
|
162
|
+
end
|
Binary file
|
@@ -39,17 +39,25 @@ module Pilot
|
|
39
39
|
|
40
40
|
UI.success("Successfully uploaded the new binary to App Store Connect")
|
41
41
|
|
42
|
+
# We will fully skip waiting for build processing *only* if no changelog is supplied
|
43
|
+
# Otherwise we may partially wait until the build appears so the changelog can be set, and then bail.
|
44
|
+
return_when_build_appears = false
|
42
45
|
if config[:skip_waiting_for_build_processing]
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
+
if config[:changelog].nil?
|
47
|
+
UI.important("`skip_waiting_for_build_processing` used and no `changelog` supplied - skipping waiting for build processing")
|
48
|
+
return
|
49
|
+
else
|
50
|
+
return_when_build_appears = true
|
51
|
+
end
|
46
52
|
end
|
47
53
|
|
48
54
|
# Calling login again here is needed if login was not called during 'start'
|
49
55
|
login unless should_login_in_start
|
50
56
|
|
51
57
|
UI.message("If you want to skip waiting for the processing to be finished, use the `skip_waiting_for_build_processing` option")
|
52
|
-
|
58
|
+
UI.message("Note that if `skip_waiting_for_build_processing` is used but a `changelog` is supplied, this process will wait for the build to appear on AppStoreConnect, update the changelog and then skip the remaining of the processing steps.")
|
59
|
+
|
60
|
+
latest_build = wait_for_build_processing_to_be_complete(return_when_build_appears)
|
53
61
|
distribute(options, build: latest_build)
|
54
62
|
end
|
55
63
|
|
@@ -80,11 +88,20 @@ module Pilot
|
|
80
88
|
end
|
81
89
|
end
|
82
90
|
|
83
|
-
def wait_for_build_processing_to_be_complete
|
91
|
+
def wait_for_build_processing_to_be_complete(return_when_build_appears = false)
|
84
92
|
platform = fetch_app_platform
|
85
93
|
app_version = FastlaneCore::IpaFileAnalyser.fetch_app_version(config[:ipa])
|
86
94
|
app_build = FastlaneCore::IpaFileAnalyser.fetch_app_build(config[:ipa])
|
87
|
-
|
95
|
+
|
96
|
+
latest_build = FastlaneCore::BuildWatcher.wait_for_build_processing_to_be_complete(
|
97
|
+
app_id: app.id,
|
98
|
+
platform: platform,
|
99
|
+
app_version: app_version,
|
100
|
+
build_version: app_build,
|
101
|
+
poll_interval: config[:wait_processing_interval],
|
102
|
+
return_when_build_appears: return_when_build_appears,
|
103
|
+
return_spaceship_testflight_build: false
|
104
|
+
)
|
88
105
|
|
89
106
|
unless latest_build.app_version == app_version && latest_build.version == app_build
|
90
107
|
UI.important("Uploaded app #{app_version} - #{app_build}, but received build #{latest_build.app_version} - #{latest_build.version}.")
|
@@ -137,6 +154,14 @@ module Pilot
|
|
137
154
|
UI.success("Deleted beta app review submission for previous build: #{waiting_for_review_build.app_version} - #{waiting_for_review_build.version}")
|
138
155
|
end
|
139
156
|
end
|
157
|
+
|
158
|
+
if !build.ready_for_internal_testing? && options[:skip_waiting_for_build_processing]
|
159
|
+
# Meta can be uploaded for a build still in processing
|
160
|
+
# Returning before distribute if skip_waiting_for_build_processing
|
161
|
+
# because can't distribute an app that is still processing
|
162
|
+
return
|
163
|
+
end
|
164
|
+
|
140
165
|
distribute_build(build, options)
|
141
166
|
type = options[:distribute_external] ? 'External' : 'Internal'
|
142
167
|
UI.success("Successfully distributed build to #{type} testers 🚀")
|
@@ -220,12 +245,21 @@ module Pilot
|
|
220
245
|
end
|
221
246
|
|
222
247
|
def self.truncate_changelog(changelog)
|
223
|
-
|
224
|
-
if changelog
|
225
|
-
|
226
|
-
|
227
|
-
|
228
|
-
|
248
|
+
max_changelog_bytes = 4000
|
249
|
+
if changelog
|
250
|
+
changelog_bytes = changelog.unpack('C*').length
|
251
|
+
if changelog_bytes > max_changelog_bytes
|
252
|
+
UI.important("Changelog will be truncated since it exceeds Apple's #{max_changelog_bytes}-byte limit. It currently contains #{changelog_bytes} bytes.")
|
253
|
+
new_changelog = ''
|
254
|
+
new_changelog_bytes = 0
|
255
|
+
max_changelog_bytes -= 3 # Will append '...' later.
|
256
|
+
changelog.chars.each do |char|
|
257
|
+
new_changelog_bytes += char.unpack('C*').length
|
258
|
+
break if new_changelog_bytes >= max_changelog_bytes
|
259
|
+
new_changelog += char
|
260
|
+
end
|
261
|
+
changelog = new_changelog + '...'
|
262
|
+
end
|
229
263
|
end
|
230
264
|
changelog
|
231
265
|
end
|
@@ -447,12 +481,18 @@ module Pilot
|
|
447
481
|
end
|
448
482
|
|
449
483
|
def update_build_beta_details(build, info)
|
450
|
-
build_beta_detail = build.build_beta_detail
|
451
|
-
|
452
484
|
attributes = {}
|
453
485
|
attributes[:autoNotifyEnabled] = info[:auto_notify_enabled] if info.key?(:auto_notify_enabled)
|
486
|
+
build_beta_detail = build.build_beta_detail
|
454
487
|
|
455
|
-
|
488
|
+
# https://github.com/fastlane/fastlane/pull/16006
|
489
|
+
if build_beta_detail
|
490
|
+
Spaceship::ConnectAPI.patch_build_beta_details(build_beta_details_id: build_beta_detail.id, attributes: attributes)
|
491
|
+
else
|
492
|
+
if attributes[:autoNotifyEnabled]
|
493
|
+
UI.important("Unable to auto notify testers as the build did not include beta detail information - this is likely a temporary issue on TestFlight.")
|
494
|
+
end
|
495
|
+
end
|
456
496
|
end
|
457
497
|
end
|
458
498
|
# rubocop:enable Metrics/ClassLength
|
data/pilot/lib/pilot/options.rb
CHANGED
@@ -132,7 +132,9 @@ module Pilot
|
|
132
132
|
FastlaneCore::ConfigItem.new(key: :skip_waiting_for_build_processing,
|
133
133
|
short_option: "-z",
|
134
134
|
env_name: "PILOT_SKIP_WAITING_FOR_BUILD_PROCESSING",
|
135
|
-
description: "
|
135
|
+
description: "If set to true, the `distribute_external` option won't work and no build will be distributed to testers. " \
|
136
|
+
"(You might want to use this option if you are using this action on CI and have to pay for 'minutes used' on your CI plan). " \
|
137
|
+
"If set to `true` and a changelog is provided, it will partially wait for the build to appear on AppStore Connect so the changelog can be set, and skip the remaining processing steps",
|
136
138
|
is_string: false,
|
137
139
|
default_value: false),
|
138
140
|
FastlaneCore::ConfigItem.new(key: :update_build_info_on_upload,
|
@@ -108,7 +108,7 @@ module Scan
|
|
108
108
|
def self.detect_simulator(devices, requested_os_type, deployment_target_key, default_device_name, simulator_type_descriptor)
|
109
109
|
require 'set'
|
110
110
|
|
111
|
-
deployment_target_version =
|
111
|
+
deployment_target_version = get_deployment_target_version(deployment_target_key)
|
112
112
|
|
113
113
|
simulators = filter_simulators(
|
114
114
|
FastlaneCore::DeviceManager.simulators(requested_os_type).tap do |array|
|
@@ -215,5 +215,10 @@ module Scan
|
|
215
215
|
Scan.config[:destination] = min_xcode8? ? ["platform=macOS"] : ["platform=OS X"]
|
216
216
|
end
|
217
217
|
end
|
218
|
+
|
219
|
+
# get deployment target version
|
220
|
+
def self.get_deployment_target_version(deployment_target_key)
|
221
|
+
Scan.config[:deployment_target_version] || Scan.project.build_settings(key: deployment_target_key) || '0'
|
222
|
+
end
|
218
223
|
end
|
219
224
|
end
|
data/scan/lib/scan/manager.rb
CHANGED
@@ -4,8 +4,13 @@ require_relative 'runner'
|
|
4
4
|
|
5
5
|
module Scan
|
6
6
|
class Manager
|
7
|
+
attr_accessor :plist_files_before
|
8
|
+
|
7
9
|
def work(options)
|
8
|
-
Scan.config = options
|
10
|
+
Scan.config = options # we set this here to auto-detect missing values, which we need later on
|
11
|
+
unless options[:derived_data_path].to_s.empty?
|
12
|
+
self.plist_files_before = test_summary_filenames(Scan.config[:derived_data_path])
|
13
|
+
end
|
9
14
|
|
10
15
|
# Also print out the path to the used Xcode installation
|
11
16
|
# We go 2 folders up, to not show "Contents/Developer/"
|
@@ -17,5 +22,17 @@ module Scan
|
|
17
22
|
|
18
23
|
return Runner.new.run
|
19
24
|
end
|
25
|
+
|
26
|
+
def test_summary_filenames(derived_data_path)
|
27
|
+
files = []
|
28
|
+
|
29
|
+
# Xcode < 10
|
30
|
+
files += Dir["#{derived_data_path}/**/Logs/Test/*TestSummaries.plist"]
|
31
|
+
|
32
|
+
# Xcode 10
|
33
|
+
files += Dir["#{derived_data_path}/**/Logs/Test/*.xcresult/TestSummaries.plist"]
|
34
|
+
|
35
|
+
return files
|
36
|
+
end
|
20
37
|
end
|
21
38
|
end
|
data/scan/lib/scan/options.rb
CHANGED
@@ -81,6 +81,11 @@ module Scan
|
|
81
81
|
description: "Enabling this option will automatically erase the simulator before running the application",
|
82
82
|
default_value: false,
|
83
83
|
type: Boolean),
|
84
|
+
FastlaneCore::ConfigItem.new(key: :disable_slide_to_type,
|
85
|
+
env_name: 'SCAN_DISABLE_SLIDE_TO_TYPE',
|
86
|
+
description: "Enabling this option will disable the simulator from showing the 'Slide to type' prompt",
|
87
|
+
default_value: true,
|
88
|
+
type: Boolean),
|
84
89
|
FastlaneCore::ConfigItem.new(key: :prelaunch_simulator,
|
85
90
|
env_name: 'SCAN_PRELAUNCH_SIMULATOR',
|
86
91
|
description: "Enabling this option will launch the first simulator prior to calling any xcodebuild command",
|
@@ -249,6 +254,11 @@ module Scan
|
|
249
254
|
default_value: false),
|
250
255
|
|
251
256
|
# concurrency
|
257
|
+
FastlaneCore::ConfigItem.new(key: :concurrent_workers,
|
258
|
+
type: Integer,
|
259
|
+
env_name: "SCAN_CONCURRENT_WORKERS",
|
260
|
+
description: "Specify the exact number of test runners that will be spawned during parallel testing. Equivalent to -parallel-testing-worker-count",
|
261
|
+
optional: true),
|
252
262
|
FastlaneCore::ConfigItem.new(key: :max_concurrent_simulators,
|
253
263
|
type: Integer,
|
254
264
|
env_name: "SCAN_MAX_CONCURRENT_SIMULATORS",
|
@@ -311,6 +321,18 @@ module Scan
|
|
311
321
|
UI.user_error!("File not found at path '#{File.expand_path(value)}'") unless File.exist?(value)
|
312
322
|
end),
|
313
323
|
|
324
|
+
# build settings
|
325
|
+
FastlaneCore::ConfigItem.new(key: :app_name,
|
326
|
+
env_name: "SCAN_APP_NAME",
|
327
|
+
optional: true,
|
328
|
+
description: "App name to use in slack message and logfile name",
|
329
|
+
is_string: true),
|
330
|
+
FastlaneCore::ConfigItem.new(key: :deployment_target_version,
|
331
|
+
env_name: "SCAN_DEPLOYMENT_TARGET_VERSION",
|
332
|
+
optional: true,
|
333
|
+
description: "Target version of the app being build or tested. Used to filter out simulator version",
|
334
|
+
is_string: true),
|
335
|
+
|
314
336
|
# slack
|
315
337
|
FastlaneCore::ConfigItem.new(key: :slack_url,
|
316
338
|
short_option: "-i",
|
@@ -381,7 +403,12 @@ module Scan
|
|
381
403
|
description: "Allows for override of the default `xcodebuild` command",
|
382
404
|
type: String,
|
383
405
|
optional: true,
|
384
|
-
default_value: "env NSUnbufferedIO=YES xcodebuild")
|
406
|
+
default_value: "env NSUnbufferedIO=YES xcodebuild"),
|
407
|
+
FastlaneCore::ConfigItem.new(key: :cloned_source_packages_path,
|
408
|
+
env_name: "SCAN_CLONED_SOURCE_PACKAGES_PATH",
|
409
|
+
description: "Sets a custom path for Swift Package Manager dependencies",
|
410
|
+
type: String,
|
411
|
+
optional: true)
|
385
412
|
|
386
413
|
]
|
387
414
|
end
|
data/scan/lib/scan/runner.rb
CHANGED
@@ -25,9 +25,17 @@ module Scan
|
|
25
25
|
def test_app
|
26
26
|
force_quit_simulator_processes if Scan.config[:force_quit_simulator]
|
27
27
|
|
28
|
-
if Scan.
|
29
|
-
Scan.
|
30
|
-
|
28
|
+
if Scan.devices
|
29
|
+
if Scan.config[:reset_simulator]
|
30
|
+
Scan.devices.each do |device|
|
31
|
+
FastlaneCore::Simulator.reset(udid: device.udid)
|
32
|
+
end
|
33
|
+
end
|
34
|
+
|
35
|
+
if Scan.config[:disable_slide_to_type]
|
36
|
+
Scan.devices.each do |device|
|
37
|
+
FastlaneCore::Simulator.disable_slide_to_type(udid: device.udid)
|
38
|
+
end
|
31
39
|
end
|
32
40
|
end
|
33
41
|
|