fastlane 2.169.0 → 2.174.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (123) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +76 -76
  3. data/deliver/lib/deliver/app_screenshot.rb +5 -7
  4. data/deliver/lib/deliver/app_screenshot_validator.rb +108 -0
  5. data/deliver/lib/deliver/commands_generator.rb +1 -1
  6. data/deliver/lib/deliver/loader.rb +13 -29
  7. data/deliver/lib/deliver/setup.rb +8 -3
  8. data/deliver/lib/deliver/upload_metadata.rb +5 -3
  9. data/fastlane/lib/fastlane/actions/add_git_tag.rb +12 -3
  10. data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +1 -0
  11. data/fastlane/lib/fastlane/actions/appetize.rb +13 -1
  12. data/fastlane/lib/fastlane/actions/artifactory.rb +36 -3
  13. data/fastlane/lib/fastlane/actions/build_and_upload_to_appetize.rb +10 -2
  14. data/fastlane/lib/fastlane/actions/build_app.rb +3 -1
  15. data/fastlane/lib/fastlane/actions/carthage.rb +22 -0
  16. data/fastlane/lib/fastlane/actions/cocoapods.rb +15 -1
  17. data/fastlane/lib/fastlane/actions/create_pull_request.rb +16 -1
  18. data/fastlane/lib/fastlane/actions/create_xcframework.rb +118 -0
  19. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +1 -1
  20. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +4 -0
  21. data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +5 -1
  22. data/fastlane/lib/fastlane/actions/download_app_privacy_details_from_app_store.rb +142 -0
  23. data/fastlane/lib/fastlane/actions/download_dsyms.rb +0 -1
  24. data/fastlane/lib/fastlane/actions/git_commit.rb +6 -2
  25. data/fastlane/lib/fastlane/actions/github_api.rb +14 -3
  26. data/fastlane/lib/fastlane/actions/nexus_upload.rb +1 -0
  27. data/fastlane/lib/fastlane/actions/onesignal.rb +13 -3
  28. data/fastlane/lib/fastlane/actions/pod_push.rb +9 -0
  29. data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +9 -1
  30. data/fastlane/lib/fastlane/actions/register_device.rb +1 -1
  31. data/fastlane/lib/fastlane/actions/register_devices.rb +2 -1
  32. data/fastlane/lib/fastlane/actions/set_github_release.rb +21 -8
  33. data/fastlane/lib/fastlane/actions/slack.rb +4 -5
  34. data/fastlane/lib/fastlane/actions/spm.rb +2 -2
  35. data/fastlane/lib/fastlane/actions/swiftlint.rb +4 -4
  36. data/fastlane/lib/fastlane/actions/upload_app_privacy_details_to_app_store.rb +291 -0
  37. data/fastlane/lib/fastlane/cli_tools_distributor.rb +3 -0
  38. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +1 -1
  39. data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +3 -0
  40. data/fastlane/lib/fastlane/version.rb +1 -1
  41. data/fastlane/swift/Actions.swift +1 -1
  42. data/fastlane/swift/Appfile.swift +1 -1
  43. data/fastlane/swift/ArgumentProcessor.swift +1 -1
  44. data/fastlane/swift/ControlCommand.swift +1 -1
  45. data/fastlane/swift/Deliverfile.swift +2 -2
  46. data/fastlane/swift/DeliverfileProtocol.swift +2 -2
  47. data/fastlane/swift/Fastlane.swift +253 -37
  48. data/fastlane/swift/Gymfile.swift +2 -2
  49. data/fastlane/swift/GymfileProtocol.swift +11 -3
  50. data/fastlane/swift/LaneFileProtocol.swift +1 -1
  51. data/fastlane/swift/MainProcess.swift +1 -1
  52. data/fastlane/swift/Matchfile.swift +2 -2
  53. data/fastlane/swift/MatchfileProtocol.swift +2 -2
  54. data/fastlane/swift/Plugins.swift +1 -1
  55. data/fastlane/swift/Precheckfile.swift +2 -2
  56. data/fastlane/swift/PrecheckfileProtocol.swift +6 -2
  57. data/fastlane/swift/RubyCommand.swift +1 -1
  58. data/fastlane/swift/RubyCommandable.swift +1 -1
  59. data/fastlane/swift/Runner.swift +2 -2
  60. data/fastlane/swift/RunnerArgument.swift +1 -1
  61. data/fastlane/swift/Scanfile.swift +2 -2
  62. data/fastlane/swift/ScanfileProtocol.swift +14 -2
  63. data/fastlane/swift/Screengrabfile.swift +2 -2
  64. data/fastlane/swift/ScreengrabfileProtocol.swift +2 -2
  65. data/fastlane/swift/Snapshotfile.swift +2 -2
  66. data/fastlane/swift/SnapshotfileProtocol.swift +15 -3
  67. data/fastlane/swift/SocketClient.swift +1 -1
  68. data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
  69. data/fastlane/swift/SocketResponse.swift +1 -1
  70. data/fastlane/swift/formatting/Brewfile.lock.json +18 -14
  71. data/fastlane/swift/main.swift +1 -1
  72. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +7 -1
  73. data/fastlane_core/lib/fastlane_core/helper.rb +2 -2
  74. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +41 -16
  75. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +3 -4
  76. data/fastlane_core/lib/fastlane_core/project.rb +41 -14
  77. data/frameit/lib/frameit/device_types.rb +7 -1
  78. data/gym/lib/gym/error_handler.rb +8 -0
  79. data/gym/lib/gym/generators/build_command_generator.rb +3 -1
  80. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +2 -2
  81. data/gym/lib/gym/options.rb +12 -2
  82. data/match/lib/match/encryption/openssl.rb +4 -2
  83. data/match/lib/match/runner.rb +1 -1
  84. data/match/lib/match/storage/git_storage.rb +14 -10
  85. data/precheck/lib/precheck/options.rb +6 -1
  86. data/precheck/lib/precheck/rule_processor.rb +1 -1
  87. data/precheck/lib/precheck/runner.rb +1 -1
  88. data/scan/lib/scan/options.rb +15 -0
  89. data/scan/lib/scan/runner.rb +6 -1
  90. data/scan/lib/scan/slack_poster.rb +4 -1
  91. data/scan/lib/scan/test_command_generator.rb +3 -1
  92. data/screengrab/lib/screengrab/runner.rb +2 -0
  93. data/sigh/lib/sigh/runner.rb +1 -1
  94. data/snapshot/lib/assets/SnapshotHelper.swift +1 -1
  95. data/snapshot/lib/snapshot/options.rb +17 -2
  96. data/snapshot/lib/snapshot/update.rb +1 -1
  97. data/spaceship/lib/spaceship/client.rb +14 -1
  98. data/spaceship/lib/spaceship/connect_api.rb +6 -0
  99. data/spaceship/lib/spaceship/connect_api/api_client.rb +17 -2
  100. data/spaceship/lib/spaceship/connect_api/models/app.rb +6 -0
  101. data/spaceship/lib/spaceship/connect_api/models/app_data_usage.rb +59 -0
  102. data/spaceship/lib/spaceship/connect_api/models/app_data_usage_category.rb +65 -0
  103. data/spaceship/lib/spaceship/connect_api/models/app_data_usage_data_protection.rb +27 -0
  104. data/spaceship/lib/spaceship/connect_api/models/app_data_usage_grouping.rb +18 -0
  105. data/spaceship/lib/spaceship/connect_api/models/app_data_usage_purposes.rb +37 -0
  106. data/spaceship/lib/spaceship/connect_api/models/app_data_usages_publish_state.rb +36 -0
  107. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +7 -1
  108. data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +9 -0
  109. data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +24 -0
  110. data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +26 -4
  111. data/spaceship/lib/spaceship/connect_api/models/device.rb +30 -0
  112. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +53 -0
  113. data/spaceship/lib/spaceship/connect_api/response.rb +3 -1
  114. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +12 -0
  115. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +103 -0
  116. data/spaceship/lib/spaceship/two_step_or_factor_client.rb +1 -0
  117. data/spaceship/lib/spaceship/upgrade_2fa_later_client.rb +91 -0
  118. metadata +45 -25
  119. data/cert/lib/cert/.options.rb.swp +0 -0
  120. data/cert/lib/cert/.runner.rb.swp +0 -0
  121. data/fastlane/lib/fastlane/actions/.download_dsyms.rb.swp +0 -0
  122. data/match/lib/match/.options.rb.swp +0 -0
  123. data/sigh/lib/sigh/.options.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
