fastlane 2.173.0 → 2.194.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (391) hide show
  1. checksums.yaml +4 -4
  2. data/LICENSE +1 -1
  3. data/README.md +105 -85
  4. data/cert/lib/cert/commands_generator.rb +2 -1
  5. data/cert/lib/cert/options.rb +4 -3
  6. data/cert/lib/cert/runner.rb +7 -7
  7. data/deliver/lib/assets/summary.html.erb +10 -10
  8. data/deliver/lib/deliver/app_screenshot.rb +8 -3
  9. data/deliver/lib/deliver/app_screenshot_iterator.rb +2 -2
  10. data/deliver/lib/deliver/commands_generator.rb +3 -2
  11. data/deliver/lib/deliver/detect_values.rb +5 -3
  12. data/deliver/lib/deliver/download_screenshots.rb +2 -3
  13. data/deliver/lib/deliver/html_generator.rb +2 -2
  14. data/deliver/lib/deliver/languages.rb +1 -1
  15. data/deliver/lib/deliver/loader.rb +1 -1
  16. data/deliver/lib/deliver/module.rb +6 -0
  17. data/deliver/lib/deliver/options.rb +48 -56
  18. data/deliver/lib/deliver/runner.rb +28 -15
  19. data/deliver/lib/deliver/screenshot_comparable.rb +62 -0
  20. data/deliver/lib/deliver/setup.rb +1 -2
  21. data/deliver/lib/deliver/submit_for_review.rb +4 -4
  22. data/deliver/lib/deliver/sync_screenshots.rb +200 -0
  23. data/deliver/lib/deliver/upload_metadata.rb +26 -11
  24. data/deliver/lib/deliver/upload_price_tier.rb +1 -1
  25. data/deliver/lib/deliver/upload_screenshots.rb +13 -12
  26. data/fastlane/lib/assets/completions/completion.bash +4 -1
  27. data/fastlane/lib/assets/completions/completion.zsh +6 -5
  28. data/{spaceship/lib/spaceship/connect_api/models/.app_store_version_submission.rb.swp → fastlane/lib/fastlane/actions/.notarize.rb.swp} +0 -0
  29. data/fastlane/lib/fastlane/actions/actions_helper.rb +2 -2
  30. data/fastlane/lib/fastlane/actions/adb.rb +2 -5
  31. data/fastlane/lib/fastlane/actions/adb_devices.rb +0 -1
  32. data/fastlane/lib/fastlane/actions/add_git_tag.rb +4 -4
  33. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +18 -18
  34. data/fastlane/lib/fastlane/actions/app_store_connect_api_key.rb +21 -7
  35. data/fastlane/lib/fastlane/actions/appaloosa.rb +7 -2
  36. data/fastlane/lib/fastlane/actions/appetize.rb +13 -8
  37. data/fastlane/lib/fastlane/actions/appetize_viewing_url_generator.rb +0 -11
  38. data/fastlane/lib/fastlane/actions/appium.rb +40 -65
  39. data/fastlane/lib/fastlane/actions/appledoc.rb +45 -45
  40. data/fastlane/lib/fastlane/actions/apteligent.rb +3 -2
  41. data/fastlane/lib/fastlane/actions/artifactory.rb +5 -6
  42. data/fastlane/lib/fastlane/actions/automatic_code_signing.rb +7 -13
  43. data/fastlane/lib/fastlane/actions/backup_file.rb +1 -1
  44. data/fastlane/lib/fastlane/actions/backup_xcarchive.rb +3 -3
  45. data/fastlane/lib/fastlane/actions/badge.rb +9 -13
  46. data/fastlane/lib/fastlane/actions/build_and_upload_to_appetize.rb +11 -5
  47. data/fastlane/lib/fastlane/actions/build_app.rb +4 -0
  48. data/fastlane/lib/fastlane/actions/bundle_install.rb +21 -11
  49. data/fastlane/lib/fastlane/actions/carthage.rb +22 -14
  50. data/fastlane/lib/fastlane/actions/changelog_from_git_commits.rb +8 -17
  51. data/fastlane/lib/fastlane/actions/chatwork.rb +3 -2
  52. data/fastlane/lib/fastlane/actions/check_app_store_metadata.rb +9 -1
  53. data/fastlane/lib/fastlane/actions/clean_build_artifacts.rb +0 -1
  54. data/fastlane/lib/fastlane/actions/clean_cocoapods_cache.rb +25 -2
  55. data/fastlane/lib/fastlane/actions/clipboard.rb +3 -6
  56. data/fastlane/lib/fastlane/actions/cloc.rb +9 -13
  57. data/fastlane/lib/fastlane/actions/cocoapods.rb +23 -15
  58. data/fastlane/lib/fastlane/actions/commit_github_file.rb +12 -4
  59. data/fastlane/lib/fastlane/actions/commit_version_bump.rb +6 -7
  60. data/fastlane/lib/fastlane/actions/copy_artifacts.rb +3 -4
  61. data/fastlane/lib/fastlane/actions/crashlytics.rb +7 -11
  62. data/fastlane/lib/fastlane/actions/create_app_on_managed_play_store.rb +70 -76
  63. data/fastlane/lib/fastlane/actions/create_keychain.rb +13 -11
  64. data/fastlane/lib/fastlane/actions/create_pull_request.rb +0 -9
  65. data/fastlane/lib/fastlane/actions/create_xcframework.rb +102 -17
  66. data/fastlane/lib/fastlane/actions/danger.rb +13 -12
  67. data/fastlane/lib/fastlane/actions/deploygate.rb +1 -2
  68. data/fastlane/lib/fastlane/actions/docs/build_app.md +1 -1
  69. data/fastlane/lib/fastlane/actions/docs/capture_android_screenshots.md +29 -30
  70. data/fastlane/lib/fastlane/actions/docs/capture_ios_screenshots.md +3 -3
  71. data/fastlane/lib/fastlane/actions/docs/create_app_online.md +171 -67
  72. data/fastlane/lib/fastlane/actions/docs/frame_screenshots.md +19 -2
  73. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +8 -2
  74. data/fastlane/lib/fastlane/actions/docs/upload_to_app_store.md.erb +37 -18
  75. data/fastlane/lib/fastlane/actions/docs/upload_to_play_store.md +2 -1
  76. data/fastlane/lib/fastlane/actions/docs/upload_to_testflight.md +10 -4
  77. data/fastlane/lib/fastlane/actions/download_app_privacy_details_from_app_store.rb +1 -1
  78. data/fastlane/lib/fastlane/actions/download_dsyms.rb +8 -19
  79. data/fastlane/lib/fastlane/actions/dsym_zip.rb +1 -1
  80. data/fastlane/lib/fastlane/actions/ensure_env_vars.rb +2 -6
  81. data/fastlane/lib/fastlane/actions/ensure_git_branch.rb +0 -1
  82. data/fastlane/lib/fastlane/actions/ensure_git_status_clean.rb +3 -4
  83. data/fastlane/lib/fastlane/actions/ensure_no_debug_code.rb +3 -5
  84. data/fastlane/lib/fastlane/actions/ensure_xcode_version.rb +1 -2
  85. data/fastlane/lib/fastlane/actions/environment_variable.rb +13 -21
  86. data/fastlane/lib/fastlane/actions/erb.rb +2 -5
  87. data/fastlane/lib/fastlane/actions/get_build_number_repository.rb +1 -1
  88. data/fastlane/lib/fastlane/actions/get_certificates.rb +5 -1
  89. data/fastlane/lib/fastlane/actions/get_github_release.rb +11 -1
  90. data/fastlane/lib/fastlane/actions/get_ipa_info_plist_value.rb +0 -1
  91. data/fastlane/lib/fastlane/actions/get_managed_play_store_publishing_rights.rb +32 -35
  92. data/fastlane/lib/fastlane/actions/get_provisioning_profile.rb +10 -2
  93. data/fastlane/lib/fastlane/actions/get_push_certificate.rb +1 -1
  94. data/fastlane/lib/fastlane/actions/get_version_number.rb +17 -10
  95. data/fastlane/lib/fastlane/actions/git_add.rb +5 -10
  96. data/fastlane/lib/fastlane/actions/git_branch.rb +4 -10
  97. data/fastlane/lib/fastlane/actions/git_commit.rb +6 -8
  98. data/fastlane/lib/fastlane/actions/git_pull.rb +4 -10
  99. data/fastlane/lib/fastlane/actions/git_remote_branch.rb +57 -0
  100. data/fastlane/lib/fastlane/actions/git_submodule_update.rb +16 -8
  101. data/fastlane/lib/fastlane/actions/git_tag_exists.rb +4 -0
  102. data/fastlane/lib/fastlane/actions/github_api.rb +4 -6
  103. data/fastlane/lib/fastlane/actions/gradle.rb +13 -21
  104. data/fastlane/lib/fastlane/actions/hg_commit_version_bump.rb +1 -1
  105. data/fastlane/lib/fastlane/actions/hg_push.rb +1 -1
  106. data/fastlane/lib/fastlane/actions/hipchat.rb +6 -6
  107. data/fastlane/lib/fastlane/actions/hockey.rb +5 -12
  108. data/fastlane/lib/fastlane/actions/ifttt.rb +3 -6
  109. data/fastlane/lib/fastlane/actions/import_from_git.rb +7 -9
  110. data/fastlane/lib/fastlane/actions/increment_build_number.rb +8 -2
  111. data/fastlane/lib/fastlane/actions/install_on_device.rb +3 -6
  112. data/fastlane/lib/fastlane/actions/install_provisioning_profile.rb +4 -0
  113. data/fastlane/lib/fastlane/actions/installr.rb +22 -25
  114. data/fastlane/lib/fastlane/actions/ipa.rb +2 -2
  115. data/fastlane/lib/fastlane/actions/jazzy.rb +11 -8
  116. data/fastlane/lib/fastlane/actions/jira.rb +61 -14
  117. data/fastlane/lib/fastlane/actions/latest_testflight_build_number.rb +7 -7
  118. data/fastlane/lib/fastlane/actions/lcov.rb +0 -4
  119. data/fastlane/lib/fastlane/actions/mailgun.rb +21 -27
  120. data/fastlane/lib/fastlane/actions/make_changelog_from_jenkins.rb +1 -1
  121. data/fastlane/lib/fastlane/actions/match_nuke.rb +59 -0
  122. data/fastlane/lib/fastlane/actions/modify_services.rb +59 -24
  123. data/fastlane/lib/fastlane/actions/nexus_upload.rb +2 -2
  124. data/fastlane/lib/fastlane/actions/notarize.rb +181 -52
  125. data/fastlane/lib/fastlane/actions/notification.rb +1 -1
  126. data/fastlane/lib/fastlane/actions/number_of_commits.rb +1 -1
  127. data/fastlane/lib/fastlane/actions/oclint.rb +15 -14
  128. data/fastlane/lib/fastlane/actions/pod_push.rb +0 -2
  129. data/fastlane/lib/fastlane/actions/podio_item.rb +0 -7
  130. data/fastlane/lib/fastlane/actions/prompt.rb +3 -4
  131. data/fastlane/lib/fastlane/actions/push_git_tags.rb +2 -2
  132. data/fastlane/lib/fastlane/actions/push_to_git_remote.rb +6 -3
  133. data/fastlane/lib/fastlane/actions/puts.rb +1 -2
  134. data/fastlane/lib/fastlane/actions/register_device.rb +10 -13
  135. data/fastlane/lib/fastlane/actions/register_devices.rb +10 -14
  136. data/fastlane/lib/fastlane/actions/reset_git_repo.rb +5 -8
  137. data/fastlane/lib/fastlane/actions/reset_simulator_contents.rb +0 -2
  138. data/fastlane/lib/fastlane/actions/resign.rb +2 -9
  139. data/fastlane/lib/fastlane/actions/restore_file.rb +1 -1
  140. data/fastlane/lib/fastlane/actions/rsync.rb +3 -6
  141. data/fastlane/lib/fastlane/actions/run_tests.rb +1 -1
  142. data/fastlane/lib/fastlane/actions/s3.rb +1 -1
  143. data/fastlane/lib/fastlane/actions/say.rb +2 -3
  144. data/fastlane/lib/fastlane/actions/scp.rb +4 -10
  145. data/fastlane/lib/fastlane/actions/set_build_number_repository.rb +1 -1
  146. data/fastlane/lib/fastlane/actions/set_changelog.rb +11 -14
  147. data/fastlane/lib/fastlane/actions/set_github_release.rb +2 -8
  148. data/fastlane/lib/fastlane/actions/set_info_plist_value.rb +1 -1
  149. data/fastlane/lib/fastlane/actions/set_pod_key.rb +3 -4
  150. data/fastlane/lib/fastlane/actions/setup_ci.rb +1 -2
  151. data/fastlane/lib/fastlane/actions/setup_circle_ci.rb +1 -1
  152. data/fastlane/lib/fastlane/actions/setup_jenkins.rb +7 -12
  153. data/fastlane/lib/fastlane/actions/setup_travis.rb +1 -1
  154. data/fastlane/lib/fastlane/actions/sh.rb +2 -4
  155. data/fastlane/lib/fastlane/actions/slack.rb +161 -141
  156. data/fastlane/lib/fastlane/actions/slather.rb +9 -19
  157. data/fastlane/lib/fastlane/actions/sonar.rb +12 -19
  158. data/fastlane/lib/fastlane/actions/sourcedocs.rb +128 -0
  159. data/fastlane/lib/fastlane/actions/spaceship_logs.rb +1 -1
  160. data/fastlane/lib/fastlane/actions/splunkmint.rb +2 -2
  161. data/fastlane/lib/fastlane/actions/spm.rb +3 -3
  162. data/fastlane/lib/fastlane/actions/ssh.rb +5 -10
  163. data/fastlane/lib/fastlane/actions/swiftlint.rb +18 -16
  164. data/fastlane/lib/fastlane/actions/sync_code_signing.rb +7 -2
  165. data/fastlane/lib/fastlane/actions/testfairy.rb +0 -1
  166. data/fastlane/lib/fastlane/actions/tryouts.rb +2 -3
  167. data/fastlane/lib/fastlane/actions/twitter.rb +0 -5
  168. data/fastlane/lib/fastlane/actions/unlock_keychain.rb +3 -3
  169. data/fastlane/lib/fastlane/actions/update_app_group_identifiers.rb +1 -4
  170. data/fastlane/lib/fastlane/actions/update_code_signing_settings.rb +8 -15
  171. data/fastlane/lib/fastlane/actions/update_fastlane.rb +2 -2
  172. data/fastlane/lib/fastlane/actions/update_icloud_container_identifiers.rb +1 -4
  173. data/fastlane/lib/fastlane/actions/update_info_plist.rb +1 -1
  174. data/fastlane/lib/fastlane/actions/update_keychain_access_groups.rb +1 -4
  175. data/fastlane/lib/fastlane/actions/update_plist.rb +1 -1
  176. data/fastlane/lib/fastlane/actions/update_project_provisioning.rb +3 -4
  177. data/fastlane/lib/fastlane/actions/update_urban_airship_configuration.rb +0 -1
  178. data/fastlane/lib/fastlane/actions/update_url_schemes.rb +15 -26
  179. data/fastlane/lib/fastlane/actions/upload_app_privacy_details_to_app_store.rb +1 -2
  180. data/fastlane/lib/fastlane/actions/upload_symbols_to_crashlytics.rb +8 -7
  181. data/fastlane/lib/fastlane/actions/upload_symbols_to_sentry.rb +3 -10
  182. data/fastlane/lib/fastlane/actions/upload_to_app_store.rb +5 -1
  183. data/fastlane/lib/fastlane/actions/upload_to_testflight.rb +10 -3
  184. data/fastlane/lib/fastlane/actions/validate_play_store_json_key.rb +40 -44
  185. data/fastlane/lib/fastlane/actions/version_get_podspec.rb +1 -2
  186. data/fastlane/lib/fastlane/actions/xcode_server_get_assets.rb +3 -3
  187. data/fastlane/lib/fastlane/actions/xcodebuild.rb +5 -5
  188. data/fastlane/lib/fastlane/actions/zip.rb +86 -21
  189. data/fastlane/lib/fastlane/cli_tools_distributor.rb +1 -1
  190. data/fastlane/lib/fastlane/commands_generator.rb +2 -1
  191. data/fastlane/lib/fastlane/documentation/actions_list.rb +2 -2
  192. data/fastlane/lib/fastlane/documentation/docs_generator.rb +1 -1
  193. data/fastlane/lib/fastlane/documentation/markdown_docs_generator.rb +12 -6
  194. data/fastlane/lib/fastlane/environment_printer.rb +1 -0
  195. data/fastlane/lib/fastlane/erb_template_helper.rb +7 -1
  196. data/fastlane/lib/fastlane/fast_file.rb +19 -7
  197. data/fastlane/lib/fastlane/fastlane_require.rb +7 -1
  198. data/fastlane/lib/fastlane/features.rb +3 -0
  199. data/fastlane/lib/fastlane/helper/adb_helper.rb +1 -1
  200. data/fastlane/lib/fastlane/helper/crashlytics_helper.rb +4 -4
  201. data/fastlane/lib/fastlane/helper/gem_helper.rb +2 -2
  202. data/fastlane/lib/fastlane/helper/git_helper.rb +34 -5
  203. data/fastlane/lib/fastlane/lane_manager.rb +3 -2
  204. data/fastlane/lib/fastlane/notification/slack.rb +56 -0
  205. data/fastlane/lib/fastlane/plugins/plugin_fetcher.rb +1 -2
  206. data/fastlane/lib/fastlane/plugins/plugin_info.rb +2 -2
  207. data/fastlane/lib/fastlane/plugins/plugin_info_collector.rb +1 -2
  208. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +2 -3
  209. data/fastlane/lib/fastlane/plugins/template/%gem_name%.gemspec.erb +7 -6
  210. data/fastlane/lib/fastlane/plugins/template/.circleci/config.yml +1 -1
  211. data/fastlane/lib/fastlane/plugins/template/.github/workflows/test.yml +1 -1
  212. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +30 -35
  213. data/fastlane/lib/fastlane/plugins/template/spec/spec_helper.rb.erb +1 -1
  214. data/fastlane/lib/fastlane/setup/setup.rb +23 -10
  215. data/fastlane/lib/fastlane/setup/setup_ios.rb +3 -3
  216. data/fastlane/lib/fastlane/swift_fastlane_function.rb +43 -15
  217. data/fastlane/lib/fastlane/swift_runner_upgrader.rb +2 -0
  218. data/fastlane/lib/fastlane/version.rb +2 -2
  219. data/fastlane/swift/Actions.swift +1 -1
  220. data/fastlane/swift/Appfile.swift +1 -1
  221. data/fastlane/swift/ArgumentProcessor.swift +1 -1
  222. data/fastlane/swift/ControlCommand.swift +1 -1
  223. data/fastlane/swift/Deliverfile.swift +1 -1
  224. data/fastlane/swift/DeliverfileProtocol.swift +27 -23
  225. data/fastlane/swift/Fastlane.swift +7993 -4352
  226. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +4 -0
  227. data/fastlane/swift/Gymfile.swift +1 -1
  228. data/fastlane/swift/GymfileProtocol.swift +1 -1
  229. data/fastlane/swift/LaneFileProtocol.swift +10 -4
  230. data/fastlane/swift/MainProcess.swift +1 -1
  231. data/fastlane/swift/Matchfile.swift +1 -1
  232. data/fastlane/swift/MatchfileProtocol.swift +3 -3
  233. data/fastlane/swift/OptionalConfigValue.swift +101 -0
  234. data/fastlane/swift/Plugins.swift +1 -1
  235. data/fastlane/swift/Precheckfile.swift +1 -1
  236. data/fastlane/swift/PrecheckfileProtocol.swift +4 -4
  237. data/fastlane/swift/RubyCommand.swift +2 -2
  238. data/fastlane/swift/RubyCommandable.swift +1 -1
  239. data/fastlane/swift/Runner.swift +2 -2
  240. data/fastlane/swift/RunnerArgument.swift +1 -1
  241. data/fastlane/swift/Scanfile.swift +1 -1
  242. data/fastlane/swift/ScanfileProtocol.swift +17 -1
  243. data/fastlane/swift/Screengrabfile.swift +1 -1
  244. data/fastlane/swift/ScreengrabfileProtocol.swift +4 -4
  245. data/fastlane/swift/Snapshotfile.swift +1 -1
  246. data/fastlane/swift/SnapshotfileProtocol.swift +5 -1
  247. data/fastlane/swift/SocketClient.swift +3 -2
  248. data/fastlane/swift/SocketClientDelegateProtocol.swift +1 -1
  249. data/fastlane/swift/SocketResponse.swift +5 -3
  250. data/fastlane/swift/formatting/Brewfile.lock.json +37 -21
  251. data/fastlane/swift/main.swift +1 -1
  252. data/fastlane/swift/upgrade_manifest.json +1 -1
  253. data/fastlane_core/lib/fastlane_core/build_watcher.rb +113 -17
  254. data/fastlane_core/lib/fastlane_core/clipboard.rb +20 -0
  255. data/fastlane_core/lib/fastlane_core/command_executor.rb +3 -9
  256. data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +6 -1
  257. data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +41 -3
  258. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +14 -8
  259. data/fastlane_core/lib/fastlane_core/device_manager.rb +1 -1
  260. data/fastlane_core/lib/fastlane_core/helper.rb +66 -10
  261. data/fastlane_core/lib/fastlane_core/ipa_upload_package_builder.rb +3 -2
  262. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +14 -8
  263. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +12 -5
  264. data/fastlane_core/lib/fastlane_core/languages.rb +2 -2
  265. data/fastlane_core/lib/fastlane_core/pkg_file_analyser.rb +5 -0
  266. data/fastlane_core/lib/fastlane_core/pkg_upload_package_builder.rb +3 -2
  267. data/fastlane_core/lib/fastlane_core/print_table.rb +5 -3
  268. data/fastlane_core/lib/fastlane_core/project.rb +30 -23
  269. data/{deliver/lib/deliver → fastlane_core/lib/fastlane_core}/queue_worker.rb +4 -4
  270. data/fastlane_core/lib/fastlane_core/swag.rb +1 -1
  271. data/fastlane_core/lib/fastlane_core/ui/disable_colors.rb +1 -0
  272. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +41 -0
  273. data/fastlane_core/lib/fastlane_core/ui/help.erb +35 -0
  274. data/fastlane_core/lib/fastlane_core/ui/help_formatter.rb +16 -0
  275. data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +16 -2
  276. data/fastlane_core/lib/fastlane_core/ui/interface.rb +1 -1
  277. data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +2 -2
  278. data/fastlane_core/lib/fastlane_core.rb +22 -20
  279. data/frameit/lib/frameit/commands_generator.rb +2 -1
  280. data/frameit/lib/frameit/config_parser.rb +2 -2
  281. data/frameit/lib/frameit/frame_downloader.rb +2 -1
  282. data/gym/lib/gym/code_signing_mapping.rb +2 -2
  283. data/gym/lib/gym/commands_generator.rb +2 -1
  284. data/gym/lib/gym/generators/package_command_generator.rb +4 -0
  285. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +19 -13
  286. data/gym/lib/gym/runner.rb +15 -4
  287. data/match/lib/match/change_password.rb +3 -3
  288. data/match/lib/match/commands_generator.rb +2 -1
  289. data/match/lib/match/encryption/interface.rb +1 -1
  290. data/match/lib/match/encryption/openssl.rb +2 -2
  291. data/match/lib/match/importer.rb +9 -10
  292. data/match/lib/match/migrate.rb +2 -3
  293. data/match/lib/match/module.rb +1 -0
  294. data/match/lib/match/nuke.rb +10 -10
  295. data/match/lib/match/options.rb +5 -4
  296. data/match/lib/match/runner.rb +12 -12
  297. data/match/lib/match/spaceship_ensure.rb +3 -0
  298. data/match/lib/match/storage/google_cloud_storage.rb +2 -2
  299. data/match/lib/match/storage/s3_storage.rb +2 -2
  300. data/pem/lib/pem/commands_generator.rb +2 -1
  301. data/pilot/lib/pilot/build_manager.rb +45 -15
  302. data/pilot/lib/pilot/commands_generator.rb +2 -1
  303. data/pilot/lib/pilot/manager.rb +14 -9
  304. data/pilot/lib/pilot/options.rb +39 -11
  305. data/pilot/lib/pilot/tester_exporter.rb +0 -1
  306. data/pilot/lib/pilot/tester_manager.rb +0 -1
  307. data/pilot/lib/pilot.rb +0 -1
  308. data/precheck/lib/precheck/commands_generator.rb +2 -1
  309. data/precheck/lib/precheck/module.rb +2 -0
  310. data/precheck/lib/precheck/options.rb +7 -6
  311. data/precheck/lib/precheck/runner.rb +13 -8
  312. data/produce/lib/produce/commands_generator.rb +129 -28
  313. data/produce/lib/produce/developer_center.rb +42 -4
  314. data/produce/lib/produce/options.rb +1 -1
  315. data/produce/lib/produce/service.rb +285 -179
  316. data/scan/lib/scan/commands_generator.rb +2 -1
  317. data/scan/lib/scan/detect_values.rb +26 -14
  318. data/scan/lib/scan/module.rb +1 -0
  319. data/scan/lib/scan/options.rb +32 -6
  320. data/scan/lib/scan/runner.rb +81 -1
  321. data/scan/lib/scan/test_command_generator.rb +37 -12
  322. data/scan/lib/scan/xcpretty_reporter_options_generator.rb +1 -1
  323. data/screengrab/lib/screengrab/android_environment.rb +5 -53
  324. data/screengrab/lib/screengrab/commands_generator.rb +2 -1
  325. data/screengrab/lib/screengrab/dependency_checker.rb +0 -20
  326. data/screengrab/lib/screengrab/options.rb +5 -2
  327. data/screengrab/lib/screengrab/runner.rb +110 -109
  328. data/sigh/lib/assets/resign.sh +81 -61
  329. data/sigh/lib/sigh/commands_generator.rb +2 -1
  330. data/sigh/lib/sigh/download_all.rb +4 -8
  331. data/sigh/lib/sigh/options.rb +6 -4
  332. data/sigh/lib/sigh/runner.rb +8 -8
  333. data/snapshot/lib/assets/SnapfileTemplate +3 -2
  334. data/snapshot/lib/assets/SnapfileTemplate.swift +2 -1
  335. data/snapshot/lib/assets/SnapshotHelper.swift +14 -10
  336. data/snapshot/lib/snapshot/commands_generator.rb +3 -1
  337. data/snapshot/lib/snapshot/options.rb +5 -0
  338. data/snapshot/lib/snapshot/reports_generator.rb +7 -1
  339. data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
  340. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher.rb +1 -1
  341. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +12 -6
  342. data/snapshot/lib/snapshot/test_command_generator.rb +17 -3
  343. data/spaceship/README.md +4 -14
  344. data/spaceship/lib/spaceship/base.rb +2 -2
  345. data/spaceship/lib/spaceship/client.rb +37 -20
  346. data/spaceship/lib/spaceship/commands_generator.rb +4 -2
  347. data/spaceship/lib/spaceship/connect_api/api_client.rb +80 -8
  348. data/spaceship/lib/spaceship/connect_api/model.rb +1 -1
  349. data/spaceship/lib/spaceship/connect_api/models/age_rating_declaration.rb +36 -4
  350. data/spaceship/lib/spaceship/connect_api/models/app.rb +10 -2
  351. data/spaceship/lib/spaceship/connect_api/models/app_info.rb +10 -0
  352. data/spaceship/lib/spaceship/connect_api/models/app_preview_set.rb +5 -0
  353. data/spaceship/lib/spaceship/connect_api/models/app_screenshot.rb +1 -1
  354. data/spaceship/lib/spaceship/connect_api/models/app_screenshot_set.rb +5 -0
  355. data/spaceship/lib/spaceship/connect_api/models/app_store_version.rb +2 -3
  356. data/spaceship/lib/spaceship/connect_api/models/app_store_version_localization.rb +6 -0
  357. data/spaceship/lib/spaceship/connect_api/models/beta_group.rb +8 -1
  358. data/spaceship/lib/spaceship/connect_api/models/beta_tester.rb +3 -1
  359. data/spaceship/lib/spaceship/connect_api/models/build.rb +14 -1
  360. data/spaceship/lib/spaceship/connect_api/models/build_beta_detail.rb +8 -0
  361. data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +32 -0
  362. data/spaceship/lib/spaceship/connect_api/models/bundle_id_capability.rb +84 -21
  363. data/spaceship/lib/spaceship/connect_api/models/capabilities.rb +27 -0
  364. data/spaceship/lib/spaceship/connect_api/models/profile.rb +6 -0
  365. data/spaceship/lib/spaceship/connect_api/models/user.rb +17 -3
  366. data/spaceship/lib/spaceship/connect_api/models/user_invitation.rb +37 -3
  367. data/spaceship/lib/spaceship/connect_api/provisioning/provisioning.rb +104 -2
  368. data/spaceship/lib/spaceship/connect_api/testflight/client.rb +3 -0
  369. data/spaceship/lib/spaceship/connect_api/testflight/testflight.rb +72 -5
  370. data/spaceship/lib/spaceship/connect_api/token.rb +19 -4
  371. data/spaceship/lib/spaceship/connect_api/tunes/client.rb +3 -0
  372. data/spaceship/lib/spaceship/connect_api/tunes/tunes.rb +19 -2
  373. data/spaceship/lib/spaceship/connect_api/users/client.rb +3 -0
  374. data/spaceship/lib/spaceship/connect_api/users/users.rb +58 -3
  375. data/spaceship/lib/spaceship/connect_api.rb +1 -0
  376. data/spaceship/lib/spaceship/playground.rb +2 -2
  377. data/spaceship/lib/spaceship/spaceauth_runner.rb +38 -15
  378. data/spaceship/lib/spaceship/tunes/members.rb +1 -1
  379. data/spaceship/lib/spaceship/tunes/tunes_client.rb +5 -2
  380. data/spaceship/lib/spaceship/two_step_or_factor_client.rb +42 -29
  381. data/spaceship/lib/spaceship/ui.rb +2 -2
  382. data/supply/lib/supply/client.rb +45 -4
  383. data/supply/lib/supply/commands_generator.rb +2 -1
  384. data/supply/lib/supply/options.rb +14 -2
  385. data/supply/lib/supply/uploader.rb +13 -9
  386. metadata +119 -98
  387. data/fastlane/lib/fastlane/.erb_template_helper.rb.swp +0 -0
  388. data/fastlane/lib/fastlane/actions/.git_commit.rb.swp +0 -0
  389. data/pilot/lib/pilot/features.rb +0 -0
  390. data/pilot/lib/pilot/tester_util.rb +0 -0
  391. data/spaceship/lib/spaceship/.DS_Store +0 -0
