fastlane 2.128.1 → 2.133.0

Sign up to get free protection for your applications and to get access to all the features.
Files changed (124) hide show
  1. checksums.yaml +5 -5
  2. data/README.md +72 -72
  3. data/cert/lib/cert/module.rb +2 -0
  4. data/cert/lib/cert/options.rb +6 -0
  5. data/cert/lib/cert/runner.rb +17 -11
  6. data/deliver/lib/deliver/submit_for_review.rb +1 -1
  7. data/fastlane/lib/fastlane.rb +4 -1
  8. data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
  9. data/fastlane/lib/fastlane/actions/actions_helper.rb +4 -0
  10. data/fastlane/lib/fastlane/actions/app_store_build_number.rb +11 -3
  11. data/fastlane/lib/fastlane/actions/appetize_viewing_url_generator.rb +1 -1
  12. data/fastlane/lib/fastlane/actions/automatic_code_signing.rb +1 -1
  13. data/fastlane/lib/fastlane/actions/carthage.rb +4 -3
  14. data/fastlane/lib/fastlane/actions/commit_github_file.rb +1 -1
  15. data/fastlane/lib/fastlane/actions/copy_artifacts.rb +1 -1
  16. data/fastlane/lib/fastlane/actions/danger.rb +7 -0
  17. data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +23 -4
  18. data/fastlane/lib/fastlane/actions/download_dsyms.rb +35 -9
  19. data/fastlane/lib/fastlane/actions/ensure_env_vars.rb +58 -0
  20. data/fastlane/lib/fastlane/actions/get_version_number.rb +21 -2
  21. data/fastlane/lib/fastlane/actions/github_api.rb +1 -1
  22. data/fastlane/lib/fastlane/actions/gradle.rb +37 -8
  23. data/fastlane/lib/fastlane/actions/import_from_git.rb +1 -1
  24. data/fastlane/lib/fastlane/actions/onesignal.rb +59 -29
  25. data/fastlane/lib/fastlane/actions/pod_push.rb +29 -10
  26. data/fastlane/lib/fastlane/actions/puts.rb +1 -1
  27. data/fastlane/lib/fastlane/actions/register_devices.rb +38 -22
  28. data/fastlane/lib/fastlane/actions/resign.rb +2 -2
  29. data/fastlane/lib/fastlane/actions/slather.rb +1 -0
  30. data/fastlane/lib/fastlane/actions/sonar.rb +18 -0
  31. data/fastlane/lib/fastlane/actions/update_fastlane.rb +1 -1
  32. data/fastlane/lib/fastlane/commands_generator.rb +17 -1
  33. data/fastlane/lib/fastlane/fast_file.rb +7 -2
  34. data/fastlane/lib/fastlane/helper/adb_helper.rb +5 -0
  35. data/fastlane/lib/fastlane/helper/crashlytics_helper.rb +12 -6
  36. data/fastlane/lib/fastlane/plugins/plugin_manager.rb +2 -0
  37. data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +3 -0
  38. data/fastlane/lib/fastlane/setup/setup_android.rb +1 -1
  39. data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +126 -34
  40. data/fastlane/lib/fastlane/swift_fastlane_function.rb +82 -9
  41. data/fastlane/lib/fastlane/swift_runner_upgrader.rb +4 -0
  42. data/fastlane/lib/fastlane/version.rb +1 -1
  43. data/fastlane/swift/Actions.swift +15 -0
  44. data/fastlane/swift/Deliverfile.swift +1 -1
  45. data/fastlane/swift/DeliverfileProtocol.swift +121 -1
  46. data/fastlane/swift/Fastlane.swift +4164 -291
  47. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +9 -0
  48. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
  49. data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
  50. data/fastlane/swift/Gymfile.swift +1 -1
  51. data/fastlane/swift/GymfileProtocol.swift +93 -11
  52. data/fastlane/swift/Matchfile.swift +1 -1
  53. data/fastlane/swift/MatchfileProtocol.swift +65 -1
  54. data/fastlane/swift/Plugins.swift +15 -0
  55. data/fastlane/swift/Precheckfile.swift +1 -1
  56. data/fastlane/swift/PrecheckfileProtocol.swift +15 -2
  57. data/fastlane/swift/Scanfile.swift +1 -1
  58. data/fastlane/swift/ScanfileProtocol.swift +111 -3
  59. data/fastlane/swift/Screengrabfile.swift +1 -1
  60. data/fastlane/swift/ScreengrabfileProtocol.swift +39 -2
  61. data/fastlane/swift/Snapshotfile.swift +1 -1
  62. data/fastlane/swift/SnapshotfileProtocol.swift +71 -1
  63. data/fastlane/swift/upgrade_manifest.json +1 -1
  64. data/fastlane_core/lib/fastlane_core/analytics/analytics_event_builder.rb +1 -1
  65. data/fastlane_core/lib/fastlane_core/command_executor.rb +1 -1
  66. data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +1 -1
  67. data/fastlane_core/lib/fastlane_core/helper.rb +1 -1
  68. data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +1 -3
  69. data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +3 -2
  70. data/frameit/lib/frameit/editor.rb +1 -1
  71. data/frameit/lib/frameit/screenshot.rb +4 -0
  72. data/gym/lib/gym/.runner.rb.swp +0 -0
  73. data/gym/lib/gym/generators/build_command_generator.rb +5 -1
  74. data/gym/lib/gym/options.rb +17 -17
  75. data/gym/lib/gym/runner.rb +33 -5
  76. data/match/lib/match/generator.rb +1 -0
  77. data/match/lib/match/importer.rb +1 -1
  78. data/match/lib/match/module.rb +2 -0
  79. data/match/lib/match/nuke.rb +6 -6
  80. data/match/lib/match/options.rb +17 -0
  81. data/match/lib/match/runner.rb +12 -8
  82. data/match/lib/match/storage/git_storage.rb +8 -2
  83. data/match/lib/match/storage/google_cloud_storage.rb +85 -33
  84. data/match/lib/match/storage/interface.rb +1 -1
  85. data/produce/lib/produce/service.rb +7 -1
  86. data/scan/lib/scan/options.rb +1 -1
  87. data/scan/lib/scan/runner.rb +1 -1
  88. data/sigh/lib/sigh/download_all.rb +48 -8
  89. data/sigh/lib/sigh/runner.rb +13 -5
  90. data/snapshot/lib/assets/SnapshotHelper.swift +3 -3
  91. data/snapshot/lib/snapshot/commands_generator.rb +2 -2
  92. data/snapshot/lib/snapshot/options.rb +5 -0
  93. data/snapshot/lib/snapshot/reports_generator.rb +3 -0
  94. data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
  95. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher.rb +1 -1
  96. data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +16 -1
  97. data/snapshot/lib/snapshot/update.rb +4 -2
  98. data/spaceship/lib/spaceship/client.rb +1 -1
  99. data/spaceship/lib/spaceship/connect_api/models/app.rb +6 -6
  100. data/spaceship/lib/spaceship/connect_api/models/beta_tester_metric.rb +1 -0
  101. data/spaceship/lib/spaceship/connect_api/models/build.rb +3 -3
  102. data/spaceship/lib/spaceship/connect_api/models/build_delivery.rb +1 -1
  103. data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +1 -1
  104. data/spaceship/lib/spaceship/connect_api/models/certificate.rb +1 -1
  105. data/spaceship/lib/spaceship/connect_api/models/device.rb +1 -1
  106. data/spaceship/lib/spaceship/connect_api/models/profile.rb +1 -1
  107. data/spaceship/lib/spaceship/du/du_client.rb +4 -0
  108. data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
  109. data/spaceship/lib/spaceship/portal/certificate.rb +15 -1
  110. data/spaceship/lib/spaceship/portal/provisioning_profile.rb +1 -1
  111. data/spaceship/lib/spaceship/spaceauth_runner.rb +1 -1
  112. data/spaceship/lib/spaceship/test_flight/tester.rb +1 -1
  113. data/spaceship/lib/spaceship/tunes/app_version.rb +4 -0
  114. data/spaceship/lib/spaceship/tunes/application.rb +4 -0
  115. data/spaceship/lib/spaceship/tunes/availability.rb +40 -8
  116. data/spaceship/lib/spaceship/tunes/b2b_organization.rb +50 -0
  117. data/spaceship/lib/spaceship/tunes/build_details.rb +160 -18
  118. data/spaceship/lib/spaceship/tunes/display_family.rb +3 -3
  119. data/spaceship/lib/spaceship/tunes/iap.rb +2 -0
  120. data/spaceship/lib/spaceship/tunes/iap_detail.rb +17 -0
  121. data/spaceship/lib/spaceship/tunes/iap_family_details.rb +10 -2
  122. data/spaceship/lib/spaceship/tunes/tunes_client.rb +63 -2
  123. data/supply/lib/supply/client.rb +1 -1
  124. metadata +54 -47