- app_info = app.fetch_live_app_info || app.fetch_edit_app_info
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,7 +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
- enabled_languages << lang_folder.language unless enabled_languages.include?(lang_folder.language)
380
+ enabled_languages << lang_folder.basename unless enabled_languages.include?(lang_folder.basename)
379
381
  end
380
382
 
381
383
  return unless enabled_languages.include?("default")
@@ -414,7 +416,7 @@ module Deliver
414
416
  # Check folder list (an empty folder signifies a language is required)
415
417
  ignore_validation = options[:ignore_language_directory_validation]
416
418
  Loader.language_folders(options[:metadata_path], ignore_validation).each do |lang_folder|
417
- enabled_languages << lang_folder.language unless enabled_languages.include?(lang_folder.language)
419
+ enabled_languages << lang_folder.basename unless enabled_languages.include?(lang_folder.basename)
418
420
  end
419
421
 
420
422
  # Mapping to strings because :default symbol can be passed in
@@ -531,7 +533,7 @@ module Deliver
531
533
 
532
534
  UI.message("Loading '#{path}'...")
533
535
  options[key] ||= {}
534
- options[key][lang_folder.language] ||= File.read(path)
536
+ options[key][lang_folder.basename] ||= File.read(path)
535
537
  end
536
538
  end
