fastlane 1.111.0 → 2.0.1

Sign up to get free protection for your applications and to get access to all the features.
Files changed (558) hide show
  1. checksums.yaml +4 -4
  2. data/README.md +76 -111
  3. data/bin/bin-proxy +19 -0
  4. data/cert/README.md +163 -0
  5. data/cert/lib/cert.rb +18 -0
  6. data/cert/lib/cert/commands_generator.rb +51 -0
  7. data/cert/lib/cert/options.rb +67 -0
  8. data/cert/lib/cert/runner.rb +181 -0
  9. data/credentials_manager/README.md +62 -0
  10. data/credentials_manager/lib/credentials_manager.rb +12 -0
  11. data/credentials_manager/lib/credentials_manager/account_manager.rb +104 -0
  12. data/credentials_manager/lib/credentials_manager/appfile_config.rb +186 -0
  13. data/credentials_manager/lib/credentials_manager/cli.rb +65 -0
  14. data/deliver/README.md +271 -0
  15. data/deliver/lib/assets/DeliverfileDefault +10 -0
  16. data/deliver/lib/assets/ScreenshotsHelp +7 -0
  17. data/deliver/lib/assets/summary.html.erb +210 -0
  18. data/deliver/lib/deliver.rb +31 -0
  19. data/deliver/lib/deliver/app_screenshot.rb +226 -0
  20. data/deliver/lib/deliver/commands_generator.rb +150 -0
  21. data/deliver/lib/deliver/detect_values.rb +69 -0
  22. data/deliver/lib/deliver/download_screenshots.rb +46 -0
  23. data/deliver/lib/deliver/generate_summary.rb +9 -0
  24. data/deliver/lib/deliver/html_generator.rb +58 -0
  25. data/deliver/lib/deliver/loader.rb +18 -0
  26. data/deliver/lib/deliver/options.rb +269 -0
  27. data/deliver/lib/deliver/runner.rb +99 -0
  28. data/deliver/lib/deliver/setup.rb +78 -0
  29. data/deliver/lib/deliver/submit_for_review.rb +87 -0
  30. data/deliver/lib/deliver/upload_assets.rb +22 -0
  31. data/deliver/lib/deliver/upload_metadata.rb +191 -0
  32. data/deliver/lib/deliver/upload_price_tier.rb +21 -0
  33. data/deliver/lib/deliver/upload_screenshots.rb +110 -0
  34. data/fastlane/README.md +193 -0
  35. data/{lib → fastlane/lib}/assets/Actions.md.erb +0 -0
  36. data/{lib → fastlane/lib}/assets/AppfileTemplate +0 -0
  37. data/{lib → fastlane/lib}/assets/AppfileTemplateAndroid +0 -0
  38. data/{lib → fastlane/lib}/assets/AvailablePlugins.md.erb +0 -0
  39. data/{lib → fastlane/lib}/assets/DefaultFastfileTemplate +2 -2
  40. data/{lib → fastlane/lib}/assets/FastfileTemplateAndroid +2 -2
  41. data/{lib → fastlane/lib}/assets/completions/completion.bash +0 -0
  42. data/{lib → fastlane/lib}/assets/completions/completion.sh +0 -0
  43. data/{lib → fastlane/lib}/assets/completions/completion.zsh +0 -0
  44. data/{lib → fastlane/lib}/assets/custom_action_template.rb +0 -0
  45. data/{lib → fastlane/lib}/assets/mailgun_html_template.erb +0 -0
  46. data/{lib → fastlane/lib}/assets/report_template.xml.erb +0 -0
  47. data/{lib → fastlane/lib}/assets/s3_html_template.erb +0 -0
  48. data/{lib → fastlane/lib}/assets/s3_plist_template.erb +0 -0
  49. data/{lib → fastlane/lib}/assets/s3_version_template.erb +0 -0
  50. data/{lib → fastlane/lib}/fastlane.rb +3 -3
  51. data/{lib → fastlane/lib}/fastlane/action.rb +0 -0
  52. data/{lib → fastlane/lib}/fastlane/action_collector.rb +0 -0
  53. data/{lib → fastlane/lib}/fastlane/actions/README.md +0 -0
  54. data/{lib → fastlane/lib}/fastlane/actions/actions_helper.rb +16 -0
  55. data/{lib → fastlane/lib}/fastlane/actions/adb.rb +0 -0
  56. data/{lib → fastlane/lib}/fastlane/actions/adb_devices.rb +0 -0
  57. data/{lib → fastlane/lib}/fastlane/actions/add_git_tag.rb +0 -0
  58. data/{lib → fastlane/lib}/fastlane/actions/app_store_build_number.rb +0 -0
  59. data/{lib → fastlane/lib}/fastlane/actions/appaloosa.rb +1 -0
  60. data/{lib → fastlane/lib}/fastlane/actions/appetize.rb +1 -0
  61. data/{lib → fastlane/lib}/fastlane/actions/appetize_viewing_url_generator.rb +1 -0
  62. data/{lib → fastlane/lib}/fastlane/actions/appium.rb +0 -0
  63. data/{lib → fastlane/lib}/fastlane/actions/appledoc.rb +0 -0
  64. data/{lib → fastlane/lib}/fastlane/actions/appstore.rb +0 -0
  65. data/{lib → fastlane/lib}/fastlane/actions/apteligent.rb +1 -0
  66. data/{lib → fastlane/lib}/fastlane/actions/artifactory.rb +2 -0
  67. data/{lib → fastlane/lib}/fastlane/actions/backup_file.rb +0 -0
  68. data/{lib → fastlane/lib}/fastlane/actions/backup_xcarchive.rb +0 -0
  69. data/{lib → fastlane/lib}/fastlane/actions/badge.rb +0 -0
  70. data/{lib → fastlane/lib}/fastlane/actions/build_and_upload_to_appetize.rb +1 -0
  71. data/{lib → fastlane/lib}/fastlane/actions/bundle_install.rb +0 -0
  72. data/{lib → fastlane/lib}/fastlane/actions/carthage.rb +1 -1
  73. data/{lib → fastlane/lib}/fastlane/actions/cert.rb +0 -4
  74. data/{lib → fastlane/lib}/fastlane/actions/changelog_from_git_commits.rb +0 -0
  75. data/{lib → fastlane/lib}/fastlane/actions/chatwork.rb +1 -0
  76. data/{lib → fastlane/lib}/fastlane/actions/clean_build_artifacts.rb +0 -0
  77. data/{lib → fastlane/lib}/fastlane/actions/clean_cocoapods_cache.rb +0 -0
  78. data/{lib → fastlane/lib}/fastlane/actions/clear_derived_data.rb +0 -0
  79. data/{lib → fastlane/lib}/fastlane/actions/clipboard.rb +0 -0
  80. data/{lib → fastlane/lib}/fastlane/actions/cloc.rb +0 -0
  81. data/{lib → fastlane/lib}/fastlane/actions/cocoapods.rb +0 -0
  82. data/{lib → fastlane/lib}/fastlane/actions/commit_version_bump.rb +0 -0
  83. data/{lib → fastlane/lib}/fastlane/actions/copy_artifacts.rb +0 -0
  84. data/{lib → fastlane/lib}/fastlane/actions/crashlytics.rb +2 -0
  85. data/{lib → fastlane/lib}/fastlane/actions/create_keychain.rb +1 -0
  86. data/{lib → fastlane/lib}/fastlane/actions/create_pull_request.rb +1 -0
  87. data/{lib → fastlane/lib}/fastlane/actions/danger.rb +1 -0
  88. data/{lib → fastlane/lib}/fastlane/actions/debug.rb +0 -0
  89. data/{lib → fastlane/lib}/fastlane/actions/default_platform.rb +0 -0
  90. data/{lib → fastlane/lib}/fastlane/actions/delete_keychain.rb +0 -0
  91. data/{lib → fastlane/lib}/fastlane/actions/deliver.rb +0 -4
  92. data/{lib → fastlane/lib}/fastlane/actions/deploygate.rb +34 -19
  93. data/{lib → fastlane/lib}/fastlane/actions/device_grid/README.md +0 -0
  94. data/{lib → fastlane/lib}/fastlane/actions/dotgpg_environment.rb +0 -0
  95. data/{lib → fastlane/lib}/fastlane/actions/download.rb +0 -0
  96. data/{lib → fastlane/lib}/fastlane/actions/download_dsyms.rb +0 -0
  97. data/{lib → fastlane/lib}/fastlane/actions/dsym_zip.rb +0 -0
  98. data/{lib → fastlane/lib}/fastlane/actions/ensure_git_branch.rb +0 -0
  99. data/{lib → fastlane/lib}/fastlane/actions/ensure_git_status_clean.rb +0 -0
  100. data/{lib → fastlane/lib}/fastlane/actions/ensure_no_debug_code.rb +10 -2
  101. data/{lib → fastlane/lib}/fastlane/actions/ensure_xcode_version.rb +0 -0
  102. data/{lib → fastlane/lib}/fastlane/actions/erb.rb +0 -0
  103. data/{lib → fastlane/lib}/fastlane/actions/fastlane_version.rb +0 -0
  104. data/{lib → fastlane/lib}/fastlane/actions/flock.rb +1 -0
  105. data/{lib → fastlane/lib}/fastlane/actions/frameit.rb +6 -10
  106. data/{lib → fastlane/lib}/fastlane/actions/gcovr.rb +0 -0
  107. data/{lib → fastlane/lib}/fastlane/actions/get_build_number.rb +0 -0
  108. data/{lib → fastlane/lib}/fastlane/actions/get_build_number_repository.rb +0 -0
  109. data/{lib → fastlane/lib}/fastlane/actions/get_github_release.rb +1 -0
  110. data/{lib → fastlane/lib}/fastlane/actions/get_info_plist_value.rb +0 -0
  111. data/{lib → fastlane/lib}/fastlane/actions/get_ipa_info_plist_value.rb +0 -0
  112. data/{lib → fastlane/lib}/fastlane/actions/get_version_number.rb +0 -0
  113. data/{lib → fastlane/lib}/fastlane/actions/git_add.rb +0 -0
  114. data/{lib → fastlane/lib}/fastlane/actions/git_branch.rb +0 -0
  115. data/{lib → fastlane/lib}/fastlane/actions/git_commit.rb +0 -0
  116. data/{lib → fastlane/lib}/fastlane/actions/git_pull.rb +0 -0
  117. data/{lib → fastlane/lib}/fastlane/actions/git_tag_exists.rb +0 -0
  118. data/{lib → fastlane/lib}/fastlane/actions/gradle.rb +0 -0
  119. data/fastlane/lib/fastlane/actions/gym.rb +84 -0
  120. data/{lib → fastlane/lib}/fastlane/actions/hg_add_tag.rb +0 -0
  121. data/{lib → fastlane/lib}/fastlane/actions/hg_commit_version_bump.rb +0 -0
  122. data/{lib → fastlane/lib}/fastlane/actions/hg_ensure_clean_status.rb +0 -0
  123. data/{lib → fastlane/lib}/fastlane/actions/hg_push.rb +0 -0
  124. data/{lib → fastlane/lib}/fastlane/actions/hipchat.rb +1 -0
  125. data/{lib → fastlane/lib}/fastlane/actions/hockey.rb +37 -11
  126. data/{lib → fastlane/lib}/fastlane/actions/ifttt.rb +1 -0
  127. data/{lib → fastlane/lib}/fastlane/actions/import.rb +0 -0
  128. data/{lib → fastlane/lib}/fastlane/actions/import_certificate.rb +2 -0
  129. data/{lib → fastlane/lib}/fastlane/actions/import_from_git.rb +0 -0
  130. data/{lib → fastlane/lib}/fastlane/actions/increment_build_number.rb +0 -0
  131. data/{lib → fastlane/lib}/fastlane/actions/increment_version_number.rb +0 -0
  132. data/{lib → fastlane/lib}/fastlane/actions/install_on_device.rb +0 -0
  133. data/{lib → fastlane/lib}/fastlane/actions/install_xcode_plugin.rb +0 -0
  134. data/{lib → fastlane/lib}/fastlane/actions/installr.rb +1 -0
  135. data/{lib → fastlane/lib}/fastlane/actions/ipa.rb +12 -4
  136. data/{lib → fastlane/lib}/fastlane/actions/is_ci.rb +0 -0
  137. data/{lib → fastlane/lib}/fastlane/actions/jazzy.rb +0 -0
  138. data/{lib → fastlane/lib}/fastlane/actions/jira.rb +1 -0
  139. data/{lib → fastlane/lib}/fastlane/actions/lane_context.rb +0 -0
  140. data/{lib → fastlane/lib}/fastlane/actions/last_git_commit.rb +0 -0
  141. data/{lib → fastlane/lib}/fastlane/actions/last_git_tag.rb +0 -0
  142. data/{lib → fastlane/lib}/fastlane/actions/latest_testflight_build_number.rb +0 -0
  143. data/{lib → fastlane/lib}/fastlane/actions/lcov.rb +0 -0
  144. data/{lib → fastlane/lib}/fastlane/actions/mailgun.rb +2 -0
  145. data/{lib → fastlane/lib}/fastlane/actions/make_changelog_from_jenkins.rb +0 -0
  146. data/{lib → fastlane/lib}/fastlane/actions/match.rb +3 -9
  147. data/{lib → fastlane/lib}/fastlane/actions/nexus_upload.rb +1 -0
  148. data/{lib → fastlane/lib}/fastlane/actions/notification.rb +0 -0
  149. data/{lib → fastlane/lib}/fastlane/actions/notify.rb +0 -0
  150. data/{lib → fastlane/lib}/fastlane/actions/number_of_commits.rb +0 -0
  151. data/{lib → fastlane/lib}/fastlane/actions/oclint.rb +0 -0
  152. data/{lib → fastlane/lib}/fastlane/actions/onesignal.rb +3 -0
  153. data/{lib → fastlane/lib}/fastlane/actions/opt_out_usage.rb +0 -0
  154. data/{lib → fastlane/lib}/fastlane/actions/pem.rb +9 -15
  155. data/{lib → fastlane/lib}/fastlane/actions/pilot.rb +6 -12
  156. data/{lib → fastlane/lib}/fastlane/actions/pod_lib_lint.rb +0 -0
  157. data/{lib → fastlane/lib}/fastlane/actions/pod_push.rb +0 -0
  158. data/{lib → fastlane/lib}/fastlane/actions/podio_item.rb +2 -0
  159. data/{lib → fastlane/lib}/fastlane/actions/produce.rb +7 -11
  160. data/{lib → fastlane/lib}/fastlane/actions/prompt.rb +5 -2
  161. data/{lib → fastlane/lib}/fastlane/actions/push_git_tags.rb +0 -0
  162. data/{lib → fastlane/lib}/fastlane/actions/push_to_git_remote.rb +0 -0
  163. data/{lib → fastlane/lib}/fastlane/actions/puts.rb +8 -0
  164. data/{lib → fastlane/lib}/fastlane/actions/read_podspec.rb +0 -0
  165. data/{lib → fastlane/lib}/fastlane/actions/recreate_schemes.rb +0 -0
  166. data/{lib → fastlane/lib}/fastlane/actions/register_devices.rb +0 -0
  167. data/{lib → fastlane/lib}/fastlane/actions/reset_git_repo.rb +0 -0
  168. data/fastlane/lib/fastlane/actions/reset_simulator_contents.rb +62 -0
  169. data/{lib → fastlane/lib}/fastlane/actions/resign.rb +0 -0
  170. data/{lib → fastlane/lib}/fastlane/actions/restore_file.rb +0 -0
  171. data/{lib → fastlane/lib}/fastlane/actions/rocket.rb +0 -0
  172. data/{lib → fastlane/lib}/fastlane/actions/rsync.rb +0 -0
  173. data/{lib → fastlane/lib}/fastlane/actions/s3.rb +2 -1
  174. data/{lib → fastlane/lib}/fastlane/actions/say.rb +0 -0
  175. data/{lib → fastlane/lib}/fastlane/actions/scan.rb +0 -4
  176. data/{lib → fastlane/lib}/fastlane/actions/scp.rb +1 -0
  177. data/{lib → fastlane/lib}/fastlane/actions/screengrab.rb +7 -13
  178. data/{lib → fastlane/lib}/fastlane/actions/set_build_number_repository.rb +0 -0
  179. data/{lib → fastlane/lib}/fastlane/actions/set_changelog.rb +0 -0
  180. data/{lib → fastlane/lib}/fastlane/actions/set_github_release.rb +1 -0
  181. data/{lib → fastlane/lib}/fastlane/actions/set_info_plist_value.rb +0 -0
  182. data/{lib → fastlane/lib}/fastlane/actions/set_pod_key.rb +0 -0
  183. data/{lib → fastlane/lib}/fastlane/actions/setup_jenkins.rb +0 -0
  184. data/{lib → fastlane/lib}/fastlane/actions/sigh.rb +9 -15
  185. data/{lib → fastlane/lib}/fastlane/actions/skip_docs.rb +0 -0
  186. data/{lib → fastlane/lib}/fastlane/actions/slack.rb +1 -0
  187. data/{lib → fastlane/lib}/fastlane/actions/slather.rb +0 -0
  188. data/{lib → fastlane/lib}/fastlane/actions/snapshot.rb +5 -11
  189. data/{lib → fastlane/lib}/fastlane/actions/sonar.rb +0 -0
  190. data/{lib → fastlane/lib}/fastlane/actions/splunkmint.rb +3 -0
  191. data/{lib → fastlane/lib}/fastlane/actions/ssh.rb +1 -0
  192. data/{lib → fastlane/lib}/fastlane/actions/supply.rb +9 -13
  193. data/{lib → fastlane/lib}/fastlane/actions/swiftlint.rb +0 -0
  194. data/{lib → fastlane/lib}/fastlane/actions/team_id.rb +0 -0
  195. data/{lib → fastlane/lib}/fastlane/actions/team_name.rb +0 -0
  196. data/{lib → fastlane/lib}/fastlane/actions/testfairy.rb +28 -9
  197. data/{lib → fastlane/lib}/fastlane/actions/testflight.rb +0 -0
  198. data/{lib → fastlane/lib}/fastlane/actions/tryouts.rb +1 -0
  199. data/{lib → fastlane/lib}/fastlane/actions/twitter.rb +4 -0
  200. data/{lib → fastlane/lib}/fastlane/actions/typetalk.rb +0 -0
  201. data/{lib → fastlane/lib}/fastlane/actions/unlock_keychain.rb +1 -0
  202. data/{lib → fastlane/lib}/fastlane/actions/update_app_group_identifiers.rb +0 -0
  203. data/{lib → fastlane/lib}/fastlane/actions/update_app_identifier.rb +0 -0
  204. data/{lib → fastlane/lib}/fastlane/actions/update_fastlane.rb +1 -20
  205. data/{lib → fastlane/lib}/fastlane/actions/update_icloud_container_identifiers.rb +0 -0
  206. data/{lib → fastlane/lib}/fastlane/actions/update_info_plist.rb +0 -0
  207. data/{lib → fastlane/lib}/fastlane/actions/update_project_code_signing.rb +0 -0
  208. data/{lib → fastlane/lib}/fastlane/actions/update_project_provisioning.rb +0 -0
  209. data/{lib → fastlane/lib}/fastlane/actions/update_project_team.rb +0 -0
  210. data/{lib → fastlane/lib}/fastlane/actions/update_urban_airship_configuration.rb +4 -0
  211. data/{lib → fastlane/lib}/fastlane/actions/update_url_schemes.rb +0 -0
  212. data/{lib → fastlane/lib}/fastlane/actions/upload_symbols_to_crashlytics.rb +1 -0
  213. data/{lib → fastlane/lib}/fastlane/actions/upload_symbols_to_sentry.rb +2 -0
  214. data/{lib → fastlane/lib}/fastlane/actions/verify_build.rb +0 -0
  215. data/{lib → fastlane/lib}/fastlane/actions/verify_pod_keys.rb +0 -0
  216. data/{lib → fastlane/lib}/fastlane/actions/verify_xcode.rb +0 -0
  217. data/{lib → fastlane/lib}/fastlane/actions/version_bump_podspec.rb +0 -0
  218. data/{lib → fastlane/lib}/fastlane/actions/version_get_podspec.rb +0 -0
  219. data/{lib → fastlane/lib}/fastlane/actions/xcode_install.rb +0 -0
  220. data/{lib → fastlane/lib}/fastlane/actions/xcode_select.rb +0 -0
  221. data/{lib → fastlane/lib}/fastlane/actions/xcode_server_get_assets.rb +1 -0
  222. data/{lib → fastlane/lib}/fastlane/actions/xcodebuild.rb +0 -0
  223. data/{lib → fastlane/lib}/fastlane/actions/xcov.rb +0 -0
  224. data/{lib → fastlane/lib}/fastlane/actions/xctool.rb +1 -1
  225. data/{lib → fastlane/lib}/fastlane/actions/xcversion.rb +0 -0
  226. data/{lib → fastlane/lib}/fastlane/actions/zip.rb +0 -0
  227. data/{lib → fastlane/lib}/fastlane/auto_complete.rb +0 -0
  228. data/fastlane/lib/fastlane/cli_tools_distributor.rb +125 -0
  229. data/{lib → fastlane/lib}/fastlane/command_line_handler.rb +0 -0
  230. data/{lib → fastlane/lib}/fastlane/commands_generator.rb +5 -4
  231. data/{lib → fastlane/lib}/fastlane/configuration_helper.rb +0 -1
  232. data/{lib → fastlane/lib}/fastlane/core_ext/bundler_monkey_patch.rb +0 -0
  233. data/{lib → fastlane/lib}/fastlane/documentation/actions_list.rb +1 -1
  234. data/{lib → fastlane/lib}/fastlane/documentation/docs_generator.rb +1 -1
  235. data/{lib → fastlane/lib}/fastlane/documentation/markdown_docs_generator.rb +0 -0
  236. data/{lib → fastlane/lib}/fastlane/environment_printer.rb +1 -1
  237. data/{lib → fastlane/lib}/fastlane/erb_template_helper.rb +0 -0
  238. data/{lib → fastlane/lib}/fastlane/fast_file.rb +1 -1
  239. data/{lib → fastlane/lib}/fastlane/fastlane_require.rb +27 -3
  240. data/{lib → fastlane/lib}/fastlane/features.rb +0 -0
  241. data/{lib → fastlane/lib}/fastlane/helper/README.md +0 -0
  242. data/{lib → fastlane/lib}/fastlane/helper/adb_helper.rb +0 -0
  243. data/{lib → fastlane/lib}/fastlane/helper/cocoapod_helper.rb +0 -0
  244. data/{lib → fastlane/lib}/fastlane/helper/crashlytics_helper.rb +0 -0
  245. data/{lib → fastlane/lib}/fastlane/helper/gem_helper.rb +0 -0
  246. data/{lib → fastlane/lib}/fastlane/helper/git_helper.rb +0 -0
  247. data/{lib → fastlane/lib}/fastlane/helper/gradle_helper.rb +0 -0
  248. data/{lib → fastlane/lib}/fastlane/helper/podspec_helper.rb +0 -0
  249. data/{lib → fastlane/lib}/fastlane/helper/sh_helper.rb +0 -0
  250. data/{lib → fastlane/lib}/fastlane/helper/xcversion_helper.rb +0 -0
  251. data/{lib → fastlane/lib}/fastlane/junit_generator.rb +1 -1
  252. data/{lib → fastlane/lib}/fastlane/lane.rb +0 -0
  253. data/{lib → fastlane/lib}/fastlane/lane_list.rb +0 -0
  254. data/{lib → fastlane/lib}/fastlane/lane_manager.rb +25 -6
  255. data/{lib → fastlane/lib}/fastlane/markdown_table_formatter.rb +0 -0
  256. data/{lib → fastlane/lib}/fastlane/new_action.rb +1 -1
  257. data/{lib → fastlane/lib}/fastlane/one_off.rb +0 -0
  258. data/{lib → fastlane/lib}/fastlane/other_action.rb +0 -0
  259. data/{lib → fastlane/lib}/fastlane/plugins/plugin_fetcher.rb +0 -0
  260. data/{lib → fastlane/lib}/fastlane/plugins/plugin_generator.rb +0 -0
  261. data/{lib → fastlane/lib}/fastlane/plugins/plugin_generator_ui.rb +0 -0
  262. data/{lib → fastlane/lib}/fastlane/plugins/plugin_info.rb +0 -0
  263. data/{lib → fastlane/lib}/fastlane/plugins/plugin_info_collector.rb +0 -0
  264. data/{lib → fastlane/lib}/fastlane/plugins/plugin_manager.rb +4 -4
  265. data/{lib → fastlane/lib}/fastlane/plugins/plugin_search.rb +0 -0
  266. data/{lib → fastlane/lib}/fastlane/plugins/plugin_update_manager.rb +0 -0
  267. data/{lib → fastlane/lib}/fastlane/plugins/plugins.rb +0 -0
  268. data/{lib → fastlane/lib}/fastlane/plugins/template/%gem_name%.gemspec.erb +3 -0
  269. data/{lib → fastlane/lib}/fastlane/plugins/template/.gitignore +0 -0
  270. data/{lib → fastlane/lib}/fastlane/plugins/template/.rspec +0 -0
  271. data/{lib → fastlane/lib}/fastlane/plugins/template/.rubocop.yml +0 -0
  272. data/{lib → fastlane/lib}/fastlane/plugins/template/.travis.yml +0 -0
  273. data/{lib → fastlane/lib}/fastlane/plugins/template/Gemfile +0 -0
  274. data/{lib → fastlane/lib}/fastlane/plugins/template/LICENSE.erb +0 -0
  275. data/{lib → fastlane/lib}/fastlane/plugins/template/README.md.erb +2 -2
  276. data/{lib → fastlane/lib}/fastlane/plugins/template/Rakefile +0 -0
  277. data/{lib → fastlane/lib}/fastlane/plugins/template/circle.yml +0 -0
  278. data/{lib → fastlane/lib}/fastlane/plugins/template/fastlane/Fastfile.erb +0 -0
  279. data/{lib → fastlane/lib}/fastlane/plugins/template/fastlane/Pluginfile.erb +0 -0
  280. data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%.rb.erb +0 -0
  281. data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/actions/%plugin_name%_action.rb.erb +0 -0
  282. data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/helper/%plugin_name%_helper.rb.erb +0 -0
  283. data/{lib → fastlane/lib}/fastlane/plugins/template/lib/fastlane/plugin/%plugin_name%/version.rb.erb +0 -0
  284. data/{lib → fastlane/lib}/fastlane/plugins/template/spec/%plugin_name%_action_spec.rb.erb +0 -0
  285. data/{lib → fastlane/lib}/fastlane/plugins/template/spec/spec_helper.rb.erb +0 -0
  286. data/{lib → fastlane/lib}/fastlane/runner.rb +25 -2
  287. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta.rb +1 -1
  288. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_command_line_handler.rb +0 -0
  289. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_info.rb +0 -0
  290. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_info_collector.rb +0 -0
  291. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_ui.rb +0 -0
  292. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_beta_user_email_fetcher.rb +0 -0
  293. data/{lib → fastlane/lib}/fastlane/setup/crashlytics_project_parser.rb +0 -0
  294. data/{lib → fastlane/lib}/fastlane/setup/setup.rb +2 -2
  295. data/{lib → fastlane/lib}/fastlane/setup/setup_android.rb +2 -2
  296. data/{lib → fastlane/lib}/fastlane/setup/setup_ios.rb +3 -3
  297. data/{lib → fastlane/lib}/fastlane/supported_platforms.rb +0 -0
  298. data/{lib → fastlane/lib}/fastlane/tools.rb +0 -0
  299. data/{lib → fastlane/lib}/fastlane/version.rb +2 -2
  300. data/fastlane_core/README.md +54 -0
  301. data/fastlane_core/lib/assets/XMLTemplate.xml.erb +12 -0
  302. data/fastlane_core/lib/fastlane_core.rb +48 -0
  303. data/fastlane_core/lib/fastlane_core/cert_checker.rb +94 -0
  304. data/fastlane_core/lib/fastlane_core/command_executor.rb +98 -0
  305. data/fastlane_core/lib/fastlane_core/configuration/commander_generator.rb +82 -0
  306. data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +133 -0
  307. data/fastlane_core/lib/fastlane_core/configuration/configuration.rb +266 -0
  308. data/fastlane_core/lib/fastlane_core/configuration/configuration_file.rb +82 -0
  309. data/fastlane_core/lib/fastlane_core/core_ext/string.rb +17 -0
  310. data/fastlane_core/lib/fastlane_core/device_manager.rb +231 -0
  311. data/fastlane_core/lib/fastlane_core/env.rb +9 -0
  312. data/{lib/fastlane → fastlane_core/lib/fastlane_core}/fastlane_folder.rb +1 -11
  313. data/fastlane_core/lib/fastlane_core/feature/feature.rb +49 -0
  314. data/fastlane_core/lib/fastlane_core/features.rb +2 -0
  315. data/fastlane_core/lib/fastlane_core/helper.rb +240 -0
  316. data/fastlane_core/lib/fastlane_core/ipa_file_analyser.rb +55 -0
  317. data/fastlane_core/lib/fastlane_core/ipa_upload_package_builder.rb +44 -0
  318. data/fastlane_core/lib/fastlane_core/itunes_search_api.rb +48 -0
  319. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +409 -0
  320. data/fastlane_core/lib/fastlane_core/keychain_importer.rb +27 -0
  321. data/fastlane_core/lib/fastlane_core/languages.rb +11 -0
  322. data/fastlane_core/lib/fastlane_core/pkg_file_analyser.rb +42 -0
  323. data/fastlane_core/lib/fastlane_core/pkg_upload_package_builder.rb +44 -0
  324. data/fastlane_core/lib/fastlane_core/print_table.rb +63 -0
  325. data/fastlane_core/lib/fastlane_core/project.rb +450 -0
  326. data/fastlane_core/lib/fastlane_core/provisioning_profile.rb +69 -0
  327. data/fastlane_core/lib/fastlane_core/string_filters.rb +34 -0
  328. data/fastlane_core/lib/fastlane_core/tool_collector.rb +179 -0
  329. data/fastlane_core/lib/fastlane_core/ui/disable_colors.rb +17 -0
  330. data/fastlane_core/lib/fastlane_core/ui/fastlane_runner.rb +190 -0
  331. data/fastlane_core/lib/fastlane_core/ui/github_issue_inspector_reporter.rb +50 -0
  332. data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +122 -0
  333. data/fastlane_core/lib/fastlane_core/ui/interface.rb +159 -0
  334. data/fastlane_core/lib/fastlane_core/ui/ui.rb +26 -0
  335. data/fastlane_core/lib/fastlane_core/update_checker/changelog.rb +37 -0
  336. data/fastlane_core/lib/fastlane_core/update_checker/update_checker.rb +198 -0
  337. data/fastlane_core/lib/fastlane_core/xcodebuild_list_output_parser.rb +28 -0
  338. data/frameit/README.md +284 -0
  339. data/frameit/lib/assets/empty.png +0 -0
  340. data/frameit/lib/frameit.rb +52 -0
  341. data/frameit/lib/frameit/commands_generator.rb +99 -0
  342. data/frameit/lib/frameit/config_parser.rb +98 -0
  343. data/frameit/lib/frameit/dependency_checker.rb +20 -0
  344. data/frameit/lib/frameit/device_types.rb +13 -0
  345. data/frameit/lib/frameit/editor.rb +351 -0
  346. data/frameit/lib/frameit/frame_downloader.rb +71 -0
  347. data/frameit/lib/frameit/mac_editor.rb +32 -0
  348. data/frameit/lib/frameit/offsets.rb +19 -0
  349. data/frameit/lib/frameit/options.rb +46 -0
  350. data/frameit/lib/frameit/runner.rb +45 -0
  351. data/frameit/lib/frameit/screenshot.rb +89 -0
  352. data/frameit/lib/frameit/strings_parser.rb +35 -0
  353. data/frameit/lib/frameit/template_finder.rb +36 -0
  354. data/gym/README.md +288 -0
  355. data/gym/lib/assets/GymfileTemplate +13 -0
  356. data/gym/lib/assets/package_application_patches/0001_codesign_args_patch.diff +38 -0
  357. data/gym/lib/assets/package_application_patches/0002_no_strict_parameter_patch.diff +42 -0
  358. data/gym/lib/assets/package_application_patches/PackageApplication_MD5 +2 -0
  359. data/gym/lib/assets/wrap_xcodebuild/xcbuild-safe.sh +58 -0
  360. data/gym/lib/gym.rb +49 -0
  361. data/gym/lib/gym/commands_generator.rb +62 -0
  362. data/gym/lib/gym/detect_values.rb +105 -0
  363. data/gym/lib/gym/error_handler.rb +186 -0
  364. data/gym/lib/gym/generators/README.md +1 -0
  365. data/gym/lib/gym/generators/build_command_generator.rb +136 -0
  366. data/gym/lib/gym/generators/package_command_generator.rb +58 -0
  367. data/gym/lib/gym/generators/package_command_generator_legacy.rb +102 -0
  368. data/gym/lib/gym/generators/package_command_generator_xcode7.rb +191 -0
  369. data/gym/lib/gym/manager.rb +17 -0
  370. data/gym/lib/gym/options.rb +254 -0
  371. data/gym/lib/gym/runner.rb +256 -0
  372. data/gym/lib/gym/xcode.rb +21 -0
  373. data/gym/lib/gym/xcodebuild_fixes/README.md +9 -0
  374. data/gym/lib/gym/xcodebuild_fixes/generic_archive_fix.rb +32 -0
  375. data/gym/lib/gym/xcodebuild_fixes/package_application_fix.rb +53 -0
  376. data/gym/lib/gym/xcodebuild_fixes/swift_fix.rb +99 -0
  377. data/gym/lib/gym/xcodebuild_fixes/watchkit2_fix.rb +35 -0
  378. data/gym/lib/gym/xcodebuild_fixes/watchkit_fix.rb +40 -0
  379. data/match/README.md +414 -0
  380. data/match/lib/assets/MatchfileTemplate +9 -0
  381. data/match/lib/assets/READMETemplate.md +49 -0
  382. data/match/lib/match.rb +57 -0
  383. data/match/lib/match/change_password.rb +30 -0
  384. data/match/lib/match/commands_generator.rb +120 -0
  385. data/match/lib/match/encrypt.rb +93 -0
  386. data/match/lib/match/generator.rb +74 -0
  387. data/match/lib/match/git_helper.rb +139 -0
  388. data/match/lib/match/nuke.rb +190 -0
  389. data/match/lib/match/options.rb +124 -0
  390. data/match/lib/match/runner.rb +172 -0
  391. data/match/lib/match/setup.rb +20 -0
  392. data/match/lib/match/spaceship_ensure.rb +78 -0
  393. data/match/lib/match/table_printer.rb +43 -0
  394. data/match/lib/match/utils.rb +59 -0
  395. data/pem/README.md +175 -0
  396. data/pem/lib/pem.rb +21 -0
  397. data/pem/lib/pem/commands_generator.rb +41 -0
  398. data/pem/lib/pem/manager.rb +93 -0
  399. data/pem/lib/pem/options.rb +79 -0
  400. data/pilot/README.md +285 -0
  401. data/pilot/lib/pilot.rb +22 -0
  402. data/pilot/lib/pilot/build_manager.rb +209 -0
  403. data/pilot/lib/pilot/commands_generator.rb +136 -0
  404. data/pilot/lib/pilot/features.rb +0 -0
  405. data/pilot/lib/pilot/manager.rb +71 -0
  406. data/pilot/lib/pilot/options.rb +161 -0
  407. data/pilot/lib/pilot/tester_exporter.rb +37 -0
  408. data/pilot/lib/pilot/tester_importer.rb +51 -0
  409. data/pilot/lib/pilot/tester_manager.rb +212 -0
  410. data/pilot/lib/pilot/tester_util.rb +23 -0
  411. data/produce/README.md +232 -0
  412. data/produce/lib/produce.rb +21 -0
  413. data/produce/lib/produce/available_default_languages.rb +36 -0
  414. data/produce/lib/produce/commands_generator.rb +134 -0
  415. data/produce/lib/produce/developer_center.rb +58 -0
  416. data/produce/lib/produce/group.rb +89 -0
  417. data/produce/lib/produce/itunes_connect.rb +87 -0
  418. data/produce/lib/produce/manager.rb +11 -0
  419. data/produce/lib/produce/options.rb +114 -0
  420. data/produce/lib/produce/service.rb +227 -0
  421. data/scan/README.md +219 -0
  422. data/scan/lib/assets/ScanfileTemplate +13 -0
  423. data/scan/lib/scan.rb +40 -0
  424. data/scan/lib/scan/commands_generator.rb +61 -0
  425. data/scan/lib/scan/detect_values.rb +184 -0
  426. data/scan/lib/scan/error_handler.rb +43 -0
  427. data/scan/lib/scan/manager.rb +17 -0
  428. data/scan/lib/scan/options.rb +189 -0
  429. data/scan/lib/scan/report_collector.rb +70 -0
  430. data/scan/lib/scan/runner.rb +103 -0
  431. data/scan/lib/scan/slack_poster.rb +59 -0
  432. data/scan/lib/scan/test_command_generator.rb +130 -0
  433. data/scan/lib/scan/test_result_parser.rb +21 -0
  434. data/screengrab/README.md +190 -0
  435. data/screengrab/lib/assets/ScreengrabfileTemplate +15 -0
  436. data/screengrab/lib/screengrab.rb +32 -0
  437. data/screengrab/lib/screengrab/android_environment.rb +88 -0
  438. data/screengrab/lib/screengrab/commands_generator.rb +60 -0
  439. data/screengrab/lib/screengrab/dependency_checker.rb +56 -0
  440. data/screengrab/lib/screengrab/detect_values.rb +16 -0
  441. data/screengrab/lib/screengrab/options.rb +109 -0
  442. data/screengrab/lib/screengrab/page.html.erb +206 -0
  443. data/screengrab/lib/screengrab/runner.rb +336 -0
  444. data/screengrab/lib/screengrab/setup.rb +16 -0
  445. data/sigh/README.md +256 -0
  446. data/sigh/lib/assets/resign.sh +774 -0
  447. data/sigh/lib/sigh.rb +19 -0
  448. data/sigh/lib/sigh/commands_generator.rb +133 -0
  449. data/sigh/lib/sigh/download_all.rb +36 -0
  450. data/sigh/lib/sigh/local_manage.rb +140 -0
  451. data/sigh/lib/sigh/manager.rb +44 -0
  452. data/sigh/lib/sigh/options.rb +117 -0
  453. data/sigh/lib/sigh/repair.rb +30 -0
  454. data/sigh/lib/sigh/resign.rb +201 -0
  455. data/sigh/lib/sigh/runner.rb +235 -0
  456. data/snapshot/README.md +400 -0
  457. data/snapshot/lib/assets/SnapfileTemplate +36 -0
  458. data/snapshot/lib/assets/SnapshotHelper.swift +138 -0
  459. data/snapshot/lib/assets/SnapshotHelper2-3.swift +140 -0
  460. data/snapshot/lib/snapshot.rb +59 -0
  461. data/snapshot/lib/snapshot/collector.rb +92 -0
  462. data/snapshot/lib/snapshot/commands_generator.rb +108 -0
  463. data/snapshot/lib/snapshot/dependency_checker.rb +50 -0
  464. data/snapshot/lib/snapshot/detect_values.rb +53 -0
  465. data/snapshot/lib/snapshot/error_handler.rb +22 -0
  466. data/snapshot/lib/snapshot/fixes/README.md +5 -0
  467. data/snapshot/lib/snapshot/fixes/hardware_keyboard_fix.rb +14 -0
  468. data/snapshot/lib/snapshot/fixes/simulator_zoom_fix.rb +25 -0
  469. data/snapshot/lib/snapshot/latest_os_version.rb +31 -0
  470. data/snapshot/lib/snapshot/options.rb +161 -0
  471. data/snapshot/lib/snapshot/page.html.erb +206 -0
  472. data/snapshot/lib/snapshot/reports_generator.rb +64 -0
  473. data/snapshot/lib/snapshot/reset_simulators.rb +88 -0
  474. data/snapshot/lib/snapshot/runner.rb +294 -0
  475. data/snapshot/lib/snapshot/screenshot_flatten.rb +18 -0
  476. data/snapshot/lib/snapshot/screenshot_rotate.rb +38 -0
  477. data/snapshot/lib/snapshot/setup.rb +35 -0
  478. data/snapshot/lib/snapshot/test_command_generator.rb +118 -0
  479. data/snapshot/lib/snapshot/update.rb +29 -0
  480. data/spaceship/README.md +191 -0
  481. data/spaceship/lib/assets/languageMapping.json +240 -0
  482. data/spaceship/lib/assets/languageMappingReadable.json +30 -0
  483. data/spaceship/lib/spaceship.rb +31 -0
  484. data/spaceship/lib/spaceship/babosa_fix.rb +30 -0
  485. data/spaceship/lib/spaceship/base.rb +236 -0
  486. data/spaceship/lib/spaceship/client.rb +487 -0
  487. data/spaceship/lib/spaceship/commands_generator.rb +48 -0
  488. data/spaceship/lib/spaceship/du/du_client.rb +122 -0
  489. data/spaceship/lib/spaceship/du/upload_file.rb +56 -0
  490. data/spaceship/lib/spaceship/du/utilities.rb +81 -0
  491. data/spaceship/lib/spaceship/helper/net_http_generic_request.rb +14 -0
  492. data/spaceship/lib/spaceship/helper/plist_middleware.rb +15 -0
  493. data/spaceship/lib/spaceship/launcher.rb +94 -0
  494. data/spaceship/lib/spaceship/playground.rb +72 -0
  495. data/spaceship/lib/spaceship/portal/app.rb +148 -0
  496. data/spaceship/lib/spaceship/portal/app_group.rb +77 -0
  497. data/spaceship/lib/spaceship/portal/app_service.rb +278 -0
  498. data/spaceship/lib/spaceship/portal/certificate.rb +333 -0
  499. data/spaceship/lib/spaceship/portal/device.rb +192 -0
  500. data/spaceship/lib/spaceship/portal/portal.rb +8 -0
  501. data/spaceship/lib/spaceship/portal/portal_base.rb +13 -0
  502. data/spaceship/lib/spaceship/portal/portal_client.rb +491 -0
  503. data/spaceship/lib/spaceship/portal/provisioning_profile.rb +467 -0
  504. data/spaceship/lib/spaceship/portal/spaceship.rb +112 -0
  505. data/spaceship/lib/spaceship/portal/ui/select_team.rb +83 -0
  506. data/spaceship/lib/spaceship/spaceauth_runner.rb +50 -0
  507. data/spaceship/lib/spaceship/tunes/app_details.rb +139 -0
  508. data/spaceship/lib/spaceship/tunes/app_image.rb +55 -0
  509. data/spaceship/lib/spaceship/tunes/app_ratings.rb +107 -0
  510. data/spaceship/lib/spaceship/tunes/app_screenshot.rb +17 -0
  511. data/spaceship/lib/spaceship/tunes/app_status.rb +60 -0
  512. data/spaceship/lib/spaceship/tunes/app_submission.rb +136 -0
  513. data/spaceship/lib/spaceship/tunes/app_trailer.rb +68 -0
  514. data/spaceship/lib/spaceship/tunes/app_version.rb +766 -0
  515. data/spaceship/lib/spaceship/tunes/app_version_common.rb +33 -0
  516. data/spaceship/lib/spaceship/tunes/app_version_generated_promocodes.rb +35 -0
  517. data/spaceship/lib/spaceship/tunes/app_version_history.rb +59 -0
  518. data/spaceship/lib/spaceship/tunes/app_version_promocodes.rb +34 -0
  519. data/spaceship/lib/spaceship/tunes/app_version_ref.rb +19 -0
  520. data/spaceship/lib/spaceship/tunes/app_version_states_history.rb +34 -0
  521. data/spaceship/lib/spaceship/tunes/application.rb +437 -0
  522. data/spaceship/lib/spaceship/tunes/build.rb +269 -0
  523. data/spaceship/lib/spaceship/tunes/build_details.rb +48 -0
  524. data/spaceship/lib/spaceship/tunes/build_train.rb +182 -0
  525. data/spaceship/lib/spaceship/tunes/device_type.rb +14 -0
  526. data/spaceship/lib/spaceship/tunes/language_converter.rb +63 -0
  527. data/spaceship/lib/spaceship/tunes/language_item.rb +56 -0
  528. data/spaceship/lib/spaceship/tunes/pricing_tier.rb +81 -0
  529. data/spaceship/lib/spaceship/tunes/recovery_device.rb +69 -0
  530. data/spaceship/lib/spaceship/tunes/spaceship.rb +34 -0
  531. data/spaceship/lib/spaceship/tunes/tester.rb +283 -0
  532. data/spaceship/lib/spaceship/tunes/transit_app_file.rb +27 -0
  533. data/spaceship/lib/spaceship/tunes/tunes.rb +35 -0
  534. data/spaceship/lib/spaceship/tunes/tunes_base.rb +15 -0
  535. data/spaceship/lib/spaceship/tunes/tunes_client.rb +1068 -0
  536. data/spaceship/lib/spaceship/tunes/user_detail.rb +19 -0
  537. data/spaceship/lib/spaceship/tunes/version_set.rb +35 -0
  538. data/spaceship/lib/spaceship/two_step_client.rb +195 -0
  539. data/spaceship/lib/spaceship/ui.rb +27 -0
  540. data/supply/README.md +214 -0
  541. data/supply/lib/supply.rb +29 -0
  542. data/supply/lib/supply/apk_listing.rb +14 -0
  543. data/supply/lib/supply/client.rb +345 -0
  544. data/supply/lib/supply/commands_generator.rb +62 -0
  545. data/supply/lib/supply/listing.rb +32 -0
  546. data/supply/lib/supply/options.rb +135 -0
  547. data/supply/lib/supply/setup.rb +102 -0
  548. data/supply/lib/supply/uploader.rb +221 -0
  549. metadata +699 -428
  550. data/bin//360/237/232/200 +0 -5
  551. data/lib/.DS_Store +0 -0
  552. data/lib/assets/.DS_Store +0 -0
  553. data/lib/assets/completions/.DS_Store +0 -0
  554. data/lib/fastlane/.DS_Store +0 -0
  555. data/lib/fastlane/actions/gym.rb +0 -90
  556. data/lib/fastlane/actions/reset_simulators.rb +0 -44
  557. data/lib/fastlane/cli_tools_distributor.rb +0 -100
  558. data/lib/fastlane/setup/.DS_Store +0 -0