@@ -3,10 +3,15 @@ require 'spaceship/connect_api'
3
3
  require_relative 'ui/ui'
4
4
 
5
5
  module FastlaneCore
6
+ class BuildWatcherError < StandardError
7
+ end
8
+
6
9
  class BuildWatcher
10
+ VersionMatches = Struct.new(:version, :builds)
11
+
7
12
  class << self
8
13
  # @return The build we waited for. This method will always return a build
9
- def wait_for_build_processing_to_be_complete(app_id: nil, platform: nil, train_version: nil, app_version: nil, build_version: nil, poll_interval: 10, strict_build_watch: false, return_when_build_appears: false, return_spaceship_testflight_build: true, select_latest: false)
14
+ def wait_for_build_processing_to_be_complete(app_id: nil, platform: nil, train_version: nil, app_version: nil, build_version: nil, poll_interval: 10, timeout_duration: nil, strict_build_watch: false, return_when_build_appears: false, return_spaceship_testflight_build: true, select_latest: false, wait_for_build_beta_detail_processing: false)
10
15
  # Warn about train_version being removed in the future
11
16
  if train_version
12
17
  UI.deprecated(":train_version is no longer a used argument on FastlaneCore::BuildWatcher. Please use :app_version instead.")
@@ -21,22 +26,35 @@ module FastlaneCore
21
26
  platform = Spaceship::ConnectAPI::Platform.map(platform) if platform