537
539
 
@@ -9,7 +9,10 @@ module Fastlane
9
9
  if options[:tag]
10
10
  tag = options[:tag]
11
11
  elsif options[:build_number]
12
- tag = "#{options[:grouping]}/#{lane_name}/#{options[:prefix]}#{options[:build_number]}#{options[:postfix]}"
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
@@ -75,6 +75,7 @@ module Fastlane
75
75
  env_name: "APP_STORE_CONNECT_API_KEY_DURATION",
76
76
  description: "The token session duration",
77
77
  optional: true,
78
+ default_value: Spaceship::ConnectAPI::Token::MAX_TOKEN_DURATION,
78
79
  type: Integer),
79
80
  FastlaneCore::ConfigItem.new(key: :in_house,
80
81
  env_name: "APP_STORE_CONNECT_API_KEY_IN_HOUSE",
@@ -31,6 +31,10 @@ module Fastlane
31
31
 
32
32
  params[:note] = options[:note] if options[:note].to_s.length > 0
33
33
 
34
+ if options[:timeout]
35
+ params[:timeout] = options[:timeout]
36
+ end
37
+
34
38
  uri = URI.parse(appetize_url(options))
35
39
  req = create_request(uri, params)
36
40
  req.basic_auth(options[:api_token], nil)
@@ -147,7 +151,15 @@ module Fastlane
147
151
  env_name: "APPETIZE_NOTE",
148
152
  description: "Notes you wish to add to the uploaded app",
149
153
  is_string: true,
150
- optional: true)
154
+ optional: true),
155
+ FastlaneCore::ConfigItem.new(key: :timeout,
156
+ env_name: "APPETIZE_TIMEOUT",
157
+ description: "The number of seconds to wait until automatically ending the session due to user inactivity. Must be 30, 60, 90, 120, 180, 300, 600, 1800, 3600 or 7200. Default is 120",
158
+ type: Integer,
159
+ optional: true,
160
+ verify_block: proc do |value|
161
+ UI.user_error!("The value provided doesn't match any of the supported options.") unless [30, 60, 90, 120, 180, 300, 600, 1800, 3600, 7200].include?(value)
162
+ end)
151
163
  ]
152
164
  end
153
165
 
@@ -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: false),
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: false),
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",
@@ -21,7 +21,8 @@ module Fastlane
21
21
  other_action.appetize(path: zipped_bundle,
22
22
  api_token: params[:api_token],
23
23
  public_key: params[:public_key],
24
- note: params[:note])
24
+ note: params[:note],
25
+ timeout: params[:timeout])
25
26
 
26
27
  public_key = Actions.lane_context[SharedValues::APPETIZE_PUBLIC_KEY]
27
28
  UI.success("Generated Public Key: #{Actions.lane_context[SharedValues::APPETIZE_PUBLIC_KEY]}")
@@ -76,7 +77,14 @@ module Fastlane
76
77
  FastlaneCore::ConfigItem.new(key: :note,
77
78
  description: "Notes you wish to add to the uploaded app",
78
79
  is_string: true,
79
- optional: true)
80
+ optional: true),
81
+ FastlaneCore::ConfigItem.new(key: :timeout,
82
+ description: "The number of seconds to wait until automatically ending the session due to user inactivity. Must be 30, 60, 90, 120, 180, 300, 600, 1800, 3600 or 7200. Default is 120",
83
+ type: Integer,
84
+ optional: true,
85
+ verify_block: proc do |value|
86
+ UI.user_error!("The value provided doesn't match any of the supported options.") unless [30, 60, 90, 120, 180, 300, 600, 1800, 3600, 7200].include?(value)
87
+ end)
80
88
  ]
81
89
  end
82
90
 