@@ -6,7 +6,7 @@
6
6
 
7
7
  A new approach to iOS code signing: Share one code signing identity across your development team to simplify your codesigning setup and prevent code signing issues.
8
8
 
9
- _match_ is the implementation of the [https://codesigning.guide concept](https://codesigning.guide). _match_ creates all required certificates & provisioning profiles and stores them in a separate git repository. Every team member with access to the repo can use those credentials for code signing. _match_ also automatically repairs broken and expired credentials. It's the easiest way to share signing credentials across teams
9
+ _match_ is the implementation of the [codesigning.guide concept](https://codesigning.guide). _match_ creates all required certificates & provisioning profiles and stores them in a separate git repository. Every team member with access to the repo can use those credentials for code signing. _match_ also automatically repairs broken and expired credentials. It's the easiest way to share signing credentials across teams
10
10
 
11
11
  [More information on how to get started with codesigning](https://docs.fastlane.tools/codesigning/getting-started/)
12
12
 
@@ -79,7 +79,7 @@ You'll be asked if you want to store your code signing identities inside a **Git
79
79
 
80
80
  Use Git Storage to store all code signing identities in a private git repo, owned and operated by you. The files will be encrypted using OpenSSL.
81
81
 
82
- First, enter the URL to your private (!) Git repo (You can create one for free on e.g. [GitHub](https://github.com/new) or [BitBucket](https://bitbucket.org/repo/create)). The URL you enter can be either a `https://` or a `git` URL. (If your machine is currently using SSH to authenticate with GitHub, you'll want to use a `git` URL, otherwise you may see an authentication error when you attempt to use match.) `fastlane match init` won't read or modify your certificates or profiles yet, and also won't validate your git URL.
82
+ First, enter the URL to your private (!) Git repo (You can create one for free on e.g. [GitHub](https://github.com/new) or [BitBucket](https://bitbucket.org/repo/create)). The URL you enter can be either a `https://` or a `git` URL. `fastlane match init` won't read or modify your certificates or profiles yet, and also won't validate your git URL.
83
83
 
84
84
  This will create a `Matchfile` in your current directory (or in your `./fastlane/` folder).
85
85
 
@@ -92,6 +92,25 @@ app_identifier("tools.fastlane.app")
92
92
  username("user@fastlane.tools")
93
93
  ```
94
94
 
95
+ ##### Git Storage on GitHub
96
+
97
+ If your machine is currently using SSH to authenticate with GitHub, you'll want to use a `git` URL, otherwise, you may see an authentication error when you attempt to use match. Alternatively, you can set a basic authorization for _match_:
98
+
99
+ Using parameter:
100
+
101
+ ```
102
+ math(git_basic_authorization: '<YOUR KEY>')
103
+ ```
104
+
105
+ Using environment variable:
106
+
107
+ ```
108
+ ENV['MATCH_GIT_BASIC_AUTHORIZATION'] = '<YOUR KEY>'
109
+ match
110
+ ```
111
+
112
+ You can find more information about GitHub basic authentication and personal token generation here: [https://developer.github.com/v3/auth/#basic-authentication](https://developer.github.com/v3/auth/#basic-authentication)
113
+
95
114
  #### Google Cloud Storage
96
115
 
97
116
  Use [Google Cloud Storage](https://cloud.google.com/storage/) for a fully hosted solution for your code signing identities. Certificates are stored on Google Cloud, encrypted using Google managed keys. Everything will be stored on your Google account, inside a storage bucket you provide. You can also directly access the files using the web console.
@@ -119,7 +138,7 @@ match(git_branch: "team2", username: "user@team2.com")
119
138
 
120
139
  #### Google Cloud Storage
121
140
 
122
- If you use Google Cloud Storage, you don't need to do anything manually. Just use Google Cloud Storage, and the top level folder will be the team ID.
141
+ If you use Google Cloud Storage, you don't need to do anything manually for multiple teams. Just use Google Cloud Storage, and the top level folder will be the team ID.
123
142
 
124
143
  ### Run
125
144
 
@@ -214,7 +233,7 @@ There are two cases for reading and writing certificates stored in a Google Clou
214
233
  1. Continuous integration jobs. These will authenticate to your Google Cloud project via a service account, and use a `gc_keys.json` file as credentials.
215
234
  1. Developers on a local workstation. In this case, you should choose whether everyone on your team will create their own `gc_keys.json` file, or whether you want to manage access to the bucket directly using your developers' Google accounts.
216
235
 
217
- When running `fastlane match init` the first time, the setup process will give you the option to create your `gc_keys.json` file. This file contains the auth credentials needed to access your Google Cloud storage bucket. Make sure to keep that file secret and never add it to version control. We recommend adding `gc_keys.json` to your `.gitignore`
236
+ When running `fastlane match init` the first time, the setup process will give you the option to create your `gc_keys.json` file. This file contains the authentication credentials needed to access your Google Cloud storage bucket. Make sure to keep that file secret and never add it to version control. We recommend adding `gc_keys.json` to your `.gitignore`
218
237
 
219
238
  ##### Managing developer access via keys
220
239
  If you want to manage developer access to your certificates via authentication keys, every developer should create their own `gc_keys.json` and add the file to all their work machines. This will give the admin full control over who has read/write access to the given Storage bucket. At the same time it allows your team to revoke a single key if a file gets compromised.
@@ -25,6 +25,7 @@ module Fastlane
25
25
  build_number = params[:build_number]
26
26
  platform = params[:platform]
27
27
  output_directory = params[:output_directory]
28
+ wait_for_dsym_processing = params[:wait_for_dsym_processing]
28
29
  min_version = Gem::Version.new(params[:min_version]) if params[:min_version]
29
30
 
30
31
  # Set version if it is latest
@@ -85,14 +86,32 @@ module Fastlane
85
86
  next
86
87
  end
87
88
 
88
- begin
89
- UI.verbose("Build_version: #{build.build_version} matches #{build_number}, grabbing dsym_url") if build_number
90
-
91
- build_details = app.tunes_build_details(train: train.version_string, build_number: build.build_version, platform: platform)
92
- download_url = build_details.dsym_url
93
- UI.verbose("dsym_url: #{download_url}")
94
- rescue Spaceship::TunesClient::ITunesConnectError => ex
95
- UI.error("Error accessing dSYM file for build\n\n#{build}\n\nException: #{ex}")
89
+ UI.verbose("Build_version: #{build.build_version} matches #{build_number}, grabbing dsym_url") if build_number
90
+
91
+ start = Time.now
92
+ download_url = nil
93
+
94
+ loop do
95
+ begin
96
+ build_details = app.tunes_build_details(train: train.version_string, build_number: build.build_version, platform: platform)
97
+ download_url = build_details.dsym_url
98
+ UI.verbose("dsym_url: #{download_url}")
99
+ rescue Spaceship::TunesClient::ITunesConnectError => ex
100
+ UI.error("Error accessing dSYM file for build\n\n#{build}\n\nException: #{ex}")
101
+ end
102
+
103
+ unless download_url
104
+ if !wait_for_dsym_processing || (Time.now - start) > (60 * 5)
105
+ # In some cases, AppStoreConnect does not process the dSYMs, thus no error should be thrown.
106
+ UI.message("Could not find any dSYM for #{build.build_version} (#{train.version_string})")
107
+ else
108
+ UI.message("Waiting for dSYM file to appear...")
109
+ sleep(30)
110
+ next
111
+ end
112
+ end
113
+
114
+ break
96
115
  end
97
116
 
98
117
  if download_url
@@ -228,7 +247,14 @@ module Fastlane
228
247
  short_option: "-s",
229
248
  env_name: "DOWNLOAD_DSYMS_OUTPUT_DIRECTORY",
230
249
  description: "Where to save the download dSYMs, defaults to the current path",
231
- optional: true)
250
+ optional: true),
251
+ FastlaneCore::ConfigItem.new(key: :wait_for_dsym_processing,
252
+ short_option: "-w",
253
+ env_name: "DOWNLOAD_DSYMS_WAIT_FOR_DSYM_PROCESSING",
254
+ description: "Wait for dSYMs to process",
255
+ optional: true,
256
+ default_value: false,
257
+ type: Boolean)
232
258
  ]
233
259
  end
234
260
 
@@ -0,0 +1,58 @@
1
+ module Fastlane
2
+ module Actions
3
+ class EnsureEnvVarsAction < Action
4
+ def self.run(params)
5
+ variables = params[:env_vars]
6
+
7
+ variables.each do |variable|
8
+ next unless ENV[variable].to_s.strip.empty?
9
+
10
+ UI.user_error!("Missing environment variable '#{variable}'")
11
+ end
12
+
13
+ is_one = variables.length == 1
14
+
15
+ UI.success("Environment variable#{is_one ? '' : 's'} '#{variables.join('\', \'')}' #{is_one ? 'is' : 'are'} set!")
16
+ end
17
+
18
+ def self.description
19
+ 'Raises an exception if the specified env vars are not set'
20
+ end
21
+
22
+ def self.details
23
+ 'This action will check if some environment variables are set.'
24
+ end
25
+
26
+ def self.available_options
27
+ [
28
+ FastlaneCore::ConfigItem.new(key: :env_vars,
29
+ description: 'The environment variables names that should be checked',
30
+ type: Array,
31
+ verify_block: proc do |value|
32
+ UI.user_error!('Specify at least one environment variable name') if value.empty?
33
+ end)
34
+ ]
35
+ end
36
+
37
+ def self.authors
38
+ ['revolter']
39
+ end
40
+
41
+ def self.example_code
42
+ [
43
+ 'ensure_env_vars(
44
+ env_vars: [\'GITHUB_USER_NAME\', \'GITHUB_API_TOKEN\']
45
+ )'
46
+ ]
47
+ end
48
+
49
+ def self.category
50
+ :misc
51
+ end
52
+
53
+ def self.is_supported?(platform)
54
+ true
55
+ end
56
+ end
57
+ end
58
+ end
@@ -16,7 +16,15 @@ module Fastlane
16
16
  project = get_project!(folder)
17
17
  target = get_target!(project, target_name)
18
18
  plist_file = get_plist!(folder, target, configuration)
19
- version_number = get_version_number!(plist_file)
19
+ version_number = get_version_number_from_plist!(plist_file)
20
+
21
+ # Get from build settings if needed (ex: $(MARKETING_VERSION) is default in Xcode 11)
22
+ if version_number =~ /\$\(([\w\-]+)\)/
23
+ version_number = get_version_number_from_build_settings!(target, $1, configuration)
24
+ # ${MARKETING_VERSION} also works
25
+ elsif version_number =~ /\$\{([\w\-]+)\}/
26
+ version_number = get_version_number_from_build_settings!(target, $1, configuration)
27
+ end
20
28
 
21
29
  # Store the number in the shared hash
22
30
  Actions.lane_context[SharedValues::VERSION_NUMBER] = version_number
@@ -65,6 +73,17 @@ module Fastlane
65
73
  target
66
74
  end
67
75
 
76
+ def self.get_version_number_from_build_settings!(target, variable, configuration = nil)
77
+ target.build_configurations.each do |config|
78
+ if configuration.nil? || config.name == configuration
79
+ value = config.build_settings[variable]
80
+ return value if value
81
+ end
82
+ end
83
+
84
+ UI.user_error!("Unable to find Xcode build setting: #{variable}")
85
+ end
86
+
68
87
  def self.get_plist!(folder, target, configuration = nil)
69
88
  plist_files = target.resolved_build_setting("INFOPLIST_FILE")
70
89
  plist_files_count = plist_files.values.compact.uniq.count
@@ -94,7 +113,7 @@ module Fastlane
94
113
  plist_file
95
114
  end
96
115
 
97
- def self.get_version_number!(plist_file)
116
+ def self.get_version_number_from_plist!(plist_file)
98
117
  plist = Xcodeproj::Plist.read_from_path(plist_file)
99
118
  UI.user_error!("Unable to read plist: #{plist_file}") unless plist
100
119
 
@@ -113,7 +113,7 @@ module Fastlane
113
113
  optional: true),
114
114
  FastlaneCore::ConfigItem.new(key: :raw_body,
115
115
  env_name: "FL_GITHUB_API_REQUEST_RAW_BODY",
116
- description: "The request body taken vertabim instead of as JSON, useful for file uploads",
116
+ description: "The request body taken verbatim instead of as JSON, useful for file uploads",
117
117
  is_string: true,
118
118
  optional: true),
119
119
  FastlaneCore::ConfigItem.new(key: :path,
@@ -8,6 +8,8 @@ module Fastlane
8
8
  GRADLE_ALL_APK_OUTPUT_PATHS = :GRADLE_ALL_APK_OUTPUT_PATHS
9
9
  GRADLE_AAB_OUTPUT_PATH = :GRADLE_AAB_OUTPUT_PATH
10
10
  GRADLE_ALL_AAB_OUTPUT_PATHS = :GRADLE_ALL_AAB_OUTPUT_PATHS
11
+ GRADLE_OUTPUT_JSON_OUTPUT_PATH = :GRADLE_OUTPUT_JSON_OUTPUT_PATH
12
+ GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS = :GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS
11
13
  GRADLE_FLAVOR = :GRADLE_FLAVOR
12
14
  GRADLE_BUILD_TYPE = :GRADLE_BUILD_TYPE
13
15
  end
@@ -60,6 +62,7 @@ module Fastlane
60
62
 
61
63
  apk_search_path = File.join(project_dir, '**', 'build', 'outputs', 'apk', '**', '*.apk')
62
64
  aab_search_path = File.join(project_dir, '**', 'build', 'outputs', 'bundle', '**', '*.aab')
65
+ output_json_search_path = File.join(project_dir, '**', 'build', 'outputs', 'apk', '**', 'output.json')
63
66
 
64
67
  # Our apk/aab is now built, but there might actually be multiple ones that were built if a flavor was not specified in a multi-flavor project (e.g. `assembleRelease`)
65
68
  # However, we're not interested in unaligned apk's...
@@ -67,18 +70,23 @@ module Fastlane
67
70
  new_apks = new_apks.map { |path| File.expand_path(path) }
68
71
  new_aabs = Dir[aab_search_path]
69
72
  new_aabs = new_aabs.map { |path| File.expand_path(path) }
73
+ new_output_jsons = Dir[output_json_search_path]
74
+ new_output_jsons = new_output_jsons.map { |path| File.expand_path(path) }
70
75
 
71
76
  # We expose all of these new apks and aabs
72
77
  Actions.lane_context[SharedValues::GRADLE_ALL_APK_OUTPUT_PATHS] = new_apks
73
78
  Actions.lane_context[SharedValues::GRADLE_ALL_AAB_OUTPUT_PATHS] = new_aabs
79
+ Actions.lane_context[SharedValues::GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS] = new_output_jsons
74
80
 
75
81
  # We also take the most recent apk and aab to return as SharedValues::GRADLE_APK_OUTPUT_PATH and SharedValues::GRADLE_AAB_OUTPUT_PATH
76
82
  # This is the one that will be relevant for most projects that just build a single build variant (flavor + build type combo).
77
83
  # In multi build variants this value is undefined
78
84
  last_apk_path = new_apks.sort_by(&File.method(:mtime)).last
79
85
  last_aab_path = new_aabs.sort_by(&File.method(:mtime)).last
86
+ last_output_json_path = new_output_jsons.sort_by(&File.method(:mtime)).last
80
87
  Actions.lane_context[SharedValues::GRADLE_APK_OUTPUT_PATH] = File.expand_path(last_apk_path) if last_apk_path
81
88
  Actions.lane_context[SharedValues::GRADLE_AAB_OUTPUT_PATH] = File.expand_path(last_aab_path) if last_aab_path
89
+ Actions.lane_context[SharedValues::GRADLE_OUTPUT_JSON_OUTPUT_PATH] = File.expand_path(last_output_json_path) if last_output_json_path
82
90
 
83
91
  # Give a helpful message in case there were no new apks or aabs. Remember we're only running this code when assembling, in which case we certainly expect there to be an apk or aab
84
92
  UI.message('Couldn\'t find any new signed apk files...') if new_apks.empty? && new_aabs.empty?
@@ -102,7 +110,7 @@ module Fastlane
102
110
  [
103
111
  FastlaneCore::ConfigItem.new(key: :task,
104
112
  env_name: 'FL_GRADLE_TASK',
105
- description: 'The gradle task you want to execute, e.g. `assemble` or `test`. For tasks such as `assembleMyFlavorRelease` you should use gradle(task: \'assemble\', flavor: \'Myflavor\', build_type: \'Release\')',
113
+ description: 'The gradle task you want to execute, e.g. `assemble`, `bundle` or `test`. For tasks such as `assembleMyFlavorRelease` you should use gradle(task: \'assemble\', flavor: \'Myflavor\', build_type: \'Release\')',
106
114
  optional: false,
107
115
  is_string: true),
108
116
  FastlaneCore::ConfigItem.new(key: :flavor,
@@ -165,7 +173,9 @@ module Fastlane
165
173
  ['GRADLE_FLAVOR', 'The flavor, e.g. `MyFlavor`'],
166
174
  ['GRADLE_BUILD_TYPE', 'The build type, e.g. `Release`'],
167
175
  ['GRADLE_AAB_OUTPUT_PATH', 'The path to the most recent Android app bundle'],
168
- ['GRADLE_ALL_AAB_OUTPUT_PATHS', 'The paths to the most recent Android app bundles']
176
+ ['GRADLE_ALL_AAB_OUTPUT_PATHS', 'The paths to the most recent Android app bundles'],
177
+ ['GRADLE_OUTPUT_JSON_OUTPUT_PATH', 'The path to the most recent output.json file'],
178
+ ['GRADLE_ALL_OUTPUT_JSON_OUTPUT_PATHS', 'The path to the newly generated output.json files']
169
179
  ]
170
180
  end
171
181
 
@@ -187,8 +197,21 @@ module Fastlane
187
197
  task: "assemble",
188
198
  flavor: "WorldDomination",
189
199
  build_type: "Release"
190
- )',
191
- 'gradle(
200
+ )
201
+ ```
202
+
203
+ To build an AAB use:
204
+ ```ruby
205
+ gradle(
206
+ task: "bundle",
207
+ flavor: "WorldDomination",
208
+ build_type: "Release"
209
+ )
210
+ ```
211
+
212
+ You can pass properties to gradle:
213
+ ```ruby
214
+ gradle(
192
215
  # ...
193
216
 
194
217
  properties: {
@@ -211,8 +234,11 @@ module Fastlane
211
234
  "android.injected.signing.key.alias" => "key_alias",
212
235
  "android.injected.signing.key.password" => "key_password",
213
236
  }
214
- )',
215
- '# If you need to pass sensitive information through the `gradle` action, and don\'t want the generated command to be printed before it is run, you can suppress that:
237
+ )
238
+ ```
239
+
240
+ If you need to pass sensitive information through the `gradle` action, and don\'t want the generated command to be printed before it is run, you can suppress that:
241
+ ```ruby
216
242
  gradle(
217
243
  # ...
218
244
  print_command: false
@@ -233,8 +259,11 @@ module Fastlane
233
259
  # ...
234
260
 
235
261
  flags: "--exitcode --xml file.xml"
236
- )',
237
- '# Delete the build directory and generated APKs
262
+ )
263
+ ```
264
+
265
+ Delete the build directory, generated APKs and AABs
266
+ ```ruby
238
267
  gradle(
239
268
  task: "clean"
240
269
  )'
@@ -31,7 +31,7 @@ module Fastlane
31
31
  default_value: 'fastlane/Fastfile',
32
32
  optional: true),
33
33
  FastlaneCore::ConfigItem.new(key: :version,
34
- description: "The version to checkout on the respository. Optimistic match operator or multiple conditions can be used to select the latest version within constraints",
34
+ description: "The version to checkout on the repository. Optimistic match operator or multiple conditions can be used to select the latest version within constraints",
35
35
  default_value: nil,
36
36
  is_string: false,
37
37
  optional: true)
@@ -11,15 +11,26 @@ module Fastlane
11
11
  require 'uri'
12
12
  require 'base64'
13
13
 
14
- UI.message("Parameter App name: #{params[:app_name]}")
14
+ app_id = params[:app_id].to_s.strip
15
15
  auth_token = params[:auth_token]
16
- app_name = params[:app_name]
16
+ app_name = params[:app_name].to_s
17
17
  apns_p12_password = params[:apns_p12_password]
18
18
  android_token = params[:android_token]
19
19
  android_gcm_sender_id = params[:android_gcm_sender_id]
20
20
 
21
+ has_app_id = !app_id.empty?
22
+ has_app_name = !app_name.empty?
23
+
24
+ is_update = has_app_id
25
+
26
+ UI.user_error!('Please specify the `app_id` or the `app_name` parameters!') if !has_app_id && !has_app_name
27
+
28
+ UI.message("Parameter App ID: #{app_id}") if has_app_id
29
+ UI.message("Parameter App name: #{app_name}") if has_app_name
30
+
21
31
  payload = {}
22
- payload['name'] = app_name
32
+
33
+ payload['name'] = app_name if has_app_name
23
34
 
24
35
  unless params[:apns_p12].nil?
25
36
  data = File.read(params[:apns_p12])
@@ -33,61 +44,70 @@ module Fastlane
33
44
  payload["gcm_key"] = android_token unless android_token.nil?
34
45
  payload["android_gcm_sender_id"] = android_gcm_sender_id unless android_gcm_sender_id.nil?
35
46
 
36
- # here's the actual lifting - POST to OneSignal
47
+ # here's the actual lifting - POST or PUT to OneSignal
37
48
 
38
49
  json_headers = { 'Content-Type' => 'application/json', 'Authorization' => "Basic #{auth_token}" }
39
- uri = URI.parse('https://onesignal.com/api/v1/apps')
50
+ url = +'https://onesignal.com/api/v1/apps'
51
+ url << '/' + app_id if is_update
52
+ uri = URI.parse(url)
40
53
  http = Net::HTTP.new(uri.host, uri.port)
41
54
  http.use_ssl = true
42
- response = http.post(uri.path, payload.to_json, json_headers)
55
+
56
+ if is_update
57
+ response = http.put(uri.path, payload.to_json, json_headers)
58
+ else
59
+ response = http.post(uri.path, payload.to_json, json_headers)
60
+ end
61
+
43
62
  response_body = JSON.parse(response.body)
44
63
 
45
64
  Actions.lane_context[SharedValues::ONE_SIGNAL_APP_ID] = response_body["id"]
46
65
  Actions.lane_context[SharedValues::ONE_SIGNAL_APP_AUTH_KEY] = response_body["basic_auth_key"]
47
66
 
48
- check_response_code(response)
67
+ check_response_code(response, is_update)
49
68
  end
50
69
 
51
- def self.check_response_code(response)
70
+ def self.check_response_code(response, is_update)
52
71
  case response.code.to_i
53
72
  when 200, 204
54
- puts("Successfully created new OneSignal app".green)
73
+ UI.success("Successfully #{is_update ? 'updated' : 'created new'} OneSignal app")
55
74
  else
56
75
  UI.user_error!("Unexpected #{response.code} with response: #{response.body}")
57
76
  end
58
77
  end
59
78
 
60
79
  def self.description
61
- "Create a new [OneSignal](https://onesignal.com/) application"
80
+ "Create or update a new [OneSignal](https://onesignal.com/) application"
62
81
  end
63
82
 
64
83
  def self.details
65
- "You can use this action to automatically create a OneSignal application. You can also upload a `.p12` with password, a GCM key, or both."
84
+ "You can use this action to automatically create or update a OneSignal application. You can also upload a `.p12` with password, a GCM key, or both."
66
85
  end
67
86
 
68
87
  def self.available_options
69
88
  [
70
- FastlaneCore::ConfigItem.new(key: :auth_token,
71
- env_name: "ONE_SIGNAL_AUTH_KEY",
72
- sensitive: true,
73
- description: "OneSignal Authorization Key",
74
- verify_block: proc do |value|
75
- unless value.to_s.length > 0
76
- UI.error("Please add 'ENV[\"ONE_SIGNAL_AUTH_KEY\"] = \"your token\"' to your Fastfile's `before_all` section.")
77
- UI.user_error!("No ONE_SIGNAL_AUTH_KEY given.")
78
- end
79
- end),
89
+ FastlaneCore::ConfigItem.new(key: :app_id,
90
+ env_name: "ONE_SIGNAL_APP_ID",
91
+ sensitive: true,
92
+ description: "OneSignal App ID. Setting this updates an existing app",
93
+ optional: true),
80
94
 
81
- FastlaneCore::ConfigItem.new(key: :app_name,
82
- env_name: "ONE_SIGNAL_APP_NAME",
83
- description: "OneSignal App Name",
95
+ FastlaneCore::ConfigItem.new(key: :auth_token,
96
+ env_name: "ONE_SIGNAL_AUTH_KEY",
97
+ sensitive: true,
98
+ description: "OneSignal Authorization Key",
84
99
  verify_block: proc do |value|
85
- unless value.to_s.length > 0
86
- UI.error("Please add 'ENV[\"ONE_SIGNAL_APP_NAME\"] = \"Your app name\"' to your Fastfile's `before_all` section.")
87
- UI.user_error!("No ONE_SIGNAL_APP_NAME given.")
100
+ if value.to_s.empty?
101
+ UI.error("Please add 'ENV[\"ONE_SIGNAL_AUTH_KEY\"] = \"your token\"' to your Fastfile's `before_all` section.")
102
+ UI.user_error!("No ONE_SIGNAL_AUTH_KEY given.")
88
103
  end
89
104
  end),
90
105
 
106
+ FastlaneCore::ConfigItem.new(key: :app_name,
107
+ env_name: "ONE_SIGNAL_APP_NAME",
108
+ description: "OneSignal App Name. This is required when creating an app (in other words, when `:app_id` is not set, and optional when updating an app",
109
+ optional: true),
110
+
91
111
  FastlaneCore::ConfigItem.new(key: :android_token,
92
112
  env_name: "ANDROID_TOKEN",
93
113
  description: "ANDROID GCM KEY",
@@ -121,8 +141,8 @@ module Fastlane
121
141
 
122
142
  def self.output
123
143
  [
124
- ['ONE_SIGNAL_APP_ID', 'The OneSignal app ID of the newly created app'],
125
- ['ONE_SIGNAL_APP_AUTH_KEY', 'The auth token for the newly created OneSignal app']
144
+ ['ONE_SIGNAL_APP_ID', 'The app ID of the newly created or updated app'],
145
+ ['ONE_SIGNAL_APP_AUTH_KEY', 'The auth token for the newly created or updated app']
126
146
  ]
127
147
  end
128
148
 
@@ -144,6 +164,16 @@ module Fastlane
144
164
  apns_p12: "Path to Apple .p12 file (optional)",
145
165
  apns_p12_password: "Password for .p12 file (optional)",
146
166
  apns_env: "production/sandbox (defaults to production)"
167
+ )',
168
+ 'onesignal(
169
+ app_id: "Your OneSignal App ID",
170
+ auth_token: "Your OneSignal Auth Token",
171
+ app_name: "New Name for OneSignal App",
172
+ android_token: "Your Android GCM key (optional)",
173
+ android_gcm_sender_id: "Your Android GCM Sender ID (optional)",
174
+ apns_p12: "Path to Apple .p12 file (optional)",
175
+ apns_p12_password: "Password for .p12 file (optional)",
176
+ apns_env: "production/sandbox (defaults to production)"
147
177
  )'
148
178
  ]
149
179
  end