22
27
  UI.message("Waiting for processing on... app_id: #{app_id}, app_version: #{app_version}, build_version: #{build_version}, platform: #{platform}")
23
28
 
29
+ build_watching_start_time = Time.new
30
+ unless timeout_duration.nil?
31
+ end_time = build_watching_start_time + timeout_duration
32
+ UI.message("Will timeout watching build after #{timeout_duration} seconds around #{end_time}...")
33
+ end
34
+
24
35
  showed_info = false
25
36
  loop do
26
- matched_build = matching_build(watched_app_version: app_version, watched_build_version: build_version, app_id: app_id, platform: platform, select_latest: select_latest)
37
+ matched_build, app_version_queried = matching_build(watched_app_version: app_version, watched_build_version: build_version, app_id: app_id, platform: platform, select_latest: select_latest)
27
38
 
28
39
  if matched_build.nil? && !showed_info
29
40
  UI.important("Read more information on why this build isn't showing up yet - https://github.com/fastlane/fastlane/issues/14997")
30
41
  showed_info = true
31
42
  end
32
43
 
33
- report_status(build: matched_build)
44
+ report_status(build: matched_build, wait_for_build_beta_detail_processing: wait_for_build_beta_detail_processing)
34
45
 
35
46
  # Processing of builds by AppStoreConnect can be a very time consuming task and will