@@ -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
- bundle_id = profile["Entitlements"]["application-identifier"].gsub("#{app_id_prefix}.", "")
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}")
@@ -33,6 +33,8 @@ module Fastlane
33
33
  cmd << "--cache-builds" if params[:cache_builds]
34
34
  cmd << "--new-resolver" if params[:new_resolver]
35
35
  cmd << "--log-path #{params[:log_path]}" if params[:log_path]
36
+ cmd << "--use-xcframeworks" if params[:use_xcframeworks]
37
+ cmd << "--archive" if params[:archive]
36
38
 
37
39
  Actions.sh(cmd.join(' '))
38
40
  end
@@ -50,6 +52,14 @@ module Fastlane
50
52
  if params[:log_path] && !%w(build bootstrap update).include?(command_name)
51
53
  UI.user_error!("Log path option is available only for 'build', 'bootstrap', and 'update' command.")
52
54
  end
55
+
56
+ if params[:use_xcframeworks] && !%w(build bootstrap update).include?(command_name)
57
+ UI.user_error!("Use XCFrameworks option is available only for 'build', 'bootstrap', and 'update' command.")
58
+ end
59
+
60
+ if command_name != "build" && params[:archive]
61
+ UI.user_error!("Archive option is available only for 'build' command.")
62
+ end
53
63
  end
54
64
 
55
65
  def self.description
@@ -183,6 +193,18 @@ module Fastlane
183
193
  env_name: "FL_CARTHAGE_LOG_PATH",
184
194
  description: "Path to the xcode build output",
185
195
  optional: true),
196
+ FastlaneCore::ConfigItem.new(key: :use_xcframeworks,
197
+ env_name: "FL_CARTHAGE_USE_XCFRAMEWORKS",
198
+ description: "Create xcframework bundles instead of one framework per platform (requires Xcode 12+)",
199
+ type: Boolean,
200
+ is_string: false,
201
+ default_value: false),
202
+ FastlaneCore::ConfigItem.new(key: :archive,
203
+ env_name: "FL_CARTHAGE_ARCHIVE",
204
+ description: "Archive built frameworks from the current project",
205
+ is_string: false,
206
+ type: Boolean,
207
+ default_value: false),
186
208
  FastlaneCore::ConfigItem.new(key: :executable,
187
209
  env_name: "FL_CARTHAGE_EXECUTABLE",
188
210
  description: "Path to the `carthage` executable on your machine",
@@ -1,6 +1,7 @@
1
1
  module Fastlane
2
2
  module Actions
3
3
  class CocoapodsAction < Action
4
+ # rubocop:disable Metrics/PerceivedComplexity
4
5
  def self.run(params)
5
6
  Actions.verify_gem!('cocoapods')
6
7
  cmd = []
@@ -19,7 +20,8 @@ module Fastlane
19
20
 
20
21
  cmd << '--no-clean' unless params[:clean]
21
22
  cmd << '--no-integrate' unless params[:integrate]
22
- cmd << '--clean-install' if params[:clean_install] && pod_version(params).to_f >= 1.7
23
+ cmd << '--clean-install' if params[:clean_install] && pod_version_at_least("1.7", params)
24
+ cmd << '--allow-root' if params[:allow_root] && pod_version_at_least("1.10", params)
23
25
  cmd << '--repo-update' if params[:repo_update]
24
26
  cmd << '--silent' if params[:silent]
25
27
  cmd << '--verbose' if params[:verbose]
@@ -46,6 +48,11 @@ module Fastlane
46
48
  use_bundle_exec?(params) ? `bundle exec pod --version` : `pod --version`
47
49
  end
48
50
 
51
+ def self.pod_version_at_least(at_least_version, params)
52
+ version = pod_version(params)
53
+ return Gem::Version.new(version) >= Gem::Version.new(at_least_version)
54
+ end
55
+
49
56
  def self.call_error_callback(params, result)
50
57
  if params[:error_callback]
51
58
  Dir.chdir(FastlaneCore::FastlaneFolder.path) do
@@ -120,6 +127,13 @@ module Fastlane
120
127
  is_string: false,
121
128
  default_value: false,
122
129
  type: Boolean),
130
+ FastlaneCore::ConfigItem.new(key: :allow_root,
131
+ env_name: "FL_COCOAPODS_ALLOW_ROOT",
132
+ description: 'Allows CocoaPods to run as root',
133
+ optional: true,
134
+ is_string: false,
135
+ default_value: false,
136
+ type: Boolean),
123
137
 
124
138
  # Deprecated
125
139
  FastlaneCore::ConfigItem.new(key: :clean,
@@ -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
- optional: false),
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