fastlane 2.128.1 → 2.133.0
Sign up to get free protection for your applications and to get access to all the features.
- checksums.yaml +5 -5
- data/README.md +72 -72
- data/cert/lib/cert/module.rb +2 -0
- data/cert/lib/cert/options.rb +6 -0
- data/cert/lib/cert/runner.rb +17 -11
- data/deliver/lib/deliver/submit_for_review.rb +1 -1
- data/fastlane/lib/fastlane.rb +4 -1
- data/fastlane/lib/fastlane/actions/.hockey.rb.swp +0 -0
- data/fastlane/lib/fastlane/actions/actions_helper.rb +4 -0
- data/fastlane/lib/fastlane/actions/app_store_build_number.rb +11 -3
- data/fastlane/lib/fastlane/actions/appetize_viewing_url_generator.rb +1 -1
- data/fastlane/lib/fastlane/actions/automatic_code_signing.rb +1 -1
- data/fastlane/lib/fastlane/actions/carthage.rb +4 -3
- data/fastlane/lib/fastlane/actions/commit_github_file.rb +1 -1
- data/fastlane/lib/fastlane/actions/copy_artifacts.rb +1 -1
- data/fastlane/lib/fastlane/actions/danger.rb +7 -0
- data/fastlane/lib/fastlane/actions/docs/sync_code_signing.md +23 -4
- data/fastlane/lib/fastlane/actions/download_dsyms.rb +35 -9
- data/fastlane/lib/fastlane/actions/ensure_env_vars.rb +58 -0
- data/fastlane/lib/fastlane/actions/get_version_number.rb +21 -2
- data/fastlane/lib/fastlane/actions/github_api.rb +1 -1
- data/fastlane/lib/fastlane/actions/gradle.rb +37 -8
- data/fastlane/lib/fastlane/actions/import_from_git.rb +1 -1
- data/fastlane/lib/fastlane/actions/onesignal.rb +59 -29
- data/fastlane/lib/fastlane/actions/pod_push.rb +29 -10
- data/fastlane/lib/fastlane/actions/puts.rb +1 -1
- data/fastlane/lib/fastlane/actions/register_devices.rb +38 -22
- data/fastlane/lib/fastlane/actions/resign.rb +2 -2
- data/fastlane/lib/fastlane/actions/slather.rb +1 -0
- data/fastlane/lib/fastlane/actions/sonar.rb +18 -0
- data/fastlane/lib/fastlane/actions/update_fastlane.rb +1 -1
- data/fastlane/lib/fastlane/commands_generator.rb +17 -1
- data/fastlane/lib/fastlane/fast_file.rb +7 -2
- data/fastlane/lib/fastlane/helper/adb_helper.rb +5 -0
- data/fastlane/lib/fastlane/helper/crashlytics_helper.rb +12 -6
- data/fastlane/lib/fastlane/plugins/plugin_manager.rb +2 -0
- data/fastlane/lib/fastlane/plugins/template/.rubocop.yml +3 -0
- data/fastlane/lib/fastlane/setup/setup_android.rb +1 -1
- data/fastlane/lib/fastlane/swift_fastlane_api_generator.rb +126 -34
- data/fastlane/lib/fastlane/swift_fastlane_function.rb +82 -9
- data/fastlane/lib/fastlane/swift_runner_upgrader.rb +4 -0
- data/fastlane/lib/fastlane/version.rb +1 -1
- data/fastlane/swift/Actions.swift +15 -0
- data/fastlane/swift/Deliverfile.swift +1 -1
- data/fastlane/swift/DeliverfileProtocol.swift +121 -1
- data/fastlane/swift/Fastlane.swift +4164 -291
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.pbxproj +9 -0
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcshareddata/IDEWorkspaceChecks.plist +8 -0
- data/fastlane/swift/FastlaneSwiftRunner/FastlaneSwiftRunner.xcodeproj/project.xcworkspace/xcuserdata/josh.xcuserdatad/UserInterfaceState.xcuserstate +0 -0
- data/fastlane/swift/Gymfile.swift +1 -1
- data/fastlane/swift/GymfileProtocol.swift +93 -11
- data/fastlane/swift/Matchfile.swift +1 -1
- data/fastlane/swift/MatchfileProtocol.swift +65 -1
- data/fastlane/swift/Plugins.swift +15 -0
- data/fastlane/swift/Precheckfile.swift +1 -1
- data/fastlane/swift/PrecheckfileProtocol.swift +15 -2
- data/fastlane/swift/Scanfile.swift +1 -1
- data/fastlane/swift/ScanfileProtocol.swift +111 -3
- data/fastlane/swift/Screengrabfile.swift +1 -1
- data/fastlane/swift/ScreengrabfileProtocol.swift +39 -2
- data/fastlane/swift/Snapshotfile.swift +1 -1
- data/fastlane/swift/SnapshotfileProtocol.swift +71 -1
- data/fastlane/swift/upgrade_manifest.json +1 -1
- data/fastlane_core/lib/fastlane_core/analytics/analytics_event_builder.rb +1 -1
- data/fastlane_core/lib/fastlane_core/command_executor.rb +1 -1
- data/fastlane_core/lib/fastlane_core/configuration/config_item.rb +1 -1
- data/fastlane_core/lib/fastlane_core/helper.rb +1 -1
- data/fastlane_core/lib/fastlane_core/itunes_transporter.rb +1 -3
- data/fastlane_core/lib/fastlane_core/ui/implementations/shell.rb +3 -2
- data/frameit/lib/frameit/editor.rb +1 -1
- data/frameit/lib/frameit/screenshot.rb +4 -0
- data/gym/lib/gym/.runner.rb.swp +0 -0
- data/gym/lib/gym/generators/build_command_generator.rb +5 -1
- data/gym/lib/gym/options.rb +17 -17
- data/gym/lib/gym/runner.rb +33 -5
- data/match/lib/match/generator.rb +1 -0
- data/match/lib/match/importer.rb +1 -1
- data/match/lib/match/module.rb +2 -0
- data/match/lib/match/nuke.rb +6 -6
- data/match/lib/match/options.rb +17 -0
- data/match/lib/match/runner.rb +12 -8
- data/match/lib/match/storage/git_storage.rb +8 -2
- data/match/lib/match/storage/google_cloud_storage.rb +85 -33
- data/match/lib/match/storage/interface.rb +1 -1
- data/produce/lib/produce/service.rb +7 -1
- data/scan/lib/scan/options.rb +1 -1
- data/scan/lib/scan/runner.rb +1 -1
- data/sigh/lib/sigh/download_all.rb +48 -8
- data/sigh/lib/sigh/runner.rb +13 -5
- data/snapshot/lib/assets/SnapshotHelper.swift +3 -3
- data/snapshot/lib/snapshot/commands_generator.rb +2 -2
- data/snapshot/lib/snapshot/options.rb +5 -0
- data/snapshot/lib/snapshot/reports_generator.rb +3 -0
- data/snapshot/lib/snapshot/simulator_launchers/launcher_configuration.rb +2 -0
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher.rb +1 -1
- data/snapshot/lib/snapshot/simulator_launchers/simulator_launcher_base.rb +16 -1
- data/snapshot/lib/snapshot/update.rb +4 -2
- data/spaceship/lib/spaceship/client.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/models/app.rb +6 -6
- data/spaceship/lib/spaceship/connect_api/models/beta_tester_metric.rb +1 -0
- data/spaceship/lib/spaceship/connect_api/models/build.rb +3 -3
- data/spaceship/lib/spaceship/connect_api/models/build_delivery.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/models/bundle_id.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/models/certificate.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/models/device.rb +1 -1
- data/spaceship/lib/spaceship/connect_api/models/profile.rb +1 -1
- data/spaceship/lib/spaceship/du/du_client.rb +4 -0
- data/spaceship/lib/spaceship/portal/.certificate.rb.swp +0 -0
- data/spaceship/lib/spaceship/portal/certificate.rb +15 -1
- data/spaceship/lib/spaceship/portal/provisioning_profile.rb +1 -1
- data/spaceship/lib/spaceship/spaceauth_runner.rb +1 -1
- data/spaceship/lib/spaceship/test_flight/tester.rb +1 -1
- data/spaceship/lib/spaceship/tunes/app_version.rb +4 -0
- data/spaceship/lib/spaceship/tunes/application.rb +4 -0
- data/spaceship/lib/spaceship/tunes/availability.rb +40 -8
- data/spaceship/lib/spaceship/tunes/b2b_organization.rb +50 -0
- data/spaceship/lib/spaceship/tunes/build_details.rb +160 -18
- data/spaceship/lib/spaceship/tunes/display_family.rb +3 -3
- data/spaceship/lib/spaceship/tunes/iap.rb +2 -0
- data/spaceship/lib/spaceship/tunes/iap_detail.rb +17 -0
- data/spaceship/lib/spaceship/tunes/iap_family_details.rb +10 -2
- data/spaceship/lib/spaceship/tunes/tunes_client.rb +63 -2
- data/supply/lib/supply/client.rb +1 -1
- 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 [
|
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.
|
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
|
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
|
-
|
89
|
-
|
90
|
-
|
91
|
-
|
92
|
-
|
93
|
-
|
94
|
-
|
95
|
-
|
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 =
|
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.
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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
|
-
|
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: :
|
71
|
-
|
72
|
-
|
73
|
-
|
74
|
-
|
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: :
|
82
|
-
env_name: "
|
83
|
-
|
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
|
-
|
86
|
-
UI.error("Please add 'ENV[\"
|
87
|
-
UI.user_error!("No
|
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
|
125
|
-
['ONE_SIGNAL_APP_AUTH_KEY', 'The auth token for the newly created
|
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
|