36
47
  # block the worker running this task until it is completed. In some cases,
37
48
  # having a build resource appear in AppStoreConnect (matched_build) may be enough (i.e. setting a changelog)
38
49
  # so here we may choose to skip the full processing of the build if return_when_build_appears is true
39
- if matched_build && (return_when_build_appears || matched_build.processed?)
50
+ if matched_build && (return_when_build_appears || processed?(build: matched_build, wait_for_build_beta_detail_processing: wait_for_build_beta_detail_processing))
51
+
52
+ if !app_version.nil? && app_version != app_version_queried
53
+ UI.important("App version is #{app_version} but build was found while querying #{app_version_queried}")
54
+ UI.important("This shouldn't be an issue as Apple sees #{app_version} and #{app_version_queried} as equal")
55
+ UI.important("See docs for more info - https://developer.apple.com/library/archive/documentation/General/Reference/InfoPlistKeyReference/Articles/CoreFoundationKeys.html#//apple_ref/doc/uid/20001431-102364")
56
+ end
57
+
40
58
  if return_spaceship_testflight_build
41
59
  return matched_build.to_testflight_build
42
60
  else
@@ -44,6 +62,9 @@ module FastlaneCore
44
62
  end
45
63
  end
46
64
 
65
+ # Before next poll, force stop build watching, if we exceeded the 'timeout_duration' waiting time
66
+ force_stop_build_watching_if_required(start_time: build_watching_start_time, timeout_duration: timeout_duration)
67
+
47
68
  sleep(poll_interval)