@@ -0,0 +1,27 @@
1
+ module Spaceship
2
+ module Tunes
3
+ # Represents a geo json
4
+ class TransitAppFile < TunesBase
5
+ attr_accessor :asset_token
6
+
7
+ attr_accessor :name
8
+
9
+ attr_accessor :time_stamp
10
+
11
+ attr_accessor :url
12
+
13
+ attr_mapping(
14
+ 'assetToken' => :asset_token,
15
+ 'timeStemp' => :time_stamp,
16
+ 'url' => :url,
17
+ 'name' => :name
18
+ )
19
+
20
+ class << self
21
+ def factory(attrs)
22
+ self.new(attrs)
23
+ end
24
+ end
25
+ end
26
+ end
27
+ end
@@ -0,0 +1,35 @@
1
+ require 'spaceship/tunes/tunes_base'
2
+ require 'spaceship/tunes/application'
3
+ require 'spaceship/tunes/version_set'
4
+ require 'spaceship/tunes/app_version'
5
+ require 'spaceship/tunes/app_version_common'
6
+ require 'spaceship/tunes/app_submission'
7
+ require 'spaceship/tunes/tunes_client'
8
+ require 'spaceship/tunes/language_item'
9
+ require 'spaceship/tunes/app_status'
10
+ require 'spaceship/tunes/app_image'
11
+ require 'spaceship/tunes/app_ratings'
12
+ require 'spaceship/tunes/app_version_ref'
13
+ require 'spaceship/tunes/app_version_history'
14
+ require 'spaceship/tunes/app_version_states_history'
15
+ require 'spaceship/tunes/transit_app_file'
16
+ require 'spaceship/tunes/user_detail'
17
+ require 'spaceship/tunes/app_screenshot'
18
+ require 'spaceship/tunes/language_converter'
19
+ require 'spaceship/tunes/build'
20
+ require 'spaceship/tunes/build_details'
21
+ require 'spaceship/tunes/build_train'
22
+ require 'spaceship/tunes/device_type'
23
+ require 'spaceship/tunes/app_trailer'
24
+ require 'spaceship/tunes/tester'
25
+ require 'spaceship/tunes/app_details'
26
+ require 'spaceship/tunes/pricing_tier'
27
+ require 'spaceship/tunes/recovery_device'
28
+
29
+ require 'spaceship/tunes/app_version_promocodes'
30
+ require 'spaceship/tunes/app_version_generated_promocodes'
31
+
32
+ # File Uploads
33
+ require 'spaceship/du/utilities'
34
+ require 'spaceship/du/upload_file'
35
+ require 'spaceship/du/du_client'
@@ -0,0 +1,15 @@
1
+ module Spaceship
2
+ module Tunes
3
+ class TunesBase < Spaceship::Base
4
+ class << self
5
+ def client
6
+ (
7
+ @client or
8
+ Spaceship::Tunes.client or
9
+ raise "Please login using `Spaceship::Tunes.login('user', 'password')`"
10
+ )
11
+ end
12
+ end
13
+ end
14
+ end
15
+ end
@@ -0,0 +1,1068 @@
1
+ require "securerandom"
2
+
3
+ module Spaceship
4
+ # rubocop:disable Metrics/ClassLength
5
+ class TunesClient < Spaceship::Client
6
+ # ITunesConnectError is only thrown when iTunes Connect raises an exception
7
+ class ITunesConnectError < BasicPreferredInfoError
8
+ end
9
+
10
+ # raised if the server failed to save temporarily
11
+ class ITunesConnectTemporaryError < ITunesConnectError
12
+ end
13
+
14
+ attr_reader :du_client
15
+
16
+ def initialize
17
+ super
18
+
19
+ @du_client = DUClient.new
20
+ end
21
+
22
+ class << self
23
+ # trailer preview screenshots are required to have a specific size
24
+ def video_preview_resolution_for(device, is_portrait)
25
+ resolutions = {
26
+ 'iphone4' => [1136, 640],
27
+ 'iphone6' => [1334, 750],
28
+ 'iphone6Plus' => [2208, 1242],
29
+ 'ipad' => [1024, 768],
30
+ 'ipadPro' => [2732, 2048]
31
+ }
32
+
33
+ r = resolutions[device]
34
+ r = [r[1], r[0]] if is_portrait
35
+ r
36
+ end
37
+ end
38
+
39
+ #####################################################
40
+ # @!group Init and Login
41
+ #####################################################
42
+
43
+ def self.hostname
44
+ "https://itunesconnect.apple.com/WebObjects/iTunesConnect.woa/"
45
+ end
46
+
47
+ # @return (Array) A list of all available teams
48
+ def teams
49
+ return @teams if @teams
50
+ r = request(:get, "ra/user/detail")
51
+ @teams = parse_response(r, 'data')['associatedAccounts'].sort_by do |team|
52
+ [
53
+ team['contentProvider']['name'],
54
+ team['contentProvider']['contentProviderId']
55
+ ]
56
+ end
57
+ end
58
+
59
+ # @return (String) The currently selected Team ID
60
+ def team_id
61
+ return @current_team_id if @current_team_id
62
+
63
+ if teams.count > 1
64
+ puts "The current user is in #{teams.count} teams. Pass a team ID or call `select_team` to choose a team. Using the first one for now."
65
+ end
66
+ @current_team_id ||= teams[0]['contentProvider']['contentProviderId']
67
+ end
68
+
69
+ # Set a new team ID which will be used from now on
70
+ def team_id=(team_id)
71
+ # First, we verify the team actually exists, because otherwise iTC would return the
72
+ # following confusing error message
73
+ #
74
+ # invalid content provider id
75
+ #
76
+ available_teams = teams.collect do |team|
77
+ (team["contentProvider"] || {})["contentProviderId"]
78
+ end
79
+
80
+ result = available_teams.find do |available_team_id|
81
+ team_id.to_s == available_team_id.to_s
82
+ end
83
+
84
+ unless result
85
+ raise ITunesConnectError.new, "Could not set team ID to '#{team_id}', only found the following available teams: #{available_teams.join(', ')}"
86
+ end
87
+
88
+ response = request(:post) do |req|
89
+ req.url "ra/v1/session/webSession"
90
+ req.body = {
91
+ contentProviderId: team_id,
92
+ dsId: user_detail_data.ds_id # https://github.com/fastlane/fastlane/issues/6711
93
+ }.to_json
94
+ req.headers['Content-Type'] = 'application/json'
95
+ end
96
+
97
+ handle_itc_response(response.body)
98
+
99
+ @current_team_id = team_id
100
+ end
101
+
102
+ # Shows a team selection for the user in the terminal. This should not be
103
+ # called on CI systems
104
+ def select_team
105
+ t_id = (ENV['FASTLANE_ITC_TEAM_ID'] || '').strip
106
+ t_name = (ENV['FASTLANE_ITC_TEAM_NAME'] || '').strip
107
+
108
+ if t_name.length > 0 && t_id.length.zero? # we prefer IDs over names, they are unique
109
+ puts "Looking for iTunes Connect Team with name #{t_name}" if $verbose
110
+
111
+ teams.each do |t|
112
+ t_id = t['contentProvider']['contentProviderId'].to_s if t['contentProvider']['name'].casecmp(t_name.downcase).zero?
113
+ end
114
+
115
+ puts "Could not find team with name '#{t_name}', trying to fallback to default team" if t_id.length.zero?
116
+ end
117
+
118
+ t_id = teams.first['contentProvider']['contentProviderId'].to_s if teams.count == 1
119
+
120
+ if t_id.length > 0
121
+ puts "Looking for iTunes Connect Team with ID #{t_id}" if $verbose
122
+
123
+ # actually set the team id here
124
+ self.team_id = t_id
125
+ return
126
+ end
127
+
128
+ # user didn't specify a team... #thisiswhywecanthavenicethings
129
+ loop do
130
+ puts "Multiple iTunes Connect teams found, please enter the number of the team you want to use: "
131
+ puts "Note: to automatically choose the team, provide either the iTunes Connect Team ID, or the Team Name in your fastlane/Appfile:"
132
+ puts "Alternatively you can pass the team name or team ID using the `FASTLANE_ITC_TEAM_ID` or `FASTLANE_ITC_TEAM_NAME` environment variable"
133
+ first_team = teams.first["contentProvider"]
134
+ puts ""
135
+ puts " itc_team_id \"#{first_team['contentProviderId']}\""
136
+ puts ""
137
+ puts "or"
138
+ puts ""
139
+ puts " itc_team_name \"#{first_team['name']}\""
140
+ puts ""
141
+ teams.each_with_index do |team, i|
142
+ puts "#{i + 1}) \"#{team['contentProvider']['name']}\" (#{team['contentProvider']['contentProviderId']})"
143
+ end
144
+
145
+ selected = ($stdin.gets || '').strip.to_i - 1
146
+ team_to_use = teams[selected] if selected >= 0
147
+
148
+ if team_to_use
149
+ self.team_id = team_to_use['contentProvider']['contentProviderId'].to_s # actually set the team id here
150
+ break
151
+ end
152
+ end
153
+ end
154
+
155
+ # @return (Hash) Fetches all information of the currently used team
156
+ def team_information
157
+ teams.find do |t|
158
+ t['teamId'] == team_id
159
+ end
160
+ end
161
+
162
+ def send_login_request(user, password)
163
+ clear_user_cached_data
164
+ send_shared_login_request(user, password)
165
+ end
166
+
167
+ # rubocop:disable Metrics/PerceivedComplexity
168
+ def handle_itc_response(raw)
169
+ return unless raw
170
+ return unless raw.kind_of? Hash
171
+
172
+ data = raw['data'] || raw # sometimes it's with data, sometimes it isn't
173
+
174
+ if data.fetch('sectionErrorKeys', []).count == 0 and
175
+ data.fetch('sectionInfoKeys', []).count == 0 and
176
+ data.fetch('sectionWarningKeys', []).count == 0 and
177
+ data.fetch('validationErrors', []).count == 0
178
+
179
+ logger.debug("Request was successful")
180
+ end
181
+
182
+ # We pass on the `current_language` so that the error message tells the user
183
+ # what language the error was caused in
184
+ handle_response_hash = lambda do |hash, current_language = nil|
185
+ errors = []
186
+ if hash.kind_of?(Hash)
187
+ current_language ||= hash["language"]
188
+
189
+ hash.each do |key, value|
190
+ errors += handle_response_hash.call(value, current_language)
191
+
192
+ next unless key == 'errorKeys' and value.kind_of?(Array) and value.count > 0
193
+ # Prepend the error with the language so it's easier to understand for the user
194
+ errors += value.collect do |current_error_message|
195
+ current_language ? "[#{current_language}]: #{current_error_message}" : current_error_message
196
+ end
197
+ end
198
+ elsif hash.kind_of? Array
199
+ hash.each do |value|
200
+ errors += handle_response_hash.call(value)
201
+ end
202
+ # else: We don't care about simple values
203
+ end
204
+ return errors
205
+ end
206
+
207
+ errors = handle_response_hash.call(data)
208
+ errors += data.fetch('sectionErrorKeys', [])
209
+ errors += data.fetch('validationErrors', [])
210
+
211
+ # Sometimes there is a different kind of error in the JSON response
212
+ # e.g. {"warn"=>nil, "error"=>["operation_failed"], "info"=>nil}
213
+ different_error = raw.fetch('messages', {}).fetch('error', nil)
214
+ errors << different_error if different_error
215
+
216
+ if errors.count > 0 # they are separated by `.` by default
217
+ if errors.count == 1 and errors.first == "You haven't made any changes."
218
+ # This is a special error which we really don't care about
219
+ elsif errors.count == 1 and errors.first.include?("try again later")
220
+ raise ITunesConnectTemporaryError.new, errors.first
221
+ else
222
+ raise ITunesConnectError.new, errors.join(' ')
223
+ end
224
+ end
225
+
226
+ puts data['sectionInfoKeys'] if data['sectionInfoKeys']
227
+ puts data['sectionWarningKeys'] if data['sectionWarningKeys']
228
+
229
+ return data
230
+ end
231
+ # rubocop:enable Metrics/PerceivedComplexity
232
+
233
+ #####################################################
234
+ # @!group Applications
235
+ #####################################################
236
+
237
+ def applications
238
+ r = request(:get, 'ra/apps/manageyourapps/summary/v2')
239
+ parse_response(r, 'data')['summaries']
240
+ end
241
+
242
+ def app_details(app_id)
243
+ r = request(:get, "ra/apps/#{app_id}/details")
244
+ parse_response(r, 'data')
245
+ end
246
+
247
+ def update_app_details!(app_id, data)
248
+ r = request(:post) do |req|
249
+ req.url "ra/apps/#{app_id}/details"
250
+ req.body = data.to_json
251
+ req.headers['Content-Type'] = 'application/json'
252
+ end
253
+
254
+ handle_itc_response(r.body)
255
+ end
256
+
257
+ # Creates a new application on iTunes Connect
258
+ # @param name (String): The name of your app as it will appear on the App Store.
259
+ # This can't be longer than 255 characters.
260
+ # @param primary_language (String): If localized app information isn't available in an
261
+ # App Store territory, the information from your primary language will be used instead.
262
+ # @param version (String): The version number is shown on the App Store and should
263
+ # match the one you used in Xcode.
264
+ # @param sku (String): A unique ID for your app that is not visible on the App Store.
265
+ # @param bundle_id (String): The bundle ID must match the one you used in Xcode. It
266
+ # can't be changed after you submit your first build.
267
+ def create_application!(name: nil, primary_language: nil, version: nil, sku: nil, bundle_id: nil, bundle_id_suffix: nil, company_name: nil, platform: nil)
268
+ # First, we need to fetch the data from Apple, which we then modify with the user's values
269
+ primary_language ||= "English"
270
+ platform ||= "ios"
271
+ r = request(:get, "ra/apps/create/v2/?platformString=#{platform}")
272
+ data = parse_response(r, 'data')
273
+
274
+ # Now fill in the values we have
275
+ # some values are nil, that's why there is a hash
276
+ data['versionString'] = { value: version }
277
+ data['name'] = { value: name }
278
+ data['bundleId'] = { value: bundle_id }
279
+ data['primaryLanguage'] = { value: primary_language }
280
+ data['primaryLocaleCode'] = { value: primary_language.to_itc_locale }
281
+ data['vendorId'] = { value: sku }
282
+ data['bundleIdSuffix'] = { value: bundle_id_suffix }
283
+ data['companyName'] = { value: company_name } if company_name
284
+ data['enabledPlatformsForCreation'] = { value: [platform] }
285
+
286
+ data['initialPlatform'] = platform
287
+ data['enabledPlatformsForCreation'] = { value: [platform] }
288
+
289
+ # Now send back the modified hash
290
+ r = request(:post) do |req|
291
+ req.url 'ra/apps/create/v2'
292
+ req.body = data.to_json
293
+ req.headers['Content-Type'] = 'application/json'
294
+ end
295
+
296
+ data = parse_response(r, 'data')
297
+ handle_itc_response(data)
298
+ end
299
+
300
+ def create_version!(app_id, version_number, platform = 'ios')
301
+ r = request(:post) do |req|
302
+ req.url "ra/apps/#{app_id}/platforms/#{platform}/versions/create/"
303
+ req.body = {
304
+ version: {
305
+ value: version_number.to_s
306
+ }
307
+ }.to_json
308
+ req.headers['Content-Type'] = 'application/json'
309
+ end
310
+
311
+ data = parse_response(r, 'data')
312
+ handle_itc_response(data)
313
+ end
314
+
315
+ def get_resolution_center(app_id, platform)
316
+ r = request(:get, "ra/apps/#{app_id}/platforms/#{platform}/resolutionCenter?v=latest")
317
+ parse_response(r, 'data')
318
+ end
319
+
320
+ def get_rating_summary(app_id, platform, versionId = '')
321
+ r = request(:get, "ra/apps/#{app_id}/reviews/summary?platform=#{platform}&versionId=#{versionId}")
322
+ parse_response(r, 'data')
323
+ end
324
+
325
+ def get_reviews(app_id, platform, storefront, versionId = '')
326
+ r = request(:get, "ra/apps/#{app_id}/reviews?platform=#{platform}&storefront=#{storefront}&versionId=#{versionId}")
327
+ parse_response(r, 'data')['reviews']
328
+ end
329
+
330
+ #####################################################
331
+ # @!group AppVersions
332
+ #####################################################
333
+
334
+ def app_version(app_id, is_live, platform: nil)
335
+ raise "app_id is required" unless app_id
336
+
337
+ # First we need to fetch the IDs for the edit / live version
338
+ r = request(:get, "ra/apps/#{app_id}/overview")
339
+ platforms = parse_response(r, 'data')['platforms']
340
+
341
+ platform = Spaceship::Tunes::AppVersionCommon.find_platform(platforms, search_platform: platform)
342
+ return nil unless platform
343
+
344
+ version_id = Spaceship::Tunes::AppVersionCommon.find_version_id(platform, is_live)
345
+ return nil unless version_id
346
+
347
+ version_platform = platform['platformString']
348
+
349
+ app_version_data(app_id, version_platform: version_platform, version_id: version_id)
350
+ end
351
+
352
+ def app_version_data(app_id, version_platform: nil, version_id: nil)
353
+ raise "app_id is required" unless app_id
354
+ raise "version_platform is required" unless version_platform
355
+ raise "version_id is required" unless version_id
356
+
357
+ r = request(:get, "ra/apps/#{app_id}/platforms/#{version_platform}/versions/#{version_id}")
358
+ parse_response(r, 'data')
359
+ end
360
+
361
+ def update_app_version!(app_id, version_id, data)
362
+ raise "app_id is required" unless app_id
363
+ raise "version_id is required" unless version_id.to_i > 0
364
+
365
+ with_tunes_retry do
366
+ r = request(:post) do |req|
367
+ req.url "ra/apps/#{app_id}/platforms/ios/versions/#{version_id}"
368
+ req.body = data.to_json
369
+ req.headers['Content-Type'] = 'application/json'
370
+ end
371
+
372
+ handle_itc_response(r.body)
373
+ end
374
+ end
375
+
376
+ #####################################################
377
+ # @!group Pricing
378
+ #####################################################
379
+
380
+ def update_price_tier!(app_id, price_tier)
381
+ r = request(:get, "ra/apps/#{app_id}/pricing/intervals")
382
+ data = parse_response(r, 'data')
383
+
384
+ first_price = (data["pricingIntervalsFieldTO"]["value"] || []).count == 0 # first price
385
+ data["pricingIntervalsFieldTO"]["value"] ||= []
386
+ data["pricingIntervalsFieldTO"]["value"] << {} if data["pricingIntervalsFieldTO"]["value"].count == 0
387
+ data["pricingIntervalsFieldTO"]["value"].first["tierStem"] = price_tier.to_s
388
+
389
+ effective_date = (first_price ? nil : Time.now.to_i * 1000)
390
+ data["pricingIntervalsFieldTO"]["value"].first["priceTierEffectiveDate"] = effective_date
391
+ data["pricingIntervalsFieldTO"]["value"].first["priceTierEndDate"] = nil
392
+ data["countriesChanged"] = first_price
393
+ data["theWorld"] = true
394
+
395
+ if first_price # first price, need to set all countries
396
+ data["countries"] = supported_countries.collect do |c|
397
+ c.delete('region') # we don't care about le region
398
+ c
399
+ end
400
+ end
401
+
402
+ # send the changes back to Apple
403
+ r = request(:post) do |req|
404
+ req.url "ra/apps/#{app_id}/pricing/intervals"
405
+ req.body = data.to_json
406
+ req.headers['Content-Type'] = 'application/json'
407
+ end
408
+ handle_itc_response(r.body)
409
+ end
410
+
411
+ def price_tier(app_id)
412
+ r = request(:get, "ra/apps/#{app_id}/pricing/intervals")
413
+ data = parse_response(r, 'data')
414
+
415
+ begin
416
+ data["pricingIntervalsFieldTO"]["value"].first["tierStem"]
417
+ rescue
418
+ nil
419
+ end
420
+ end
421
+
422
+ # Returns an array of all available pricing tiers
423
+ #
424
+ # @note Although this information is publicly available, the current spaceship implementation requires you to have a logged in client to access it
425
+ #
426
+ # @return [Array] the PricingTier objects (Spaceship::Tunes::PricingTier)
427
+ # [{
428
+ # "tierStem": "0",
429
+ # "tierName": "Free",
430
+ # "pricingInfo": [{
431
+ # "country": "United States",
432
+ # "countryCode": "US",
433
+ # "currencySymbol": "$",
434
+ # "currencyCode": "USD",
435
+ # "wholesalePrice": 0.0,
436
+ # "retailPrice": 0.0,
437
+ # "fRetailPrice": "$0.00",
438
+ # "fWholesalePrice": "$0.00"
439
+ # }, {
440
+ # ...
441
+ # }, {
442
+ # ...
443
+ def pricing_tiers
444
+ r = request(:get, 'ra/apps/pricing/matrix')
445
+ data = parse_response(r, 'data')['pricingTiers']
446
+ data.map { |tier| Spaceship::Tunes::PricingTier.factory(tier) }
447
+ end
448
+
449
+ # An array of supported countries
450
+ # [{
451
+ # "code": "AL",
452
+ # "name": "Albania",
453
+ # "region": "Europe"
454
+ # }, {
455
+ # ...
456
+ def supported_countries
457
+ r = request(:get, "ra/apps/pricing/supportedCountries")
458
+ parse_response(r, 'data')
459
+ end
460
+
461
+ #####################################################
462
+ # @!group App Icons
463
+ #####################################################
464
+ # Uploads a large icon
465
+ # @param app_version (AppVersion): The version of your app
466
+ # @param upload_image (UploadFile): The icon to upload
467
+ # @return [JSON] the response
468
+ def upload_large_icon(app_version, upload_image)
469
+ raise "app_version is required" unless app_version
470
+ raise "upload_image is required" unless upload_image
471
+
472
+ du_client.upload_large_icon(app_version, upload_image, content_provider_id, sso_token_for_image)
473
+ end
474
+
475
+ # Uploads a watch icon
476
+ # @param app_version (AppVersion): The version of your app
477
+ # @param upload_image (UploadFile): The icon to upload
478
+ # @return [JSON] the response
479
+ def upload_watch_icon(app_version, upload_image)
480
+ raise "app_version is required" unless app_version
481
+ raise "upload_image is required" unless upload_image
482
+
483
+ du_client.upload_watch_icon(app_version, upload_image, content_provider_id, sso_token_for_image)
484
+ end
485
+
486
+ # Uploads a screenshot
487
+ # @param app_version (AppVersion): The version of your app
488
+ # @param upload_image (UploadFile): The image to upload
489
+ # @param device (string): The target device
490
+ # @param is_messages (Bool): True if the screenshot is for iMessage
491
+ # @return [JSON] the response
492
+ def upload_screenshot(app_version, upload_image, device, is_messages)
493
+ raise "app_version is required" unless app_version
494
+ raise "upload_image is required" unless upload_image
495
+ raise "device is required" unless device
496
+
497
+ du_client.upload_screenshot(app_version, upload_image, content_provider_id, sso_token_for_image, device, is_messages)
498
+ end
499
+
500
+ # Uploads an iMessage screenshot
501
+ # @param app_version (AppVersion): The version of your app
502
+ # @param upload_image (UploadFile): The image to upload
503
+ # @param device (string): The target device
504
+ # @return [JSON] the response
505
+ def upload_messages_screenshot(app_version, upload_image, device)
506
+ raise "app_version is required" unless app_version
507
+ raise "upload_image is required" unless upload_image
508
+ raise "device is required" unless device
509
+
510
+ du_client.upload_messages_screenshot(app_version, upload_image, content_provider_id, sso_token_for_image, device)
511
+ end
512
+
513
+ # Uploads the transit app file
514
+ # @param app_version (AppVersion): The version of your app
515
+ # @param upload_file (UploadFile): The image to upload
516
+ # @return [JSON] the response
517
+ def upload_geojson(app_version, upload_file)
518
+ raise "app_version is required" unless app_version
519
+ raise "upload_file is required" unless upload_file
520
+
521
+ du_client.upload_geojson(app_version, upload_file, content_provider_id, sso_token_for_image)
522
+ end
523
+
524
+ # Uploads the transit app file
525
+ # @param app_version (AppVersion): The version of your app
526
+ # @param upload_trailer (UploadFile): The trailer to upload
527
+ # @return [JSON] the response
528
+ def upload_trailer(app_version, upload_trailer)
529
+ raise "app_version is required" unless app_version
530
+ raise "upload_trailer is required" unless upload_trailer
531
+
532
+ du_client.upload_trailer(app_version, upload_trailer, content_provider_id, sso_token_for_video)
533
+ end
534
+
535
+ # Uploads the trailer preview
536
+ # @param app_version (AppVersion): The version of your app
537
+ # @param upload_trailer_preview (UploadFile): The trailer preview to upload
538
+ # @return [JSON] the response
539
+ def upload_trailer_preview(app_version, upload_trailer_preview)
540
+ raise "app_version is required" unless app_version
541
+ raise "upload_trailer_preview is required" unless upload_trailer_preview
542
+
543
+ du_client.upload_trailer_preview(app_version, upload_trailer_preview, content_provider_id, sso_token_for_image)
544
+ end
545
+
546
+ # Fetches the App Version Reference information from ITC
547
+ # @return [AppVersionRef] the response
548
+ def ref_data
549
+ r = request(:get, '/WebObjects/iTunesConnect.woa/ra/apps/version/ref')
550
+ data = parse_response(r, 'data')
551
+ Spaceship::Tunes::AppVersionRef.factory(data)
552
+ end
553
+
554
+ # Fetches the User Detail information from ITC. This gets called often and almost never changes
555
+ # so we cache it
556
+ # @return [UserDetail] the response
557
+ def user_detail_data
558
+ return @cached if @cached
559
+ r = request(:get, '/WebObjects/iTunesConnect.woa/ra/user/detail')
560
+ data = parse_response(r, 'data')
561
+ @cached = Spaceship::Tunes::UserDetail.factory(data)
562
+ end
563
+
564
+ #####################################################
565
+ # @!group CandiateBuilds
566
+ #####################################################
567
+
568
+ def candidate_builds(app_id, version_id)
569
+ r = request(:get, "ra/apps/#{app_id}/versions/#{version_id}/candidateBuilds")
570
+ parse_response(r, 'data')['builds']
571
+ end
572
+
573
+ #####################################################
574
+ # @!group Build Trains
575
+ #####################################################
576
+
577
+ # @param (testing_type) internal or external
578
+ def build_trains(app_id, testing_type, platform: nil)
579
+ raise "app_id is required" unless app_id
580
+ url = "ra/apps/#{app_id}/trains/?testingType=#{testing_type}"
581
+ url += "&platform=#{platform}" unless platform.nil?
582
+ r = request(:get, url)
583
+ parse_response(r, 'data')
584
+ end
585
+
586
+ def update_build_trains!(app_id, testing_type, data)
587
+ raise "app_id is required" unless app_id
588
+
589
+ # The request fails if this key is present in the data
590
+ data.delete("dailySubmissionCountByPlatform")
591
+
592
+ r = request(:post) do |req|
593
+ req.url "ra/apps/#{app_id}/testingTypes/#{testing_type}/trains/"
594
+ req.body = data.to_json
595
+ req.headers['Content-Type'] = 'application/json'
596
+ end
597
+
598
+ handle_itc_response(r.body)
599
+ end
600
+
601
+ def remove_testflight_build_from_review!(app_id: nil, train: nil, build_number: nil, platform: 'ios')
602
+ r = request(:post) do |req|
603
+ req.url "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/reject"
604
+ req.body = {}.to_json
605
+ req.headers['Content-Type'] = 'application/json'
606
+ end
607
+ handle_itc_response(r.body)
608
+ end
609
+
610
+ # All build trains, even if there is no TestFlight
611
+ def all_build_trains(app_id: nil, platform: 'ios')
612
+ platform = 'ios' if platform.nil?
613
+ r = request(:get, "ra/apps/#{app_id}/buildHistory?platform=#{platform}")
614
+ handle_itc_response(r.body)
615
+ end
616
+
617
+ def all_builds_for_train(app_id: nil, train: nil, platform: 'ios')
618
+ platform = 'ios' if platform.nil?
619
+ r = request(:get, "ra/apps/#{app_id}/trains/#{train}/buildHistory?platform=#{platform}")
620
+ handle_itc_response(r.body)
621
+ end
622
+
623
+ def build_details(app_id: nil, train: nil, build_number: nil, platform: nil)
624
+ r = request(:get, "ra/apps/#{app_id}/platforms/#{platform || 'ios'}/trains/#{train}/builds/#{build_number}/details")
625
+ handle_itc_response(r.body)
626
+ end
627
+
628
+ def update_build_information!(app_id: nil,
629
+ train: nil,
630
+ build_number: nil,
631
+
632
+ # optional:
633
+ whats_new: nil,
634
+ description: nil,
635
+ feedback_email: nil,
636
+ platform: 'ios')
637
+ url = "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/testInformation"
638
+
639
+ build_info = get_build_info_for_review(app_id: app_id, train: train, build_number: build_number, platform: platform)
640
+ build_info["details"].each do |current|
641
+ current["whatsNew"]["value"] = whats_new if whats_new
642
+ current["description"]["value"] = description if description
643
+ current["feedbackEmail"]["value"] = feedback_email if feedback_email
644
+ end
645
+
646
+ review_user_name = build_info['reviewUserName']['value']
647
+ review_password = build_info['reviewPassword']['value']
648
+ build_info['reviewAccountRequired']['value'] = (review_user_name.to_s + review_password.to_s).length > 0
649
+
650
+ # Now send everything back to iTC
651
+ r = request(:post) do |req| # same URL, but a POST request
652
+ req.url url
653
+ req.body = build_info.to_json
654
+ req.headers['Content-Type'] = 'application/json'
655
+ end
656
+ handle_itc_response(r.body)
657
+ end
658
+
659
+ # rubocop:disable Metrics/ParameterLists
660
+ def submit_testflight_build_for_review!(app_id: nil, train: nil, build_number: nil, platform: 'ios',
661
+ # Required Metadata:
662
+ changelog: nil,
663
+ description: nil,
664
+ feedback_email: nil,
665
+ marketing_url: nil,
666
+ first_name: nil,
667
+ last_name: nil,
668
+ review_email: nil,
669
+ phone_number: nil,
670
+ significant_change: false,
671
+
672
+ # Optional Metadata:
673
+ privacy_policy_url: nil,
674
+ review_user_name: nil,
675
+ review_password: nil,
676
+ review_notes: nil,
677
+ encryption: false,
678
+ encryption_updated: false,
679
+ is_exempt: false,
680
+ proprietary: false,
681
+ third_party: false)
682
+
683
+ build_info = get_build_info_for_review(app_id: app_id, train: train, build_number: build_number, platform: platform)
684
+ # Now fill in the values provided by the user
685
+
686
+ # First the localised values:
687
+ build_info['details'].each do |current|
688
+ current['whatsNew']['value'] = changelog if changelog
689
+ current['description']['value'] = description if description
690
+ current['feedbackEmail']['value'] = feedback_email if feedback_email
691
+ current['marketingUrl']['value'] = marketing_url if marketing_url
692
+ current['privacyPolicyUrl']['value'] = privacy_policy_url if privacy_policy_url
693
+ current['pageLanguageValue'] = current['language'] # There is no valid reason why we need this, only iTC being iTC
694
+ end
695
+
696
+ review_info = {
697
+ "significantChange" => {
698
+ "value" => significant_change
699
+ },
700
+ "buildTestInformationTO" => build_info,
701
+ "exportComplianceTO" => {
702
+ "usesEncryption" => {
703
+ "value" => encryption
704
+ },
705
+ "encryptionUpdated" => {
706
+ "value" => encryption_updated
707
+ },
708
+ "isExempt" => {
709
+ "value" => is_exempt
710
+ },
711
+ "containsProprietaryCryptography" => {
712
+ "value" => proprietary
713
+ },
714
+ "containsThirdPartyCryptography" => {
715
+ "value" => third_party
716
+ }
717
+ }
718
+ }
719
+
720
+ r = request(:post) do |req| # same URL, but a POST request
721
+ req.url "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/review/submit"
722
+
723
+ req.body = review_info.to_json
724
+ req.headers['Content-Type'] = 'application/json'
725
+ end
726
+ handle_itc_response(r.body)
727
+ end
728
+ # rubocop:enable Metrics/ParameterLists
729
+
730
+ def get_build_info_for_review(app_id: nil, train: nil, build_number: nil, platform: 'ios')
731
+ url = "ra/apps/#{app_id}/platforms/#{platform}/trains/#{train}/builds/#{build_number}/testInformation"
732
+ r = request(:get) do |req|
733
+ req.url url
734
+ req.headers['Content-Type'] = 'application/json'
735
+ end
736
+ handle_itc_response(r.body)
737
+
738
+ r.body['data']
739
+ end
740
+
741
+ #####################################################
742
+ # @!group Submit for Review
743
+ #####################################################
744
+
745
+ def prepare_app_submissions(app_id, version)
746
+ raise "app_id is required" unless app_id
747
+ raise "version is required" unless version
748
+
749
+ r = request(:get) do |req|
750
+ req.url "ra/apps/#{app_id}/versions/#{version}/submit/summary"
751
+ req.headers['Content-Type'] = 'application/json'
752
+ end
753
+
754
+ handle_itc_response(r.body)
755
+ parse_response(r, 'data')
756
+ end
757
+
758
+ def send_app_submission(app_id, data)
759
+ raise "app_id is required" unless app_id
760
+
761
+ # ra/apps/1039164429/version/submit/complete
762
+ r = request(:post) do |req|
763
+ req.url "ra/apps/#{app_id}/version/submit/complete"
764
+ req.body = data.to_json
765
+ req.headers['Content-Type'] = 'application/json'
766
+ end
767
+
768
+ handle_itc_response(r.body)
769
+
770
+ if r.body.fetch('messages').fetch('info').last == "Successful POST"
771
+ # success
772
+ else
773
+ raise "Something went wrong when submitting the app for review. Make sure to pass valid options to submit your app for review"
774
+ end
775
+
776
+ parse_response(r, 'data')
777
+ end
778
+
779
+ #####################################################
780
+ # @!group release
781
+ #####################################################
782
+
783
+ def release!(app_id, version)
784
+ raise "app_id is required" unless app_id
785
+ raise "version is required" unless version
786
+
787
+ r = request(:post) do |req|
788
+ req.url "ra/apps/#{app_id}/versions/#{version}/releaseToStore"
789
+ req.headers['Content-Type'] = 'application/json'
790
+ req.body = app_id.to_s
791
+ end
792
+
793
+ handle_itc_response(r.body)
794
+ parse_response(r, 'data')
795
+ end
796
+
797
+ #####################################################
798
+ # @!group Testers
799
+ #####################################################
800
+ def testers(tester)
801
+ url = tester.url[:index]
802
+ r = request(:get, url)
803
+ parse_response(r, 'data')['testers']
804
+ end
805
+
806
+ def testers_by_app(tester, app_id)
807
+ url = tester.url(app_id)[:index_by_app]
808
+ r = request(:get, url)
809
+ parse_response(r, 'data')['users']
810
+ end
811
+
812
+ def groups
813
+ return @cached_groups if @cached_groups
814
+ r = request(:get, '/WebObjects/iTunesConnect.woa/ra/users/pre/ext')
815
+ @cached_groups = parse_response(r, 'data')['groups']
816
+ end
817
+
818
+ def create_tester!(tester: nil, email: nil, first_name: nil, last_name: nil, groups: nil)
819
+ url = tester.url[:create]
820
+ raise "Action not provided for this tester type." unless url
821
+
822
+ tester_data = {
823
+ emailAddress: {
824
+ value: email
825
+ },
826
+ firstName: {
827
+ value: first_name || ""
828
+ },
829
+ lastName: {
830
+ value: last_name || ""
831
+ },
832
+ testing: {
833
+ value: true
834
+ }
835
+ }
836
+ if groups
837
+ tester_data[:groups] = groups.map { |x| { "id" => x } }
838
+ end
839
+
840
+ data = { testers: [tester_data] }
841
+
842
+ r = request(:post) do |req|
843
+ req.url url
844
+ req.body = data.to_json
845
+ req.headers['Content-Type'] = 'application/json'
846
+ end
847
+
848
+ data = parse_response(r, 'data')['testers']
849
+ handle_itc_response(data) || data[0]
850
+ end
851
+
852
+ def delete_tester!(tester)
853
+ url = tester.class.url[:delete]
854
+ raise "Action not provided for this tester type." unless url
855
+
856
+ data = [
857
+ {
858
+ emailAddress: {
859
+ value: tester.email
860
+ },
861
+ firstName: {
862
+ value: tester.first_name
863
+ },
864
+ lastName: {
865
+ value: tester.last_name
866
+ },
867
+ testing: {
868
+ value: false
869
+ },
870
+ userName: tester.email,
871
+ testerId: tester.tester_id
872
+ }
873
+ ]
874
+
875
+ r = request(:post) do |req|
876
+ req.url url
877
+ req.body = data.to_json
878
+ req.headers['Content-Type'] = 'application/json'
879
+ end
880
+
881
+ data = parse_response(r, 'data')['testers']
882
+ handle_itc_response(data) || data[0]
883
+ end
884
+
885
+ def add_tester_to_app!(tester, app_id)
886
+ update_tester_from_app!(tester, app_id, true)
887
+ end
888
+
889
+ def remove_tester_from_app!(tester, app_id)
890
+ update_tester_from_app!(tester, app_id, false)
891
+ end
892
+
893
+ #####################################################
894
+ # @!group Sandbox Testers
895
+ #####################################################
896
+ def sandbox_testers(tester_class)
897
+ url = tester_class.url[:index]
898
+ r = request(:get, url)
899
+ parse_response(r, 'data')
900
+ end
901
+
902
+ def create_sandbox_tester!(tester_class: nil, email: nil, password: nil, first_name: nil, last_name: nil, country: nil)
903
+ url = tester_class.url[:create]
904
+ r = request(:post) do |req|
905
+ req.url url
906
+ req.body = {
907
+ user: {
908
+ emailAddress: { value: email },
909
+ password: { value: password },
910
+ confirmPassword: { value: password },
911
+ firstName: { value: first_name },
912
+ lastName: { value: last_name },
913
+ storeFront: { value: country },
914
+ birthDay: { value: 1 },
915
+ birthMonth: { value: 1 },
916
+ secretQuestion: { value: SecureRandom.hex },
917
+ secretAnswer: { value: SecureRandom.hex },
918
+ sandboxAccount: nil
919
+ }
920
+ }.to_json
921
+ req.headers['Content-Type'] = 'application/json'
922
+ end
923
+ parse_response(r, 'data')['user']
924
+ end
925
+
926
+ def delete_sandbox_testers!(tester_class, emails)
927
+ url = tester_class.url[:delete]
928
+ request(:post) do |req|
929
+ req.url url
930
+ req.body = emails.map do |email|
931
+ {
932
+ emailAddress: {
933
+ value: email
934
+ }
935
+ }
936
+ end.to_json
937
+ req.headers['Content-Type'] = 'application/json'
938
+ end
939
+ true
940
+ end
941
+
942
+ #####################################################
943
+ # @!group State History
944
+ #####################################################
945
+ def versions_history(app_id, platform)
946
+ r = request(:get, "ra/apps/#{app_id}/stateHistory?platform=#{platform}")
947
+ parse_response(r, 'data')['versions']
948
+ end
949
+
950
+ def version_states_history(app_id, platform, version_id)
951
+ r = request(:get, "ra/apps/#{app_id}/versions/#{version_id}/stateHistory?platform=#{platform}")
952
+ parse_response(r, 'data')
953
+ end
954
+
955
+ #####################################################
956
+ # @!group Promo codes
957
+ #####################################################
958
+ def app_promocodes(app_id: nil)
959
+ r = request(:get, "ra/apps/#{app_id}/promocodes/versions")
960
+ parse_response(r, 'data')['versions']
961
+ end
962
+
963
+ def generate_app_version_promocodes!(app_id: nil, version_id: nil, quantity: nil)
964
+ data = {
965
+ numberOfCodes: { value: quantity },
966
+ agreedToContract: { value: true }
967
+ }
968
+ url = "ra/apps/#{app_id}/promocodes/versions/#{version_id}"
969
+ r = request(:post) do |req|
970
+ req.url url
971
+ req.body = data.to_json
972
+ req.headers['Content-Type'] = 'application/json'
973
+ end
974
+ parse_response(r, 'data')
975
+ end
976
+
977
+ def app_promocodes_history(app_id: nil)
978
+ r = request(:get, "ra/apps/#{app_id}/promocodes/history")
979
+ parse_response(r, 'data')['requests']
980
+ end
981
+
982
+ #####################################################
983
+ # @!group reject
984
+ #####################################################
985
+
986
+ def reject!(app_id, version)
987
+ raise "app_id is required" unless app_id
988
+ raise "version is required" unless version
989
+
990
+ r = request(:post) do |req|
991
+ req.url "ra/apps/#{app_id}/versions/#{version}/reject"
992
+ req.headers['Content-Type'] = 'application/json'
993
+ req.body = app_id.to_s
994
+ end
995
+
996
+ handle_itc_response(r.body)
997
+ parse_response(r, 'data')
998
+ end
999
+
1000
+ private
1001
+
1002
+ def with_tunes_retry(tries = 5, &_block)
1003
+ return yield
1004
+ rescue Spaceship::TunesClient::ITunesConnectTemporaryError => ex
1005
+ unless (tries -= 1).zero?
1006
+ msg = "ITC temporary save error received: '#{ex.message}'. Retrying after 60 seconds (remaining: #{tries})..."
1007
+ puts msg
1008
+ logger.warn msg
1009
+ sleep 60 unless defined? SpecHelper # unless FastlaneCore::Helper.is_test?
1010
+ retry
1011
+ end
1012
+ raise ex # re-raise the exception
1013
+ end
1014
+
1015
+ def clear_user_cached_data
1016
+ @content_provider_id = nil
1017
+ @sso_token_for_image = nil
1018
+ @sso_token_for_video = nil
1019
+ end
1020
+
1021
+ # the contentProviderIr found in the UserDetail instance
1022
+ def content_provider_id
1023
+ @content_provider_id ||= user_detail_data.content_provider_id
1024
+ end
1025
+
1026
+ # the ssoTokenForImage found in the AppVersionRef instance
1027
+ def sso_token_for_image
1028
+ @sso_token_for_image ||= ref_data.sso_token_for_image
1029
+ end
1030
+
1031
+ # the ssoTokenForVideo found in the AppVersionRef instance
1032
+ def sso_token_for_video
1033
+ @sso_token_for_video ||= ref_data.sso_token_for_video
1034
+ end
1035
+
1036
+ def update_tester_from_app!(tester, app_id, testing)
1037
+ url = tester.class.url(app_id)[:update_by_app]
1038
+ data = {
1039
+ users: [
1040
+ {
1041
+ emailAddress: {
1042
+ value: tester.email
1043
+ },
1044
+ firstName: {
1045
+ value: tester.first_name
1046
+ },
1047
+ lastName: {
1048
+ value: tester.last_name
1049
+ },
1050
+ testing: {
1051
+ value: testing
1052
+ }
1053
+ }
1054
+ ]
1055
+ }
1056
+
1057
+ r = request(:post) do |req|
1058
+ req.url url
1059
+ req.body = data.to_json
1060
+ req.headers['Content-Type'] = 'application/json'
1061
+ end
1062
+
1063
+ data = parse_response(r, 'data')
1064
+ handle_itc_response(data)
1065
+ end
1066
+ end
1067
+ # rubocop:enable Metrics/ClassLength
1068
+ end