fastlane 2.168.0 → 2.173.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +4 -4
- data/README.md +68 -68
- data/cert/lib/cert/options.rb +2 -2
- data/deliver/lib/deliver/app_screenshot.rb +5 -7
- data/deliver/lib/deliver/app_screenshot_validator.rb +108 -0
- data/deliver/lib/deliver/commands_generator.rb +1 -1
- data/deliver/lib/deliver/loader.rb +123 -21
- data/deliver/lib/deliver/setup.rb +8 -3
- data/deliver/lib/deliver/upload_metadata.rb +6 -10
- data/deliver/lib/deliver/upload_screenshots.rb +1 -64
- data/fastlane/lib/fastlane/actions/add_git_tag.rb +12 -3
- data/fastlane/lib/fastlane/actions/artifactory.rb +36 -3
- data/fastlane/lib/fastlane/actions/build_app.rb +3 -1
- data/fastlane/lib/fastlane/actions/create_pull_request.rb +16 -1
- data/fastlane/lib/fastlane/actions/create_xcframework.rb +118 -0
- data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +1 -1
- data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +4 -0
- data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +5 -1
- data/fastlane/lib/fastlane/actions/download_app_privacy_details_from_app_store.rb +142 -0
- data/fastlane/lib/fastlane/actions/download_dsyms.rb +0 -1
- data/fastlane/lib/fastlane/actions/git_commit.rb +6 -2
- data/fastlane/lib/fastlane/actions/github_api.rb +14 -3
- data/fastlane/lib/fastlane/actions/nexus_upload.rb +1 -0
- data/fastlane/lib/fastlane/actions/onesignal.rb +13 -3
- data/fastlane/lib/fastlane/actions/pod_push.rb +9 -0
- data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +9 -1
- data/fastlane/lib/fastlane/actions/register_device.rb +1 -1
- data/fastlane/lib/fastlane/actions/register_devices.rb +2 -1
- data/fastlane/lib/fastlane/actions/set_github_release.rb +21 -8
- data/fastlane/lib/fastlane/actions/slack.rb +4 -5
- data/fastlane/lib/fastlane/actions/spm.rb +2 -2
- data/fastlane/lib/fastlane/actions/swiftlint.rb +4 -4
- data/fastlane/lib/fastlane/actions/upload_app_privacy_details_to_app_store.rb +291 -0
- data/fastlane/lib/fastlane/actions/xcode_install.rb +8 -5
- data/fastlane/lib/fastlane/cli_tools_distributor.rb +3 -0
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +1 -1
- data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +3 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Deliverfile.swift +2 -2
- data/fastlane/swift/DeliverfileProtocol.swift +2 -2
- data/fastlane/swift/Fastlane.swift +267 -45
- data/fastlane/swift/Gymfile.swift +2 -2
- data/fastlane/swift/GymfileProtocol.swift +15 -3
- data/fastlane/swift/Matchfile.swift +2 -2
- data/fastlane/swift/MatchfileProtocol.swift +2 -2
- data/fastlane/swift/Precheckfile.swift +2 -2
- data/fastlane/swift/PrecheckfileProtocol.swift +6 -2
- data/fastlane/swift/Scanfile.swift +2 -2
- data/fastlane/swift/ScanfileProtocol.swift +18 -2
- data/fastlane/swift/Screengrabfile.swift +2 -2
- data/fastlane/swift/ScreengrabfileProtocol.swift +2 -2
- data/fastlane/swift/Snapshotfile.swift +2 -2
- data/fastlane/swift/SnapshotfileProtocol.swift +15 -3
- data/fastlane_core/lib/fastlane_core/helper.rb +2 -2
- data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +41 -16
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +3 -4
- data/fastlane_core/lib/fastlane_core/project.rb +19 -6
- data/frameit/lib/frameit/device_types.rb +7 -1
- data/gym/lib/gym/error_handler.rb +8 -0
- data/gym/lib/gym/generators/build_command_generator.rb +3 -0
- data/gym/lib/gym/generators/package_command_generator_xcode7.rb +2 -2
- data/gym/lib/gym/options.rb +19 -3
- data/match/lib/match/encryption/openssl.rb +4 -2
- data/match/lib/match/runner.rb +1 -1
- data/match/lib/match/storage/git_storage.rb +14 -10
- data/precheck/lib/precheck/options.rb +6 -1
- data/precheck/lib/precheck/rule_processor.rb +1 -1
- data/precheck/lib/precheck/runner.rb +1 -1
- data/scan/lib/scan/options.rb +22 -1
- data/scan/lib/scan/runner.rb +6 -1
- data/scan/lib/scan/slack_poster.rb +4 -1
- data/scan/lib/scan/test_command_generator.rb +3 -0
- data/screengrab/lib/screengrab/runner.rb +2 -0
- data/sigh/lib/sigh/runner.rb +1 -1
- data/snapshot/lib/assets/SnapshotHelper.swift +6 -2
- data/snapshot/lib/snapshot/options.rb +17 -2
- data/snapshot/lib/snapshot/update.rb +1 -1
- data/spaceship/lib/spaceship/client.rb +28 -1
- data/spaceship/lib/spaceship/connect_api.rb +6 -0
- data/spaceship/lib/spaceship/connect_api/api_client.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/models/app.rb +19 -4
- data/spaceship/lib/spaceship/connect_api/models/app_data_usage.rb +59 -0
- data/spaceship/lib/spaceship/connect_api/models/app_data_usage_category.rb +65 -0
- data/spaceship/lib/spaceship/connect_api/models/app_data_usage_data_protection.rb +27 -0
- data/spaceship/lib/spaceship/connect_api/models/app_data_usage_grouping.rb +18 -0
- data/spaceship/lib/spaceship/connect_api/models/app_data_usage_purposes.rb +37 -0
- data/spaceship/lib/spaceship/connect_api/models/app_data_usages_publish_state.rb +36 -0
- data/spaceship/lib/spaceship/connect_api/models/app_info.rb +1 -0
- data/spaceship/lib/spaceship/connect_api/models/app_info_localization.rb +2 -0
- data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +8 -1
- data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +9 -0
- data/spaceship/lib/spaceship/connect_api/models/device.rb +30 -0
- data/spaceship/lib/spaceship/connect_api/response.rb +3 -1
- data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +12 -0
- data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +103 -0
- data/spaceship/lib/spaceship/errors.rb +19 -0
- data/spaceship/lib/spaceship/two_step_or_factor_client.rb +19 -6
- data/spaceship/lib/spaceship/upgrade_2fa_later_client.rb +91 -0
- metadata +44 -23
- data/fastlane/lib/fastlane/actions/.download_dsyms.rb.swp +0 -0
- data/spaceship/lib/spaceship/connect_api/models/.app.rb.swp +0 -0
- data/spaceship/lib/spaceship/connect_api/models/.app_screenshot.rb.swp +0 -0
- data/spaceship/lib/spaceship/connect_api/models/.build.rb.swp +0 -0
@@ -46,7 +46,7 @@ module Deliver
|
|
46
46
|
v = app.get_latest_app_store_version(platform: platform)
|
47
47
|
|
48
48
|
metadata_path = options[:metadata_path] || File.join(deliver_path, 'metadata')
|
49
|
-
generate_metadata_files(app, v, metadata_path)
|
49
|
+
generate_metadata_files(app, v, metadata_path, options)
|
50
50
|
|
51
51
|
# Generate the final Deliverfile here
|
52
52
|
return File.read(deliverfile_path)
|
@@ -60,9 +60,14 @@ module Deliver
|
|
60
60
|
end
|
61
61
|
end
|
62
62
|
|
63
|
-
def generate_metadata_files(app, version, path)
|
63
|
+
def generate_metadata_files(app, version, path, options)
|
64
64
|
# App info localizations
|
65
|
-
|
65
|
+
if options[:use_live_version]
|
66
|
+
app_info = app.fetch_live_app_info
|
67
|
+
UI.user_error!("The option `use_live_version` was set to `true`, however no live app was found on App Store Connect.") unless app_info
|
68
|
+
else
|
69
|
+
app_info = app.fetch_edit_app_info || app.fetch_live_app_info
|
70
|
+
end
|
66
71
|
app_info_localizations = app_info.get_app_info_localizations
|
67
72
|
app_info_localizations.each do |localization|
|
68
73
|
language = localization.locale
|
@@ -1,3 +1,5 @@
|
|
1
|
+
require 'spaceship'
|
2
|
+
|
1
3
|
require_relative 'module'
|
2
4
|
require_relative 'queue_worker'
|
3
5
|
|
@@ -375,9 +377,7 @@ module Deliver
|
|
375
377
|
# Check folder list (an empty folder signifies a language is required)
|
376
378
|
ignore_validation = options[:ignore_language_directory_validation]
|
377
379
|
Loader.language_folders(options[:metadata_path], ignore_validation).each do |lang_folder|
|
378
|
-
|
379
|
-
language = File.basename(lang_folder)
|
380
|
-
enabled_languages << language unless enabled_languages.include?(language)
|
380
|
+
enabled_languages << lang_folder.basename unless enabled_languages.include?(lang_folder.basename)
|
381
381
|
end
|
382
382
|
|
383
383
|
return unless enabled_languages.include?("default")
|
@@ -416,10 +416,7 @@ module Deliver
|
|
416
416
|
# Check folder list (an empty folder signifies a language is required)
|
417
417
|
ignore_validation = options[:ignore_language_directory_validation]
|
418
418
|
Loader.language_folders(options[:metadata_path], ignore_validation).each do |lang_folder|
|
419
|
-
|
420
|
-
|
421
|
-
language = File.basename(lang_folder)
|
422
|
-
enabled_languages << language unless enabled_languages.include?(language)
|
419
|
+
enabled_languages << lang_folder.basename unless enabled_languages.include?(lang_folder.basename)
|
423
420
|
end
|
424
421
|
|
425
422
|
# Mapping to strings because :default symbol can be passed in
|
@@ -530,14 +527,13 @@ module Deliver
|
|
530
527
|
# Load localised data
|
531
528
|
ignore_validation = options[:ignore_language_directory_validation]
|
532
529
|
Loader.language_folders(options[:metadata_path], ignore_validation).each do |lang_folder|
|
533
|
-
language = File.basename(lang_folder)
|
534
530
|
(LOCALISED_VERSION_VALUES.keys + LOCALISED_APP_VALUES.keys).each do |key|
|
535
|
-
path = File.join(lang_folder, "#{key}.txt")
|
531
|
+
path = File.join(lang_folder.path, "#{key}.txt")
|
536
532
|
next unless File.exist?(path)
|
537
533
|
|
538
534
|
UI.message("Loading '#{path}'...")
|
539
535
|
options[key] ||= {}
|
540
|
-
options[key][
|
536
|
+
options[key][lang_folder.basename] ||= File.read(path)
|
541
537
|
end
|
542
538
|
end
|
543
539
|
|
@@ -251,70 +251,7 @@ module Deliver
|
|
251
251
|
|
252
252
|
def collect_screenshots(options)
|
253
253
|
return [] if options[:skip_screenshots]
|
254
|
-
return
|
255
|
-
end
|
256
|
-
|
257
|
-
def collect_screenshots_for_languages(path, ignore_validation)
|
258
|
-
screenshots = []
|
259
|
-
extensions = '{png,jpg,jpeg}'
|
260
|
-
|
261
|
-
available_languages = UploadScreenshots.available_languages.each_with_object({}) do |lang, lang_hash|
|
262
|
-
lang_hash[lang.downcase] = lang
|
263
|
-
end
|
264
|
-
|
265
|
-
Loader.language_folders(path, ignore_validation).each do |lng_folder|
|
266
|
-
language = File.basename(lng_folder)
|
267
|
-
|
268
|
-
# Check to see if we need to traverse multiple platforms or just a single platform
|
269
|
-
if language == Loader::APPLE_TV_DIR_NAME || language == Loader::IMESSAGE_DIR_NAME
|
270
|
-
screenshots.concat(collect_screenshots_for_languages(File.join(path, language), ignore_validation))
|
271
|
-
next
|
272
|
-
end
|
273
|
-
|
274
|
-
files = Dir.glob(File.join(lng_folder, "*.#{extensions}"), File::FNM_CASEFOLD).sort
|
275
|
-
next if files.count == 0
|
276
|
-
|
277
|
-
framed_screenshots_found = Dir.glob(File.join(lng_folder, "*_framed.#{extensions}"), File::FNM_CASEFOLD).count > 0
|
278
|
-
|
279
|
-
UI.important("Framed screenshots are detected! 🖼 Non-framed screenshot files may be skipped. 🏃") if framed_screenshots_found
|
280
|
-
|
281
|
-
language_dir_name = File.basename(lng_folder)
|
282
|
-
|
283
|
-
if available_languages[language_dir_name.downcase].nil?
|
284
|
-
UI.user_error!("#{language_dir_name} is not an available language. Please verify that your language codes are available in iTunesConnect. See https://developer.apple.com/library/content/documentation/LanguagesUtilities/Conceptual/iTunesConnect_Guide/Chapters/AppStoreTerritories.html for more information.")
|
285
|
-
end
|
286
|
-
|
287
|
-
language = available_languages[language_dir_name.downcase]
|
288
|
-
|
289
|
-
files.each do |file_path|
|
290
|
-
is_framed = file_path.downcase.include?("_framed.")
|
291
|
-
is_watch = file_path.downcase.include?("watch")
|
292
|
-
|
293
|
-
if framed_screenshots_found && !is_framed && !is_watch
|
294
|
-
UI.important("🏃 Skipping screenshot file: #{file_path}")
|
295
|
-
next
|
296
|
-
end
|
297
|
-
|
298
|
-
screenshots << AppScreenshot.new(file_path, language)
|
299
|
-
end
|
300
|
-
end
|
301
|
-
|
302
|
-
# Checking if the device type exists in spaceship
|
303
|
-
# Ex: iPhone 6.1 inch isn't supported in App Store Connect but need
|
304
|
-
# to have it in there for frameit support
|
305
|
-
unaccepted_device_shown = false
|
306
|
-
screenshots.select! do |screenshot|
|
307
|
-
exists = !screenshot.device_type.nil?
|
308
|
-
unless exists
|
309
|
-
UI.important("Unaccepted device screenshots are detected! 🚫 Screenshot file will be skipped. 🏃") unless unaccepted_device_shown
|
310
|
-
unaccepted_device_shown = true
|
311
|
-
|
312
|
-
UI.important("🏃 Skipping screenshot file: #{screenshot.path} - Not an accepted App Store Connect device...")
|
313
|
-
end
|
314
|
-
exists
|
315
|
-
end
|
316
|
-
|
317
|
-
return screenshots
|
254
|
+
return Loader.load_app_screenshots(options[:screenshots_path], options[:ignore_language_directory_validation])
|
318
255
|
end
|
319
256
|
|
320
257
|
# helper method so Spaceship::Tunes.client.available_languages is easier to test
|
@@ -9,7 +9,10 @@ module Fastlane
|
|
9
9
|
if options[:tag]
|
10
10
|
tag = options[:tag]
|
11
11
|
elsif options[:build_number]
|
12
|
-
|
12
|
+
tag_components = [options[:grouping]]
|
13
|
+
tag_components << lane_name if options[:includes_lane]
|
14
|
+
tag_components << "#{options[:prefix]}#{options[:build_number]}#{options[:postfix]}"
|
15
|
+
tag = tag_components.join('/')
|
13
16
|
else
|
14
17
|
UI.user_error!("No value found for 'tag' or 'build_number'. At least one of them must be provided. Note that if you do specify a tag, all other arguments are ignored.")
|
15
18
|
end
|
@@ -34,14 +37,14 @@ module Fastlane
|
|
34
37
|
def self.details
|
35
38
|
list = <<-LIST.markdown_list
|
36
39
|
`grouping` is just to keep your tags organised under one 'folder', defaults to 'builds'
|
37
|
-
`lane` is the name of the current fastlane lane
|
40
|
+
`lane` is the name of the current fastlane lane, if chosen to be included via 'includes_lane' option, which defaults to 'true'
|
38
41
|
`prefix` is anything you want to stick in front of the version number, e.g. 'v'
|
39
42
|
`postfix` is anything you want to stick at the end of the version number, e.g. '-RC1'
|
40
43
|
`build_number` is the build number, which defaults to the value emitted by the `increment_build_number` action
|
41
44
|
LIST
|
42
45
|
|
43
46
|
[
|
44
|
-
"This will automatically tag your build with the following format: `<grouping>/<lane>/<prefix><build_number>`, where:".markdown_preserve_newlines,
|
47
|
+
"This will automatically tag your build with the following format: `<grouping>/<lane>/<prefix><build_number><postfix>`, where:".markdown_preserve_newlines,
|
45
48
|
list,
|
46
49
|
"For example, for build 1234 in the 'appstore' lane, it will tag the commit with `builds/appstore/1234`."
|
47
50
|
].join("\n")
|
@@ -57,6 +60,11 @@ module Fastlane
|
|
57
60
|
env_name: "FL_GIT_TAG_GROUPING",
|
58
61
|
description: "Is used to keep your tags organised under one 'folder'",
|
59
62
|
default_value: 'builds'),
|
63
|
+
FastlaneCore::ConfigItem.new(key: :includes_lane,
|
64
|
+
env_name: "FL_GIT_TAG_INCLUDES_LANE",
|
65
|
+
description: "Whether the current lane should be included in the tag and message composition, e.g. '<grouping>/<lane>/<prefix><build_number><postfix>'",
|
66
|
+
is_string: false,
|
67
|
+
default_value: true),
|
60
68
|
FastlaneCore::ConfigItem.new(key: :prefix,
|
61
69
|
env_name: "FL_GIT_TAG_PREFIX",
|
62
70
|
description: "Anything you want to put in front of the version number (e.g. 'v')",
|
@@ -102,6 +110,7 @@ module Fastlane
|
|
102
110
|
'add_git_tag # simple tag with default values',
|
103
111
|
'add_git_tag(
|
104
112
|
grouping: "fastlane-builds",
|
113
|
+
includes_lane: true,
|
105
114
|
prefix: "v",
|
106
115
|
postfix: "-RC1",
|
107
116
|
build_number: 123
|
@@ -10,7 +10,12 @@ module Fastlane
|
|
10
10
|
Actions.verify_gem!('artifactory')
|
11
11
|
|
12
12
|
require 'artifactory'
|
13
|
+
|
14
|
+
UI.user_error!("Cannot connect to Artifactory - 'username' was provided but it's missing 'password'") if params[:username] && !params[:password]
|
15
|
+
UI.user_error!("Cannot connect to Artifactory - 'password' was provided but it's missing 'username'") if !params[:username] && params[:password]
|
16
|
+
UI.user_error!("Cannot connect to Artifactory - either 'api_key', or 'username' and 'password' must be provided") if !params[:api_key] && !params[:username]
|
13
17
|
file_path = File.absolute_path(params[:file])
|
18
|
+
|
14
19
|
if File.exist?(file_path)
|
15
20
|
client = connect_to_artifactory(params)
|
16
21
|
artifact = Artifactory::Resource::Artifact.new
|
@@ -37,7 +42,7 @@ module Fastlane
|
|
37
42
|
end
|
38
43
|
|
39
44
|
def self.connect_to_artifactory(params)
|
40
|
-
config_keys = [:endpoint, :username, :password, :ssl_pem_file, :ssl_verify, :proxy_username, :proxy_password, :proxy_address, :proxy_port, :read_timeout]
|
45
|
+
config_keys = [:endpoint, :username, :password, :api_key, :ssl_pem_file, :ssl_verify, :proxy_username, :proxy_password, :proxy_address, :proxy_port, :read_timeout]
|
41
46
|
config = params.values.select do |key|
|
42
47
|
config_keys.include?(key)
|
43
48
|
end
|
@@ -48,6 +53,10 @@ module Fastlane
|
|
48
53
|
'This action uploads an artifact to artifactory'
|
49
54
|
end
|
50
55
|
|
56
|
+
def self.details
|
57
|
+
'Connect to the artifactory server using either a username/password or an api_key'
|
58
|
+
end
|
59
|
+
|
51
60
|
def self.is_supported?(platform)
|
52
61
|
true
|
53
62
|
end
|
@@ -72,6 +81,13 @@ module Fastlane
|
|
72
81
|
file: "example.ipa", # File to upload
|
73
82
|
repo: "mobile_artifacts", # Artifactory repo
|
74
83
|
repo_path: "/ios/appname/example-major.minor.ipa" # Path to place the artifact including its filename
|
84
|
+
)',
|
85
|
+
'artifactory(
|
86
|
+
api_key: "api_key",
|
87
|
+
endpoint: "https://artifactory.example.com/artifactory/",
|
88
|
+
file: "example.ipa", # File to upload
|
89
|
+
repo: "mobile_artifacts", # Artifactory repo
|
90
|
+
repo_path: "/ios/appname/example-major.minor.ipa" # Path to place the artifact including its filename
|
75
91
|
)'
|
76
92
|
]
|
77
93
|
end
|
@@ -101,12 +117,29 @@ module Fastlane
|
|
101
117
|
FastlaneCore::ConfigItem.new(key: :username,
|
102
118
|
env_name: "FL_ARTIFACTORY_USERNAME",
|
103
119
|
description: "Artifactory username",
|
104
|
-
optional:
|
120
|
+
optional: true,
|
121
|
+
conflicting_options: [:api_key],
|
122
|
+
conflict_block: proc do |value|
|
123
|
+
UI.user_error!("You can't use option '#{value.key}' along with 'username'")
|
124
|
+
end),
|
105
125
|
FastlaneCore::ConfigItem.new(key: :password,
|
106
126
|
env_name: "FL_ARTIFACTORY_PASSWORD",
|
107
127
|
description: "Artifactory password",
|
108
128
|
sensitive: true,
|
109
|
-
optional:
|
129
|
+
optional: true,
|
130
|
+
conflicting_options: [:api_key],
|
131
|
+
conflict_block: proc do |value|
|
132
|
+
UI.user_error!("You can't use option '#{value.key}' along with 'password'")
|
133
|
+
end),
|
134
|
+
FastlaneCore::ConfigItem.new(key: :api_key,
|
135
|
+
env_name: "FL_ARTIFACTORY_API_KEY",
|
136
|
+
description: "Artifactory API key",
|
137
|
+
sensitive: true,
|
138
|
+
optional: true,
|
139
|
+
conflicting_options: [:username, :password],
|
140
|
+
conflict_block: proc do |value|
|
141
|
+
UI.user_error!("You can't use option '#{value.key}' along with 'api_key'")
|
142
|
+
end),
|
110
143
|
FastlaneCore::ConfigItem.new(key: :properties,
|
111
144
|
env_name: "FL_ARTIFACTORY_PROPERTIES",
|
112
145
|
description: "Artifact properties hash",
|
@@ -8,6 +8,7 @@ module Fastlane
|
|
8
8
|
end
|
9
9
|
|
10
10
|
class BuildAppAction < Action
|
11
|
+
# rubocop:disable Metrics/PerceivedComplexity
|
11
12
|
def self.run(values)
|
12
13
|
require 'gym'
|
13
14
|
|
@@ -50,7 +51,8 @@ module Fastlane
|
|
50
51
|
begin
|
51
52
|
profile = FastlaneCore::ProvisioningProfile.parse(profile_path)
|
52
53
|
app_id_prefix = profile["ApplicationIdentifierPrefix"].first
|
53
|
-
|
54
|
+
entitlements = profile["Entitlements"]
|
55
|
+
bundle_id = (entitlements["application-identifier"] || entitlements["com.apple.application-identifier"]).gsub("#{app_id_prefix}.", "")
|
54
56
|
values[:export_options][:provisioningProfiles][bundle_id] = profile["Name"]
|
55
57
|
rescue => ex
|
56
58
|
UI.error("Couldn't load profile at path: #{profile_path}")
|
@@ -20,6 +20,7 @@ module Fastlane
|
|
20
20
|
GithubApiAction.run(
|
21
21
|
server_url: params[:api_url],
|
22
22
|
api_token: params[:api_token],
|
23
|
+
api_bearer: params[:api_bearer],
|
23
24
|
http_method: 'POST',
|
24
25
|
path: "repos/#{params[:repo]}/pulls",
|
25
26
|
body: payload,
|
@@ -60,6 +61,7 @@ module Fastlane
|
|
60
61
|
GithubApiAction.run(
|
61
62
|
server_url: params[:api_url],
|
62
63
|
api_token: params[:api_token],
|
64
|
+
api_bearer: params[:api_bearer],
|
63
65
|
http_method: 'PATCH',
|
64
66
|
path: "repos/#{params[:repo]}/issues/#{number}",
|
65
67
|
body: payload,
|
@@ -79,6 +81,7 @@ module Fastlane
|
|
79
81
|
GithubApiAction.run(
|
80
82
|
server_url: params[:api_url],
|
81
83
|
api_token: params[:api_token],
|
84
|
+
api_bearer: params[:api_bearer],
|
82
85
|
http_method: 'POST',
|
83
86
|
path: "repos/#{params[:repo]}/issues/#{number}/assignees",
|
84
87
|
body: payload,
|
@@ -103,6 +106,7 @@ module Fastlane
|
|
103
106
|
GithubApiAction.run(
|
104
107
|
server_url: params[:api_url],
|
105
108
|
api_token: params[:api_token],
|
109
|
+
api_bearer: params[:api_bearer],
|
106
110
|
http_method: 'POST',
|
107
111
|
path: "repos/#{params[:repo]}/pulls/#{number}/requested_reviewers",
|
108
112
|
body: payload,
|
@@ -124,6 +128,7 @@ module Fastlane
|
|
124
128
|
GithubApiAction.run(
|
125
129
|
server_url: params[:api_url],
|
126
130
|
api_token: params[:api_token],
|
131
|
+
api_bearer: params[:api_bearer],
|
127
132
|
http_method: 'PATCH',
|
128
133
|
path: "repos/#{params[:repo]}/issues/#{number}",
|
129
134
|
body: payload,
|
@@ -161,7 +166,17 @@ module Fastlane
|
|
161
166
|
default_value: ENV["GITHUB_API_TOKEN"],
|
162
167
|
default_value_dynamic: true,
|
163
168
|
is_string: true,
|
164
|
-
|
169
|
+
conflicting_options: [:api_bearer],
|
170
|
+
optional: true),
|
171
|
+
FastlaneCore::ConfigItem.new(key: :api_bearer,
|
172
|
+
env_name: "GITHUB_PULL_REQUEST_API_BEARER",
|
173
|
+
description: "Use a Bearer authorization token. Usually generated by Github Apps, e.g. GitHub Actions GITHUB_TOKEN environment variable",
|
174
|
+
sensitive: true,
|
175
|
+
code_gen_sensitive: true,
|
176
|
+
is_string: true,
|
177
|
+
conflicting_options: [:api_token],
|
178
|
+
optional: true,
|
179
|
+
default_value: nil),
|
165
180
|
FastlaneCore::ConfigItem.new(key: :repo,
|
166
181
|
env_name: "GITHUB_PULL_REQUEST_REPO",
|
167
182
|
description: "The name of the repository you want to submit the pull request to",
|
@@ -0,0 +1,118 @@
|
|
1
|
+
module Fastlane
|
2
|
+
module Actions
|
3
|
+
module SharedValues
|
4
|
+
XCFRAMEWORK_PATH ||= :XCFRAMEWORK_PATH
|
5
|
+
end
|
6
|
+
|
7
|
+
class CreateXcframeworkAction < Action
|
8
|
+
def self.run(params)
|
9
|
+
UI.user_error!("Please provide either :frameworks or :libraries to be packaged into the xcframework") unless params[:frameworks] || params[:libraries]
|
10
|
+
|
11
|
+
create_command = ['xcodebuild', '-create-xcframework']
|
12
|
+
create_command << params[:frameworks].map { |framework| ['-framework', "\"#{framework}\""] }.flatten if params[:frameworks]
|
13
|
+
create_command << params[:libraries].map { |library, headers| ['-library', "\"#{library}\""] + (headers.empty? ? [] : ['-headers', "\"#{headers}\""]) } if params[:libraries]
|
14
|
+
create_command << ['-output', "\"#{params[:output]}\""]
|
15
|
+
create_command << ['-allow-internal-distribution'] if params[:allow_internal_distribution]
|
16
|
+
|
17
|
+
Actions.lane_context[SharedValues::XCFRAMEWORK_PATH] = params[:output]
|
18
|
+
|
19
|
+
sh(create_command)
|
20
|
+
end
|
21
|
+
|
22
|
+
#####################################################
|
23
|
+
# @!group Documentation
|
24
|
+
#####################################################
|
25
|
+
|
26
|
+
def self.description
|
27
|
+
"Package multiple build configs of a library/framework into a single xcframework"
|
28
|
+
end
|
29
|
+
|
30
|
+
def self.details
|
31
|
+
<<~DETAILS
|
32
|
+
Utility for packaging multiple build configurations of a given library
|
33
|
+
or framework into a single xcframework.
|
34
|
+
|
35
|
+
If you want to package several frameworks just provide an array containing
|
36
|
+
the list of frameworks to be packaged using the :frameworks parameter.
|
37
|
+
|
38
|
+
If you want to package several libraries with their corresponding headers
|
39
|
+
provide a hash containing the library as the key and the directory containing
|
40
|
+
its headers as the value (or an empty string if there are no headers associated
|
41
|
+
with the provided library).
|
42
|
+
|
43
|
+
Finally specify the location of the xcframework to be generated using the :output
|
44
|
+
parameter.
|
45
|
+
DETAILS
|
46
|
+
end
|
47
|
+
|
48
|
+
def self.available_options
|
49
|
+
[
|
50
|
+
FastlaneCore::ConfigItem.new(key: :frameworks,
|
51
|
+
env_name: "FL_CREATE_XCFRAMEWORK_FRAMEWORKS",
|
52
|
+
description: "Frameworks to add to the target xcframework",
|
53
|
+
type: Array,
|
54
|
+
optional: true,
|
55
|
+
conflicting_options: [:libraries],
|
56
|
+
verify_block: proc do |value|
|
57
|
+
value.each do |framework|
|
58
|
+
UI.user_error!("#{framework} doesn't end with '.framework'. Is this really a framework?") unless framework.end_with?('.framework')
|
59
|
+
UI.user_error!("Couldn't find framework at #{framework}") unless File.exist?(framework)
|
60
|
+
UI.user_error!("#{framework} doesn't seem to be a framework") unless File.directory?(framework)
|
61
|
+
end
|
62
|
+
end),
|
63
|
+
FastlaneCore::ConfigItem.new(key: :libraries,
|
64
|
+
env_name: "FL_CREATE_XCFRAMEWORK_LIBRARIES",
|
65
|
+
description: "Libraries to add to the target xcframework, with their corresponding headers",
|
66
|
+
type: Hash,
|
67
|
+
optional: true,
|
68
|
+
conflicting_options: [:frameworks],
|
69
|
+
verify_block: proc do |value|
|
70
|
+
value.each do |library, headers|
|
71
|
+
UI.user_error!("Couldn't find library at #{library}") unless File.exist?(library)
|
72
|
+
UI.user_error!("#{headers} doesn't exist or is not a directory") unless headers.empty? || File.directory?(headers)
|
73
|
+
end
|
74
|
+
end),
|
75
|
+
FastlaneCore::ConfigItem.new(key: :output,
|
76
|
+
env_name: "FL_CREATE_XCFRAMEWORK_OUTPUT",
|
77
|
+
description: "The path to write the xcframework to",
|
78
|
+
type: String,
|
79
|
+
optional: false),
|
80
|
+
FastlaneCore::ConfigItem.new(key: :allow_internal_distribution,
|
81
|
+
env_name: "FL_CREATE_XCFRAMEWORK_ALLOW_INTERNAL_DISTRIBUTION",
|
82
|
+
description: "Specifies that the created xcframework contains information not suitable for public distribution",
|
83
|
+
type: Boolean,
|
84
|
+
optional: true,
|
85
|
+
default_value: false)
|
86
|
+
]
|
87
|
+
end
|
88
|
+
|
89
|
+
def self.output
|
90
|
+
[
|
91
|
+
['XCFRAMEWORK_PATH', 'Location of the generated xcframework']
|
92
|
+
]
|
93
|
+
end
|
94
|
+
|
95
|
+
def self.return_value
|
96
|
+
end
|
97
|
+
|
98
|
+
def self.example_code
|
99
|
+
[
|
100
|
+
"create_xcframework(frameworks: ['FrameworkA.framework', 'FrameworkB.framework'], output: 'UniversalFramework.xcframework')",
|
101
|
+
"create_xcframework(libraries: { 'LibraryA.so' => '', 'LibraryB.so' => 'LibraryBHeaders'}, output: 'UniversalFramework.xcframework')"
|
102
|
+
]
|
103
|
+
end
|
104
|
+
|
105
|
+
def self.category
|
106
|
+
:building
|
107
|
+
end
|
108
|
+
|
109
|
+
def self.authors
|
110
|
+
["jgongo"]
|
111
|
+
end
|
112
|
+
|
113
|
+
def self.is_supported?(platform)
|
114
|
+
[:ios, :mac].include?(platform)
|
115
|
+
end
|
116
|
+
end
|
117
|
+
end
|
118
|
+
end
|