48
69
  end
49
70
  end
@@ -60,37 +81,112 @@ module FastlaneCore
60
81
  watched_app_version = remove_version_leading_zeros(version: watched_app_version)
61
82
  watched_build_version = remove_version_leading_zeros(version: watched_build_version)
62
83
 
63
- matched_builds = Spaceship::ConnectAPI::Build.all(
64
- app_id: app_id,
65
- version: watched_app_version,
66
- build_number: watched_build_version,
67
- platform: platform
68
- )
84
+ # App Store Connect will allow users to upload X.Y is the same as X.Y.0 and treat them as the same version
85
+ # However, only the first uploaded version format will be the one that is queryable
86
+ # This could lead to BuildWatcher never finding X.Y.0 if X.Y was upoaded first as X.Y will only yield results
87
+ #
88
+ # This will add an additional request to search for both X.Y and X.Y.0 but
89
+ # will give preference to the version format specified passed in
90
+ watched_app_version_alternate = alternate_version(watched_app_version)
91
+ versions = [watched_app_version, watched_app_version_alternate].compact
92
+
93
+ if versions.empty?
94
+ if select_latest
95
+ message = watched_build_version.nil? ? "Searching for the latest build" : "Searching for the latest build with build number: #{watched_build_version}"
96
+ UI.message(message)
97
+ versions = [nil]
98
+ else
99
+ raise BuildWatcherError.new, "There is no app version to watch"
100
+ end
101
+ end
102
+
103
+ version_matches = versions.map do |version|
104
+ match = VersionMatches.new
105
+ match.version = version
106
+ match.builds = Spaceship::ConnectAPI::Build.all(
107
+ app_id: app_id,
108
+ version: version,
109
+ build_number: watched_build_version,
110
+ platform: platform
111
+ )
112
+
113
+ match
114
+ end.flatten
69
115
 
70
116
  # Raise error if more than 1 build is returned
71
117
  # This should never happen but need to inform the user if it does
118
+ matched_builds = version_matches.map(&:builds).flatten
72
119
  if matched_builds.size > 1 && !select_latest
73
120
  error_builds = matched_builds.map do |build|
74
121
  "#{build.app_version}(#{build.version}) for #{build.platform} - #{build.processing_state}"
75
122
  end.join("\n")
76
- error_message = "FastlaneCore::BuildWatcher found more than 1 matching build: \n#{error_builds}"
77
- UI.crash!(error_message)
123
+ error_message = "Found more than 1 matching build: \n#{error_builds}"
124
+ raise BuildWatcherError.new, error_message
78
125
  end
79
126
 
80
- matched_build = matched_builds.first
127
+ version_match = version_matches.reject do |match|
128
+ match.builds.empty?
129
+ end.first
130
+ matched_build = version_match&.builds&.first
81
131
 
82
- return matched_build
132
+ return matched_build, version_match&.version
83
133
  end
84
134
 
85
- def report_status(build: nil)
86
- if build && !build.processed?
135
+ def alternate_version(version)
136
+ return nil if version.nil?
137
+
138
+ version_info = Gem::Version.new(version)
139
+ if version_info.segments.size == 3 && version_info.segments[2] == 0
140
+ return version_info.segments[0..1].join(".")
141
+ elsif version_info.segments.size == 2
142
+ return "#{version}.0"
143
+ end
144
+
145
+ return nil
146
+ end
147
+
148
+ def processed?(build: nil, wait_for_build_beta_detail_processing: false)
149
+ return false unless build
150
+
151
+ is_processed = build.processed?
152
+
153
+ # App Store Connect API has multiple build processing states
154
+ # builds have one processing status
155
+ # buildBetaDetails have two processing statues (internal and external testing)
156
+ #
157
+ # If set, this method will only return true if all three statuses are complete
158
+ if wait_for_build_beta_detail_processing
159
+ is_processed &&= (build.build_beta_detail&.processed? || false)
160
+ end
161
+
162
+ return is_processed
163
+ end
164
+
165
+ def report_status(build: nil, wait_for_build_beta_detail_processing: false)
166
+ is_processed = processed?(build: build, wait_for_build_beta_detail_processing: wait_for_build_beta_detail_processing)
167
+
168
+ if build && !is_processed
87
169
  UI.message("Waiting for App Store Connect to finish processing the new build (#{build.app_version} - #{build.version}) for #{build.platform}")
88
- elsif build && build.processed?
170
+ elsif build && is_processed
89
171
  UI.success("Successfully finished processing the build #{build.app_version} - #{build.version} for #{build.platform}")
90
172
  else
91
173
  UI.message("Waiting for the build to show up in the build list - this may take a few minutes (check your email for processing issues if this continues)")
92
174
  end
93
175
  end
176
+
177
+ def force_stop_build_watching_if_required(start_time: nil, timeout_duration: nil)
178
+ return if start_time.nil? || timeout_duration.nil? # keep watching build for App Store Connect processing
179
+
180
+ current_time = Time.new
181
+ end_time = start_time + timeout_duration
182
+ pending_duration = end_time - current_time
183
+
184
+ if current_time > end_time
185
+ UI.crash!("FastlaneCore::BuildWatcher exceeded the '#{timeout_duration.to_i}' seconds, Stopping now!")
186
+ else
187
+ UI.verbose("Will timeout watching build after pending #{pending_duration.to_i} seconds around #{end_time}...")
188
+ end
189
+ end
94
190
  end
95
191
  end
96
192
  end
@@ -0,0 +1,20 @@
1
+ require 'fastlane_core'
2
+ require 'open3'
3
+
4
+ module FastlaneCore
5
+ class Clipboard
6
+ def self.copy(content: nil)
7
+ return UI.crash!("'pbcopy' or 'pbpaste' command not found.") unless is_supported?
8
+ Open3.popen3('pbcopy') { |input, _, _| input << content }
9
+ end
10
+
11
+ def self.paste
12
+ return UI.crash!("'pbcopy' or 'pbpaste' command not found.") unless is_supported?
13
+ return `pbpaste`
14
+ end
15
+
16
+ def self.is_supported?
17
+ return `which pbcopy`.length > 0 && `which pbpaste`.length > 0
18
+ end
19
+ end
20
+ end
@@ -13,16 +13,10 @@ module FastlaneCore
13
13
  #
14
14
  # Derived from https://stackoverflow.com/a/5471032/3005
15
15
  def which(cmd)
16
- # PATHEXT contains the list of file extensions that Windows considers executable, semicolon separated.
17
- # e.g. ".COM;.EXE;.BAT;.CMD"
18
- exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : []
19
- exts << '' # Always have an empty string (= no file extension)
20
-
21
16
  ENV['PATH'].split(File::PATH_SEPARATOR).each do |path|
22
- exts.each do |ext|
23
- cmd_path = File.join(path, "#{cmd}#{ext}")
24
- return cmd_path if Helper.executable?(cmd_path)
25
- end
17
+ cmd_path = File.join(path, cmd)
18
+ executable_path = Helper.get_executable_path(cmd_path)
19
+ return executable_path if Helper.executable?(executable_path)
26
20
  end
27
21
 
28
22
  return nil
@@ -30,6 +30,11 @@ module FastlaneCore
30
30
  type = option.is_string ? String : nil
31
31
  end
32
32
 
33
+ # OptionParser doesn't like symbol but a symbol and string can be easily cast with `to_sym` and `to_s`
34
+ if type == Symbol
35
+ type = String
36
+ end
37
+
33
38
  # Boolean is a fastlane thing, it's either TrueClass, or FalseClass, but we won't know
34
39
  # that until runtime, so nil is the best we get
35
40
  if type == Fastlane::Boolean
@@ -67,7 +72,7 @@ module FastlaneCore
67
72
  long_switch = "--#{option.key} #{value_appendix}"
68
73
 
69
74
  description = option.description
70
- description += " (#{option.env_name})" unless option.env_name.to_s.empty?
75
+ description += " (#{option.env_names.join(', ')})" unless option.env_names.empty?
71
76
 
72
77
  # We compact this array here to remove the short_switch variable if it is nil.
73
78
  # Passing a nil value to global_option has been shown to create problems with
@@ -12,6 +12,9 @@ module FastlaneCore
12
12
  # [String] the name of the environment variable, which is only used if no other values were found
13
13
  attr_accessor :env_name
14
14
 
15
+ # [Array] the names of the environment variables, which is only used if no other values were found
16
+ attr_accessor :env_names
17
+
15
18
  # [String] A description shown to the user
16
19
  attr_accessor :description
17
20
 
@@ -71,6 +74,7 @@ module FastlaneCore
71
74
  # Creates a new option
72
75
  # @param key (Symbol) the key which is used as command parameters or key in the fastlane tools
73
76
  # @param env_name (String) the name of the environment variable, which is only used if no other values were found
77
+ # @param env_names (Array) the names of the environment variables, which is only used if no other values were found
74
78
  # @param description (String) A description shown to the user
75
79
  # @param short_option (String) A string of length 1 which is used for the command parameters (e.g. -f)
76
80
  # @param default_value the value which is used if there was no given values and no environment values
@@ -88,8 +92,10 @@ module FastlaneCore
88
92
  # @param sensitive (Boolean) Set if the variable is sensitive, such as a password or API token, to prevent echoing when prompted for the parameter
89
93
  # @param display_in_shell (Boolean) Set if the variable can be used from shell
90
94
  # rubocop:disable Metrics/ParameterLists
95
+ # rubocop:disable Metrics/PerceivedComplexity
91
96
  def initialize(key: nil,
92
97
  env_name: nil,
98
+ env_names: nil,
93
99
  description: nil,
94
100
  short_option: nil,
95
101
  default_value: nil,
@@ -109,6 +115,11 @@ module FastlaneCore
109
115
  UI.user_error!("key must be a symbol") unless key.kind_of?(Symbol)
110
116
  UI.user_error!("env_name must be a String") unless (env_name || '').kind_of?(String)
111
117
 
118
+ UI.user_error!("env_names must be an Array") unless (env_names || []).kind_of?(Array)
119
+ (env_names || []).each do |name|
120
+ UI.user_error!("env_names must only contain String") unless (name || '').kind_of?(String)
121
+ end
122
+
112
123
  if short_option
113
124
  UI.user_error!("short_option for key :#{key} must of type String") unless short_option.kind_of?(String)
114
125
  UI.user_error!("short_option for key :#{key} must be a string of length 1") unless short_option.delete('-').length == 1
@@ -138,6 +149,7 @@ module FastlaneCore
138
149
 
139
150
  @key = key
140
151
  @env_name = env_name
152
+ @env_names = [env_name].compact + (env_names || [])
141
153
  @description = description
142
154
  @short_option = short_option
143
155
  @default_value = default_value
@@ -160,6 +172,7 @@ module FastlaneCore
160
172
 
161
173
  update_code_gen_default_value_if_able!
162
174
  end
175
+ # rubocop:enable Metrics/PerceivedComplexity
163
176
  # rubocop:enable Metrics/ParameterLists
164
177
 
165
178
  # if code_gen_default_value is nil, use the default value if it isn't a `code_gen_sensitive` value
@@ -203,6 +216,17 @@ module FastlaneCore
203
216
  end
204
217
  end
205
218
 
219
+ def ensure_array_type_passes_validation(value)
220
+ if @skip_type_validation
221
+ return
222
+ end
223
+
224
+ # Arrays can be an either be an array or string that gets split by comma in auto_convert_type
225
+ if !value.kind_of?(Array) && !value.kind_of?(String)
226
+ UI.user_error!("'#{self.key}' value must be either `Array` or `comma-separated String`! Found #{value.class} instead.")
227
+ end
228
+ end
229
+
206
230
  # Make sure, the value is valid (based on the verify block)
207
231
  # Raises an exception if the value is invalid
208
232
  def valid?(value)
@@ -212,6 +236,8 @@ module FastlaneCore
212
236
  # Verify that value is the type that we're expecting, if we are expecting a type
213
237
  if data_type == Fastlane::Boolean
214
238
  ensure_boolean_type_passes_validation(value)
239
+ elsif data_type == Array
240
+ ensure_array_type_passes_validation(value)
215
241
  else
216
242
  ensure_generic_type_passes_validation(value)
217
243
  end
@@ -228,6 +254,16 @@ module FastlaneCore
228
254
  true
229
255
  end
230
256
 
257
+ def fetch_env_value
258
+ env_names.each do |name|
259
+ next if ENV[name].nil?
260
+ # verify! before using (see https://github.com/fastlane/fastlane/issues/14449)
261
+ return ENV[name].dup if verify!(auto_convert_value(ENV[name]))
262
+ end
263
+
264
+ return nil
265
+ end
266
+
231
267
  # rubocop:disable Metrics/PerceivedComplexity
232
268
  # Returns an updated value type (if necessary)
233
269
  def auto_convert_value(value)
@@ -239,6 +275,8 @@ module FastlaneCore
239
275
  return value.to_i if value.to_i.to_s == value.to_s
240
276
  elsif data_type == Float
241
277
  return value.to_f if value.to_f.to_s == value.to_s
278
+ elsif data_type == Symbol
279
+ return value.to_sym if value.to_sym.to_s == value.to_s
242
280
  elsif allow_shell_conversion
243
281
  return value.shelljoin if value.kind_of?(Array)
244
282
  return value.map { |k, v| "#{k.to_s.shellescape}=#{v.shellescape}" }.join(' ') if value.kind_of?(Hash)
@@ -249,11 +287,11 @@ module FastlaneCore
249
287
  rescue JSON::ParserError
250
288
  end
251
289
  elsif data_type != String
252
- # Special treatment if the user specified true, false or YES, NO
290
+ # Special treatment if the user specified true, false, on, off or YES, NO
253
291
  # There is no boolean type, so we just do it here
254
- if %w(YES yes true TRUE).include?(value)
292
+ if %w(yes YES true TRUE on ON).include?(value)
255
293
  return true
256
- elsif %w(NO no false FALSE).include?(value)
294
+ elsif %w(no NO false FALSE off OFF).include?(value)
257
295
  return false
258
296
  end
259
297
  end
@@ -208,19 +208,19 @@ module FastlaneCore
208
208
  #####################################################
209
209
 
210
210
  # Returns the value for a certain key. fastlane_core tries to fetch the value from different sources
211
- # if 'ask' is true and the value is not present, the user will be prompted to provide a value
211
+ # if 'ask' is true and the value is not present, the user will be prompted to provide a value if optional
212
+ # if 'force_ask' is true, the option is not required to be optional to ask
212
213
  # rubocop:disable Metrics/PerceivedComplexity
213
- def fetch(key, ask: true)
214
- UI.crash!("Key '#{key}' must be a symbol. Example :app_id.") unless key.kind_of?(Symbol)
214
+ def fetch(key, ask: true, force_ask: false)
215
+ UI.crash!("Key '#{key}' must be a symbol. Example :#{key}") unless key.kind_of?(Symbol)
215
216
 
216
217
  option = verify_options_key!(key)
217
218
 
218
219
  # Same order as https://docs.fastlane.tools/advanced/#priorities-of-parameters-and-options
219
220
  value = if @values.key?(key) && !@values[key].nil?
220
221
  @values[key]
221
- elsif option.env_name && !ENV[option.env_name].nil?
222
- # verify! before using (see https://github.com/fastlane/fastlane/issues/14449)
223
- ENV[option.env_name].dup if option.verify!(option.auto_convert_value(ENV[option.env_name]))
222
+ elsif (env_value = option.fetch_env_value)
223
+ env_value
224
224
  elsif self.config_file_options.key?(key)
225
225
  self.config_file_options[key]
226
226
  else
@@ -229,7 +229,7 @@ module FastlaneCore
229
229
 
230
230
  value = option.auto_convert_value(value)
231
231
  value = nil if value.nil? && !option.string? # by default boolean flags are false
232
- return value unless value.nil? && !option.optional && ask
232
+ return value unless value.nil? && (!option.optional || force_ask) && ask
233
233
 
234
234
  # fallback to asking
235
235
  if Helper.test? || !UI.interactive?
@@ -243,11 +243,17 @@ module FastlaneCore
243
243
  while value.nil?
244
244
  UI.important("To not be asked about this value, you can specify it using '#{option.key}'") if ENV["FASTLANE_ONBOARDING_IN_PROCESS"].to_s.length == 0
245
245
  value = option.sensitive ? UI.password("#{option.description}: ") : UI.input("#{option.description}: ")
246
+
247
+ # ConfigItem allows to specify a type for the item but UI.password and
248
+ # UI.input return String values. Try to convert the String input to
249
+ # the option's type before passing it along.
250
+ value = option.auto_convert_value(value)
251
+
246
252
  # Also store this value to use it from now on
247
253
  begin
248
254
  set(key, value)
249
255
  rescue => ex
250
- puts(ex)
256
+ UI.error(ex)
251
257
  value = nil
252
258
  end
253
259
  end
@@ -118,7 +118,7 @@ module FastlaneCore
118
118
  discover_devices(child_item, device_types, discovered_device_udids)
119
119
  end
120
120
 
121
- is_supported_device = device_types.any? { |device_type| usb_item['_name'] == device_type }
121
+ is_supported_device = device_types.any?(usb_item['_name'])
122
122
  serial_num = usb_item['serial_num'] || ''
123
123
  has_serial_number = serial_num.length == 40 || serial_num.length == 24
124
124
 
@@ -75,7 +75,7 @@ module FastlaneCore
75
75
 
76
76
  # Check for Jenkins, Travis CI, ... environment variables
77
77
  ['JENKINS_HOME', 'JENKINS_URL', 'TRAVIS', 'CI', 'APPCENTER_BUILD_ID', 'TEAMCITY_VERSION', 'GO_PIPELINE_NAME', 'bamboo_buildKey', 'GITLAB_CI', 'XCS', 'TF_BUILD', 'GITHUB_ACTION', 'GITHUB_ACTIONS', 'BITRISE_IO', 'BUDDY'].each do |current|
78
- return true if ENV.key?(current)
78
+ return true if FastlaneCore::Env.truthy?(current)
79
79
  end
80
80
  return false
81
81
  end
@@ -167,11 +167,23 @@ module FastlaneCore
167
167
  @xcode_version
168
168
  end
169
169
 
170
- # @return true if Xcode version is higher than 8.3
170
+ # @return true if installed Xcode version is 'greater than or equal to' the input parameter version
171
171
  def self.xcode_at_least?(version)
172
- FastlaneCore::UI.user_error!("Unable to locate Xcode. Please make sure to have Xcode installed on your machine") if xcode_version.nil?
173
- v = xcode_version
174
- Gem::Version.new(v) >= Gem::Version.new(version)
172
+ installed_xcode_version = xcode_version
173
+ UI.user_error!("Unable to locate Xcode. Please make sure to have Xcode installed on your machine") if installed_xcode_version.nil?
174
+ Gem::Version.new(installed_xcode_version) >= Gem::Version.new(version)
175
+ end
176
+
177
+ # Swift
178
+ #
179
+
180
+ # @return Swift version
181
+ def self.swift_version
182
+ if system("which swift > /dev/null 2>&1")
183
+ output = `swift --version`
184
+ return output.split("\n").first.match(/version ([0-9.]+)/).captures.first
185
+ end
186
+ return nil
175
187
  end
176
188
 
177
189
  # iTMSTransporter
@@ -368,8 +380,37 @@ module FastlaneCore
368
380
 
369
381
  # checks if a given path is an executable file
370
382
  def self.executable?(cmd_path)
371
- # no executable files on Windows, so existing is enough there
372
- cmd_path && !File.directory?(cmd_path) && (File.executable?(cmd_path) || (self.windows? && File.exist?(cmd_path)))
383
+ if !cmd_path || File.directory?(cmd_path)
384
+ return false
385
+ end
386
+
387
+ return File.exist?(get_executable_path(cmd_path))
388
+ end
389
+
390
+ # returns the path of the executable with the correct extension on Windows
391
+ def self.get_executable_path(cmd_path)
392
+ cmd_path = localize_file_path(cmd_path)
393
+
394
+ if self.windows?
395
+ # PATHEXT contains the list of file extensions that Windows considers executable, semicolon separated.
396
+ # e.g. ".COM;.EXE;.BAT;.CMD"
397
+ exts = ENV['PATHEXT'] ? ENV['PATHEXT'].split(';') : []
398
+
399
+ # no executable files on Windows, so existing is enough there
400
+ # also check if command + ext is present
401
+ exts.each do |ext|
402
+ executable_path = "#{cmd_path}#{ext.downcase}"
403
+ return executable_path if File.exist?(executable_path)
404
+ end
405
+ end
406
+
407
+ return cmd_path
408
+ end
409
+
410
+ # returns the path with the platform-specific path separator (`/` on UNIX, `\` on Windows)
411
+ def self.localize_file_path(path)
412
+ # change `/` to `\` on Windows
413
+ return self.windows? ? path.gsub('/', '\\') : path
373
414
  end
374
415
 
375
416
  # checks if given file is a valid json file
@@ -425,20 +466,35 @@ module FastlaneCore
425
466
  UI.current.log
426
467
  end
427
468
 
428
- def self.ask_password(message: "Passphrase: ", confirm: nil)
469
+ def self.ask_password(message: "Passphrase: ", confirm: nil, confirmation_message: "Type passphrase again: ")
429
470
  raise "This code should only run in interactive mode" unless UI.interactive?
430
471
 
431
472
  loop do
432
473
  password = UI.password(message)
433
474
  if confirm
434
- password2 = UI.password("Type passphrase again: ")
475
+ password2 = UI.password(confirmation_message)
435
476
  if password == password2
436
477
  return password
437
478
  end
438
479
  else
439
480
  return password
440
481
  end
441
- UI.error("Passphrases differ. Try again")
482
+ UI.error("Your entries do not match. Please try again")
483
+ end
484
+ end
485
+
486
+ # URI.open added by `require 'open-uri'` is not available in Ruby 2.4. This helper lets you open a URI
487
+ # by choosing appropriate interface to do so depending on Ruby version. This helper is subject to be removed
488
+ # when fastlane drops Ruby 2.4 support.
489
+ def self.open_uri(*rest, &block)
490
+ require 'open-uri'
491
+
492
+ if Gem::Version.new(RUBY_VERSION) < Gem::Version.new('2.5')
493
+ dup = rest.dup
494
+ uri = dup.shift
495
+ URI.parse(uri).open(*dup, &block)
496
+ else
497
+ URI.open(*rest, &block)
442
498
  end
443
499
  end
444
500
  end
@@ -1,4 +1,5 @@
1
1
  require "digest/md5"
2
+ require 'securerandom'
2
3
 
3
4
  require_relative 'globals'
4
5
  require_relative 'ui/ui'
@@ -12,7 +13,7 @@ module FastlaneCore
12
13
  attr_accessor :package_path
13
14
 
14
15
  def generate(app_id: nil, ipa_path: nil, package_path: nil, platform: nil)
15
- self.package_path = File.join(package_path, "#{app_id}.itmsp")
16
+ self.package_path = File.join(package_path, "#{app_id}-#{SecureRandom.uuid}.itmsp")
16
17
  FileUtils.rm_rf(self.package_path) if File.directory?(self.package_path)
17
18
  FileUtils.mkdir_p(self.package_path)
18
19
 
@@ -32,7 +33,7 @@ module FastlaneCore
32
33
  File.write(File.join(self.package_path, METADATA_FILE_NAME), xml)
33
34
  UI.success("Wrote XML data to '#{self.package_path}'") if FastlaneCore::Globals.verbose?
34
35
 
35
- return package_path
36
+ return self.package_path
36
37
  end
37
38
 
38
39
  def unique_ipa_path(ipa_path)
@@ -94,6 +94,10 @@ module FastlaneCore
94
94
  return exit_status.zero?
95
95
  end
96
96
 
97
+ def displayable_errors
98
+ @errors.map { |error| "[Transporter Error Output]: #{error}" }.join("\n").gsub!(/"/, "")
99
+ end
100
+
97
101
  private
98
102
 
99
103
  def parse_line(line, hide_output)
@@ -107,7 +111,6 @@ module FastlaneCore
107
111
 
108
112
  elsif line =~ ERROR_REGEX
109
113
  @errors << $1
110
- UI.error("[Transporter Error Output]: #{$1}")
111
114
 
112
115
  # Check if it's a login error
113
116
  if $1.include?("Your Apple ID or password was entered incorrectly") ||
@@ -117,9 +120,6 @@ module FastlaneCore
117
120
  CredentialsManager::AccountManager.new(user: @user).invalid_credentials
118
121
  UI.error("Please run this tool again to apply the new password")
119
122
  end
120
- elsif $1.include?("Redundant Binary Upload. There already exists a binary upload with build")
121
- UI.error($1)
122
- UI.error("You have to change the build number of your app to upload your ipa file")
123
123
  end
124
124
 
125
125
  output_done = true
@@ -471,11 +471,13 @@ module FastlaneCore
471
471
  # Uploads the modified package back to App Store Connect
472
472
  # @param app_id [Integer] The unique App ID
473
473
  # @param dir [String] the path in which the package file is located
474
+ # @param package_path [String] the path to the package file (used instead of app_id and dir)
474
475
  # @return (Bool) True if everything worked fine
475
476
  # @raise [Deliver::TransporterTransferError] when something went wrong
476
477
  # when transferring
477
- def upload(app_id, dir)
478
- actual_dir = File.join(dir, "#{app_id}.itmsp")
478
+ def upload(app_id = nil, dir = nil, package_path: nil)
479
+ raise "app_id and dir are required or package_path is required" if (app_id.nil? || dir.nil?) && package_path.nil?
480
+ actual_dir = package_path || File.join(dir, "#{app_id}.itmsp")
479
481
 
480
482
  UI.message("Going to upload updated app to App Store Connect")
481
483
  UI.success("This might take a few minutes. Please don't interrupt the script.")
@@ -490,7 +492,7 @@ module FastlaneCore
490
492
  result = @transporter_executor.execute(command, ItunesTransporter.hide_transporter_output?)
491
493
  rescue TransporterRequiresApplicationSpecificPasswordError => ex
492
494
  handle_two_step_failure(ex)
493
- return upload(app_id, dir)
495
+ return upload(app_id, dir, package_path: package_path)
494
496
  end
495
497
 
496
498
  if result
@@ -501,7 +503,11 @@ module FastlaneCore
501
503
  handle_error(@password)
502
504
  end
503
505
 
504
- result
506
+ return result
507
+ end
508
+
509
+ def displayable_errors
510
+ @transporter_executor.displayable_errors
505
511
  end
506
512
 
507
513
  def provider_ids