fastlane-plugin-dynatrace 0.1.7 → 1.0.0
Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA256:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: b1e38a109d92db2380ea11d2f46c22bf47d51089244fb4bea5d80b5e61ba99a6
|
4
|
+
data.tar.gz: 12544e3125d0150b485fd3a8b09b0dd23e456c3806e9418f0c50c578b96e7374
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: c332f1b61211ebe151c790e9402bdafae21606925b38acad64132d049046d22ae11a17f6f8fefb392f0501bc609c030f8f88f9742b9bfc3e8383742b942dda8f
|
7
|
+
data.tar.gz: 60724f36ca0fd22fd1b879c2ba6de2f42d954681907aad98084b4ee510d8e86603ee6ebfc3550c5e97f8c6e233c6a56676d10e6545c95aa82148a653f9b28398
|
data/README.md
CHANGED
@@ -10,135 +10,97 @@ This project is a [_fastlane_](https://github.com/fastlane/fastlane) plugin. To
|
|
10
10
|
fastlane add_plugin dynatrace
|
11
11
|
```
|
12
12
|
|
13
|
-
|
14
|
-
|
15
|
-
> Please note that sometimes the latest version of the DSS client may not be compatble with your environment if you have a managed cluster on an older version. In this case, please contact Dynatrace Support to obtain the correct version.
|
13
|
+
### Dynatrace Managed
|
14
|
+
If the installation is on version 1.195 or earlier the Symbolication Client has to be manually download and specified (`dtxDssClientPath`), else it's fetched and updated automatically. A matching version can be downloaded manually with this link [https://api.mobileagent.downloads.dynatrace.com/sprint-latest-dss-client/xyz](https://api.mobileagent.downloads.dynatrace.com/sprint-latest-dss-client/xyz) by replacing `xyz` with the 3-digit sprint version of your Dynatrace Managed installation.
|
16
15
|
|
17
16
|
## About the Dynatrace fastlane plugin
|
18
|
-
|
19
|
-
This plugin allows you to decode and upload symbolication files to Dynatrace. You can also use it to first download your latest dSYM files from AppStore Connect if you use Bitcode.
|
17
|
+
This plugin allows you to decode and upload symbol files (iOS) or just upload obfuscation mapping files (Android) to Dynatrace. You can also use it to first download your latest dSYM files from App Store Connect if you use Bitcode.
|
20
18
|
|
21
19
|
## Action: `dynatrace_process_symbols`
|
22
20
|
|
23
21
|
| Supported Platforms | ios, android |
|
24
22
|
|---------------------|--------------|
|
25
|
-
| Author | @MANassar |
|
26
|
-
|
27
23
|
|
28
24
|
## Is your app Bitcode enabled?
|
29
|
-
|
30
25
|
> Only applies for apps distributed via the AppStore or TestFlight.
|
31
26
|
|
32
|
-
|
33
|
-
If your app is bitcode enabled, then the dSYMs that are generated during the Xcode build are **_not_** the dSYMs you want to upload to Dynatrace. This is because Apple recompiles your application on their servers, generating new dSYM files in the process. These newly generated dSYM files need to be downloaded from *AppStore Connect*, then processed and uploaded to Dynatrace.
|
27
|
+
If your app is bitcode enabled, then the dSYMs that are generated during the Xcode build are **_not_** the dSYMs you want to upload to Dynatrace. This is because Apple recompiles the application on their servers, generating new dSYM files in the process. These newly generated dSYM files need to be downloaded from *App Store Connect*, then processed and uploaded to Dynatrace.
|
34
28
|
|
35
29
|
### Important
|
30
|
+
There is a time gap between the application being uploaded to App Store Connect and the dSYM files to be ready. So **_we have to introduce some "wait" time in the CI to accomodate for this_**. You can do this by setting the `waitForDsymProcessing` to true. Unfortunately, Apple does not specify how long this time is. We recommend 1800 seconds (30 mins) as this is usually enough for the symbols are ready for download. You can increase this timeout if needed (`waitForDsymProcessingTimeout`).
|
36
31
|
|
37
|
-
|
38
|
-
|
39
|
-
> Notice that this timeout is only the maximum waiting time. If the symbol files are processed and are ready sooner, it will execute sooner and will not wait for the whole duration of the timeout.
|
32
|
+
> Notice that this timeout is only the **maximum** waiting time. If the symbol files are ready sooner, it will continue processing and will not wait for the whole duration of the timeout.
|
40
33
|
|
41
34
|
### Automatically downloading dSYMs and using AppFile for authentication
|
42
35
|
|
43
36
|
#### AppFile
|
44
|
-
|
45
37
|
```ruby
|
46
|
-
app_identifier("com.yourcompany.yourappID") #
|
47
|
-
apple_id("user@email.com")
|
38
|
+
app_identifier("com.yourcompany.yourappID") # bundle identifier of your app
|
39
|
+
apple_id("user@email.com")
|
48
40
|
```
|
49
41
|
|
50
42
|
#### Fastfile
|
51
|
-
|
52
43
|
```ruby
|
53
|
-
|
54
|
-
|
55
|
-
|
56
|
-
|
57
|
-
|
58
|
-
|
59
|
-
|
60
|
-
|
61
|
-
|
62
|
-
|
63
|
-
wait_for_dsym_processing: true,
|
64
|
-
wait_timeout: symbols_wait_timeout,
|
65
|
-
app_identifier: "<your application bundle id (CFBundleIdentifier)>",
|
66
|
-
version: version,
|
67
|
-
build_number: build
|
68
|
-
)
|
69
|
-
|
70
|
-
#Pass the dsyms to Dynatrace for processing
|
71
|
-
dynatrace_process_symbols(
|
72
|
-
symbolsfile: lane_context[SharedValues::DSYM_PATHS][0],
|
73
|
-
dtxDssClientPath:"<path>/DTXDssClient",
|
74
|
-
appId: "<your Dynatrace application ID>",
|
75
|
-
apitoken: "<your Dynatrace API token>",
|
76
|
-
os: "ios",
|
77
|
-
versionStr: build,
|
78
|
-
version: version,
|
79
|
-
server: "<your dynatrace environment URL>",
|
80
|
-
)
|
81
|
-
end
|
82
|
-
|
44
|
+
dynatrace_process_symbols(
|
45
|
+
appId: "<Dynatrace application ID>",
|
46
|
+
apitoken: "<Dynatrace API token>",
|
47
|
+
os: "ios",
|
48
|
+
bundleId: "<CFBundlebundleId (iOS) / package (Android)>",
|
49
|
+
versionStr: "<Build Number (CFBundleVersion)>",
|
50
|
+
version: "<App Version (CFBundleShortVersionString)>",
|
51
|
+
server: "<Dynatrace Environment URL>",
|
52
|
+
downloadDsyms: true
|
53
|
+
)
|
83
54
|
```
|
84
55
|
|
85
56
|
|
86
|
-
## If you are NOT using Bitcode, or if you have already downloaded your new symbols from
|
57
|
+
## If you are NOT using Bitcode, or if you have already downloaded your new symbols from App Store Connect manually.
|
87
58
|
|
88
59
|
### Supply all parameters locally
|
89
|
-
|
90
60
|
```ruby
|
91
61
|
dynatrace_process_symbols(
|
92
|
-
|
93
|
-
|
94
|
-
apitoken: "your DT API token",
|
62
|
+
appId: "<Dynatrace application ID>",
|
63
|
+
apitoken: "<Dynatrace API Token>",
|
95
64
|
os: "<ios> or <android>",
|
96
|
-
bundleId: "
|
97
|
-
|
98
|
-
|
99
|
-
|
100
|
-
symbolsfile: "<
|
101
|
-
|
102
|
-
debugMode: true)
|
103
|
-
|
65
|
+
bundleId: "<CFBundlebundleId (iOS) / package (Android)>",
|
66
|
+
versionStr: "<CFBundleShortVersionString (iOS) / versionName (Android)>",
|
67
|
+
version: "<CFBundleVersion (iOS) / versionCode (Android)>",
|
68
|
+
server: "<Dynatrace Environment URL>",
|
69
|
+
symbolsfile: "<Symbols File Path>"
|
70
|
+
)
|
104
71
|
```
|
105
72
|
|
106
73
|
## List of all Parameters
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
| os
|
115
|
-
| apitoken
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
74
|
+
| Key | Description | default value |
|
75
|
+
|------------------------------|-----------------------------------------------------------------------------------------------------------------------------------------------------------------------|----------------|
|
76
|
+
| action | *(iOS only)* Action to be performed by DTXDssClient (`upload` or `decode`). | `upload` |
|
77
|
+
| downloadDsyms | *(iOS only)* Download the dSYMs from App Store Connect. | `false` |
|
78
|
+
| waitForDsymProcessing | *(iOS only)* Wait for dSYM processing to be finished. | `true` |
|
79
|
+
| waitForDsymProcessingTimeout | *(iOS only)* Timeout in seconds to wait for the dSYMs be downloadable. | `1800` |
|
80
|
+
| username | *(iOS only)* The username/AppleID to use to download the dSYMs. Alternatively you can specify this in your AppFile as `apple_id`. | |
|
81
|
+
| os | The type of the symbol files, either `ios` or `android`. | |
|
82
|
+
| apitoken | Dynatrace API token with mobile symbolication permissions. | |
|
83
|
+
| dtxDssClientPath | **(DEPRECATED)** The path to your DTXDssClient. The DTXDssClient is downloaded and updated automatically, unless this key is set. | |
|
84
|
+
| appID | The application ID you get from your Dynatrace environment. | |
|
85
|
+
| bundleId | The CFBundlebundleId (iOS) / package (Android) of the application. Alternatively you can specify this in your AppFile as `app_identifier`. | |
|
86
|
+
| versionStr | The CFBundleShortVersionString (iOS) / versionName (Android) | |
|
87
|
+
| version | The CFBundleVersion (iOS) / versionCode (Android). Is also used for the dSYM download. | |
|
88
|
+
| symbolsfile | Path to the dSYM file to be processed. If downloadDsyms is set, this is only a fallback. | |
|
89
|
+
| server | The API endpoint for the Dynatrace environment (e.g. `https://environmentID.live.dynatrace.com` or `https://dynatrace-managed.com/e/environmentID`). | |
|
90
|
+
| debugMode | Enable debug logging. | false |
|
123
91
|
|
124
92
|
|
125
93
|
## Example
|
126
|
-
|
127
94
|
Try it by cloning the repo, running `fastlane install_plugins` and `bundle exec fastlane test`.
|
128
95
|
|
129
|
-
|
130
96
|
## Issues and Feedback
|
131
|
-
|
132
|
-
For any other issues and feedback about this plugin, please submit it to this repository or contact Dynatrace Support.
|
97
|
+
For any other issues and feedback about this plugin, please submit it to this repository or contact [Dynatrace Support](https://support.dynatrace.com).
|
133
98
|
|
134
99
|
## Troubleshooting
|
135
|
-
|
136
100
|
If you have trouble using plugins, check out the [Plugins Troubleshooting](https://docs.fastlane.tools/plugins/plugins-troubleshooting/) guide.
|
137
101
|
|
138
102
|
## Using _fastlane_ Plugins
|
139
|
-
|
140
103
|
For more information about how the `fastlane` plugin system works, check out the [Plugins documentation](https://docs.fastlane.tools/plugins/create-plugin/).
|
141
104
|
|
142
105
|
## About _fastlane_
|
143
|
-
|
144
106
|
_fastlane_ is the easiest way to automate beta deployments and releases for your iOS and Android apps. To learn more, check out [fastlane.tools](https://fastlane.tools).
|
@@ -1,4 +1,8 @@
|
|
1
1
|
require 'fastlane/action'
|
2
|
+
require 'net/http'
|
3
|
+
require 'open-uri'
|
4
|
+
require 'zip'
|
5
|
+
require "fileutils"
|
2
6
|
require_relative '../helper/dynatrace_helper'
|
3
7
|
|
4
8
|
module Fastlane
|
@@ -6,7 +10,6 @@ module Fastlane
|
|
6
10
|
class DynatraceProcessSymbolsAction < Action
|
7
11
|
|
8
12
|
def self.run(params)
|
9
|
-
# fastlane will take care of reading in the parameter and fetching the environment variable:
|
10
13
|
UI.message "DTXDssClientPath: #{params[:dtxDssClientPath]}"
|
11
14
|
UI.message "Parameter API Token: #{params[:apitoken]}"
|
12
15
|
UI.message "OS: #{params[:os]}"
|
@@ -16,242 +19,236 @@ module Fastlane
|
|
16
19
|
|
17
20
|
UI.message "Checking AppFile for possible AppID"
|
18
21
|
bundleId = CredentialsManager::AppfileConfig.try_fetch_value(:app_identifier)
|
19
|
-
if
|
22
|
+
if bundleId
|
20
23
|
UI.message "Using #{bundleId} from your AppFile"
|
21
24
|
else
|
22
25
|
bundleId = params[:bundleId]
|
23
26
|
UI.message "BundleID: #{bundleId}"
|
24
27
|
end
|
25
28
|
|
29
|
+
UI.message "Checking AppFile for possible username/AppleID"
|
30
|
+
username = CredentialsManager::AppfileConfig.try_fetch_value(:apple_id)
|
31
|
+
if username
|
32
|
+
UI.message "Using #{username} from your AppFile"
|
33
|
+
else
|
34
|
+
username = params[:username]
|
35
|
+
UI.message "Didn't find a username in AppFile, using passed username parameter: #{params[:username]}"
|
36
|
+
end
|
37
|
+
|
38
|
+
dtxDssClientPath = Helper::DynatraceHelper.get_dss_client(params)
|
26
39
|
|
27
40
|
dsym_paths = []
|
28
|
-
symbolFilesKey = "symbolsfile" #default to iOS
|
41
|
+
symbolFilesKey = "symbolsfile" # default to iOS
|
29
42
|
|
30
|
-
if
|
31
|
-
|
32
|
-
|
33
|
-
|
34
|
-
|
35
|
-
|
43
|
+
if params[:os] == "ios"
|
44
|
+
if params[:downloadDsyms] == true
|
45
|
+
UI.message "Downloading dSYMs from App Store Connect"
|
46
|
+
startTime = Time.now
|
47
|
+
|
48
|
+
# it takes a couple of minutes until the new build is available through the API
|
49
|
+
# -> retry until available
|
50
|
+
while params[:waitForDsymProcessing] and # wait is active
|
51
|
+
!lane_context[SharedValues::DSYM_PATHS] and # has dsym path
|
52
|
+
(Time.now - startTime) < params[:waitForDsymProcessingTimeout] # is in time
|
53
|
+
|
54
|
+
Actions::DownloadDsymsAction.run(wait_for_dsym_processing: params[:waitForDsymProcessing],
|
55
|
+
wait_timeout: (params[:waitForDsymProcessingTimeout] - (Time.now - startTime)).round(0), # remaining timeout
|
56
|
+
app_identifier: bundleId,
|
57
|
+
username: username,
|
58
|
+
version: params[:version],
|
59
|
+
build_number: params[:versionStr],
|
60
|
+
platform: :ios) # should be optional (Hint: it's not)
|
61
|
+
|
62
|
+
if !lane_context[SharedValues::DSYM_PATHS] and (Time.now - startTime) < params[:waitForDsymProcessingTimeout]
|
63
|
+
UI.message "Version #{params[:version]} (Build #{params[:versionStr]}) isn't listed yet, retrying in 60 seconds (timeout in #{(params[:waitForDsymProcessingTimeout] - (Time.now - startTime)).round(0)} seconds)."
|
64
|
+
sleep(60)
|
65
|
+
end
|
36
66
|
end
|
37
67
|
|
38
|
-
if (params[:
|
39
|
-
|
40
|
-
|
41
|
-
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
username: username,
|
52
|
-
version: version,
|
53
|
-
build_number: :versionStr,
|
54
|
-
)
|
55
|
-
dsym_paths += Actions.lane_context[SharedValues::DSYM_PATHS] if Actions.lane_context[SharedValues::DSYM_PATHS]
|
56
|
-
|
57
|
-
if dsym_paths.count > 0
|
58
|
-
UI.message("Downloaded the Dsyms from AppStore Connect. Paths #{dsym_paths}")
|
59
|
-
|
60
|
-
else
|
61
|
-
raise 'No dsyms found error'
|
62
|
-
end
|
63
|
-
end
|
64
|
-
|
65
|
-
rescue
|
66
|
-
UI.error("Couldn't download Dsyms. Checking if we have a local path")
|
68
|
+
if (Time.now - startTime) > params[:waitForDsymProcessingTimeout]
|
69
|
+
UI.user_error!("Timeout during dSYM download. Try increasing :waitForDsymProcessingTimeout.")
|
70
|
+
end
|
71
|
+
|
72
|
+
dsym_paths += Actions.lane_context[SharedValues::DSYM_PATHS] if Actions.lane_context[SharedValues::DSYM_PATHS]
|
73
|
+
|
74
|
+
if dsym_paths.count > 0
|
75
|
+
UI.message "Downloaded the dSYMs from App Store Connect. Paths: #{dsym_paths}"
|
76
|
+
else
|
77
|
+
raise 'No dSYM paths found!'
|
78
|
+
end
|
79
|
+
else
|
80
|
+
UI.error "dSYM download disabled, using local path (#{params[:symbolsfile]})"
|
67
81
|
dsym_paths << params[:symbolsfile] if params[:symbolsfile]
|
68
|
-
end
|
82
|
+
end
|
69
83
|
|
70
|
-
|
71
|
-
|
72
|
-
|
73
|
-
|
84
|
+
else # android
|
85
|
+
dsym_paths << params[:symbolsfile] if params[:symbolsfile]
|
86
|
+
symbolFilesKey = "file"
|
87
|
+
end
|
74
88
|
|
75
|
-
|
76
|
-
|
77
|
-
|
78
|
-
|
79
|
-
|
80
|
-
|
81
|
-
|
82
|
-
|
89
|
+
# check if we have dSYMs to proceed with
|
90
|
+
if dsym_paths.count == 0
|
91
|
+
UI.message "Symbol file path: #{params[:symbolsfile]}"
|
92
|
+
dsym_paths = params[:symbolsfile]
|
93
|
+
symbolFilesCommandSnippet = "#{symbolFilesKey}=\"#{dsym_paths}\""
|
94
|
+
else
|
95
|
+
symbolFilesCommandSnippet = "#{symbolFilesKey}=\"#{dsym_paths[0]}\""
|
96
|
+
end
|
83
97
|
|
84
|
-
#
|
98
|
+
# start constructing the command that will trigger the DTXDssClient
|
85
99
|
command = []
|
86
|
-
command << "#{
|
100
|
+
command << "#{dtxDssClientPath}"
|
87
101
|
command << "-#{params[:action]}" #"-upload"
|
88
102
|
command << "appid=\"#{params[:appId]}\""
|
89
103
|
command << "apitoken=\"#{params[:apitoken]}\""
|
90
104
|
command << "os=#{params[:os]}"
|
91
105
|
command << "bundleId=\"#{bundleId}\""
|
92
|
-
|
93
|
-
command << "versionStr=\"#{version}\""
|
94
|
-
else
|
95
|
-
command << "versionStr=\"#{params[:versionStr]}\""
|
96
|
-
end
|
106
|
+
command << "versionStr=\"#{params[:versionStr]}\""
|
97
107
|
command << "version=\"#{params[:version]}\""
|
98
108
|
command << symbolFilesCommandSnippet
|
99
|
-
command << "server=\"#{params
|
109
|
+
command << "server=\"#{Helper::DynatraceHelper.get_server_base_url(params)}\""
|
100
110
|
command << "DTXLogLevel=ALL -verbose" if params[:debugMode] == true
|
101
|
-
command << "forced=1" #
|
111
|
+
command << "forced=1" # if the file already exists
|
102
112
|
|
103
113
|
# Create the full shell command to trigger the DTXDssClient
|
104
114
|
shell_command = command.join(' ')
|
105
115
|
|
116
|
+
UI.message "dSYM path: #{dsym_paths[0]}"
|
117
|
+
UI.message "#{shell_command}"
|
106
118
|
|
107
|
-
|
108
|
-
|
109
|
-
|
110
|
-
|
111
|
-
|
119
|
+
sh("#{shell_command}", error_callback: ->(result) {
|
120
|
+
# ShAction doesn't return any reference to the return value -> parse it from the output
|
121
|
+
result_groups = result.match /(?:ERROR: Execution failed, rc=)(-?\d*)(?:\sreason=)(.*)/
|
122
|
+
if result_groups and result_groups.length() >= 2
|
123
|
+
if result_groups[1] == "413"
|
124
|
+
UI.user_error!("DTXDssClient: #{result_groups[2]} See https://www.dynatrace.com/support/help/shortlink/mobile-symbolication#manage-the-uploaded-symbol-files for more information.")
|
125
|
+
else
|
126
|
+
UI.user_error!("DTXDssClient: #{result_groups[2]}")
|
127
|
+
end
|
128
|
+
else
|
129
|
+
UI.user_error!("DTXDssClient finished with errors.")
|
130
|
+
end
|
131
|
+
})
|
112
132
|
|
113
|
-
UI.message
|
133
|
+
UI.message "Cleaning build artifacts"
|
114
134
|
Fastlane::Actions::CleanBuildArtifactsAction.run(exclude_pattern: nil)
|
115
|
-
|
116
|
-
end #end the run functions
|
135
|
+
end
|
117
136
|
|
118
137
|
def self.description
|
119
|
-
"This action processes and uploads your symbol files to Dynatrace"
|
138
|
+
"This action processes and uploads your symbol files to Dynatrace."
|
120
139
|
end
|
121
140
|
|
122
141
|
def self.details
|
123
|
-
"This action allows you to process and upload symbol files to Dynatrace.
|
142
|
+
"This action allows you to process and upload symbol files to Dynatrace. If you use Bitcode you can also use it to download the latest dSYM files from App Store Connect."
|
124
143
|
end
|
125
144
|
|
126
145
|
def self.available_options
|
127
|
-
# Define all options your action supports.
|
128
146
|
[
|
129
147
|
FastlaneCore::ConfigItem.new(key: :action,
|
130
148
|
env_name: "FL_UPLOAD_TO_DYNATRACE_ACTION",
|
131
|
-
description: "
|
149
|
+
description: "(iOS only) Action to be performed by DTXDssClient (\"upload\" or \"decode\")",
|
132
150
|
default_value: "upload",
|
133
151
|
is_string: true,
|
134
152
|
verify_block: proc do |value|
|
135
|
-
UI.user_error!("Action needs to either be upload or decode") unless (value and value == "upload" or value == "decode")
|
136
|
-
# UI.user_error!("Couldn't find file at path '#{value}'") unless File.exist?(value)
|
153
|
+
UI.user_error!("Action needs to either be \"upload\" or \"decode\"") unless (value and value == "upload" or value == "decode")
|
137
154
|
end),
|
138
155
|
|
139
156
|
FastlaneCore::ConfigItem.new(key: :downloadDsyms,
|
140
|
-
env_name: "FL_UPLOAD_TO_DYNATRACE_DOWNLOAD_DSYMS",
|
157
|
+
env_name: "FL_UPLOAD_TO_DYNATRACE_DOWNLOAD_DSYMS",
|
141
158
|
default_value: false,
|
142
159
|
is_string: false,
|
143
|
-
description: "
|
144
|
-
|
160
|
+
description: "(iOS only) Download the dSYMs from App Store Connect"),
|
161
|
+
|
162
|
+
FastlaneCore::ConfigItem.new(key: :waitForDsymProcessing,
|
163
|
+
env_name: "FL_UPLOAD_TO_DYNATRACE_DOWNLOAD_DSYMS_WAIT_PROCESSING",
|
164
|
+
default_value: true,
|
165
|
+
is_string: false,
|
166
|
+
description: "(iOS only) Wait for dSYM processing to be finished"),
|
145
167
|
|
146
|
-
|
147
|
-
env_name: "FL_UPLOAD_TO_DYNATRACE_DOWNLOAD_DSYMS_WAIT_TIMEOUT",
|
148
|
-
default_value:
|
168
|
+
FastlaneCore::ConfigItem.new(key: :waitForDsymProcessingTimeout,
|
169
|
+
env_name: "FL_UPLOAD_TO_DYNATRACE_DOWNLOAD_DSYMS_WAIT_TIMEOUT",
|
170
|
+
default_value: 1800,
|
149
171
|
is_string: false,
|
150
|
-
description: "
|
151
|
-
),
|
172
|
+
description: "(iOS only) Timeout in seconds to wait for the dSYMs be downloadable"),
|
152
173
|
|
153
174
|
FastlaneCore::ConfigItem.new(key: :username,
|
154
|
-
env_name: "FL_UPLOAD_TO_DYNATRACE_DOWNLOAD_DSYMS_USERNAME",
|
155
|
-
description: "The username
|
156
|
-
|
157
|
-
|
158
|
-
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
|
164
|
-
|
165
|
-
end),
|
175
|
+
env_name: "FL_UPLOAD_TO_DYNATRACE_DOWNLOAD_DSYMS_USERNAME",
|
176
|
+
description: "(iOS only) The username/AppleID to use to download the dSYMs"),
|
177
|
+
|
178
|
+
FastlaneCore::ConfigItem.new(key: :os,
|
179
|
+
env_name: "FL_UPLOAD_TO_DYNATRACE_OS",
|
180
|
+
description: "The type of the symbol files, either \"ios\" or \"android\"",
|
181
|
+
sensitive: false,
|
182
|
+
optional: false,
|
183
|
+
verify_block: proc do |value|
|
184
|
+
UI.user_error!("Please specify the type of the symbol files. Possible values are \"ios\" or \"android\".") unless (value and not value.empty? and (value == "ios" || value =="android"))
|
185
|
+
end),
|
166
186
|
|
167
187
|
FastlaneCore::ConfigItem.new(key: :apitoken,
|
168
|
-
env_name: "FL_UPLOAD_TO_DYNATRACE_apitoken",
|
169
|
-
description: "
|
188
|
+
env_name: "FL_UPLOAD_TO_DYNATRACE_apitoken",
|
189
|
+
description: "Dynatrace API token with mobile symbolication permissions",
|
170
190
|
verify_block: proc do |value|
|
171
|
-
UI.user_error!("No API token for
|
172
|
-
# UI.user_error!("Couldn't find file at path '#{value}'") unless File.exist?(value)
|
191
|
+
UI.user_error!("No Dynatrade API token for specified, pass using `apitoken: 'token'`") unless (value and not value.empty?)
|
173
192
|
end),
|
174
193
|
|
175
194
|
FastlaneCore::ConfigItem.new(key: :dtxDssClientPath,
|
176
195
|
env_name: "FL_UPLOAD_TO_DYNATRACE_DTXDssClientPath",
|
177
|
-
description: "The path to your DTXDssClient",
|
178
|
-
|
196
|
+
description: "(DEPRECATED) The path to your DTXDssClient. The DTXDssClient is downloaded and updated automatically, unless this key is set",
|
197
|
+
optional: true),
|
198
|
+
|
199
|
+
FastlaneCore::ConfigItem.new(key: :appId,
|
200
|
+
env_name: "FL_UPLOAD_TO_DYNATRACE_APP_ID",
|
201
|
+
description: "The app ID you get from your Dynatrace environment",
|
179
202
|
verify_block: proc do |value|
|
180
|
-
UI.user_error!("
|
181
|
-
|
182
|
-
# default_value: false) # the default value if the user didn't provide one
|
183
|
-
end),
|
184
|
-
|
185
|
-
FastlaneCore::ConfigItem.new(key: :appId,
|
186
|
-
env_name: "FL_UPLOAD_TO_DYNATRACE_APP_ID",
|
187
|
-
description: "The app ID you get from your Dynatrace WebUI",
|
188
|
-
verify_block: proc do |value|
|
189
|
-
UI.user_error!("Please provide the appID for your app. Pass using `appId: 'appId'`") unless (value and not value.empty?)
|
190
|
-
# is_string: true # true: verifies the input is a string, false: every kind of value
|
191
|
-
# default_value: false) # the default value if the user didn't provide one
|
192
|
-
end),
|
203
|
+
UI.user_error!("Please provide the appID for your application. Pass using `appId: 'appId'`") unless (value and not value.empty?)
|
204
|
+
end),
|
193
205
|
|
194
206
|
FastlaneCore::ConfigItem.new(key: :bundleId,
|
195
207
|
env_name: "FL_UPLOAD_TO_DYNATRACE_BUNDLE_ID",
|
196
|
-
description: "The CFBundlebundleId (iOS) / package (Android) of the
|
208
|
+
description: "The CFBundlebundleId (iOS) / package (Android) of the application",
|
197
209
|
verify_block: proc do |value|
|
198
210
|
UI.user_error!("Please provide the BundleID for your app. Pass using `bundleId: 'bundleId'`") unless (value and not value.empty?)
|
199
|
-
|
200
|
-
# default_value: false) # the default value if the user didn't provide one
|
201
|
-
end),
|
211
|
+
end),
|
202
212
|
|
203
213
|
FastlaneCore::ConfigItem.new(key: :versionStr,
|
204
214
|
env_name: "FL_UPLOAD_TO_DYNATRACE_VERSION_STRING",
|
205
215
|
description: "The CFBundleShortVersionString (iOS) / versionName (Android)",
|
206
216
|
verify_block: proc do |value|
|
207
217
|
UI.user_error!("Please provide the CFBundleShortVersionString for your app. Pass using `versionStr: 'versionStr'`") unless (value and not value.empty?)
|
208
|
-
|
209
|
-
|
210
|
-
|
211
|
-
|
212
|
-
|
213
|
-
|
214
|
-
|
215
|
-
|
216
|
-
UI.user_error!("Please provide the version for your app. Pass using `version: 'version'`") unless (value and not value.empty?)
|
217
|
-
# is_string: true # true: verifies the input is a string, false: every kind of value
|
218
|
-
# default_value: false) # the default value if the user didn't provide one
|
219
|
-
end),
|
218
|
+
end),
|
219
|
+
|
220
|
+
FastlaneCore::ConfigItem.new(key: :version,
|
221
|
+
env_name: "FL_UPLOAD_TO_DYNATRACE_VERSION",
|
222
|
+
description: "The CFBundleVersion (iOS) / versionCode (Android). Is also used for the dSYM download",
|
223
|
+
verify_block: proc do |value|
|
224
|
+
UI.user_error!("Please provide the version for your app. Pass using `version: 'version'`") unless (value and not value.empty?)
|
225
|
+
end),
|
220
226
|
|
221
227
|
FastlaneCore::ConfigItem.new(key: :symbolsfile,
|
222
228
|
env_name: "FL_UPLOAD_TO_DYNATRACE_SYM_FILE_PATH",
|
223
|
-
description: "
|
229
|
+
description: "Path to the dSYM file to be processed. Is only used when downloadDsyms is not set",
|
230
|
+
verify_block: proc do |value|
|
231
|
+
UI.user_error!("Please provide a value for the symbol files. Pass using `symbolsfile: 'symbolsfile'`") unless (value and not value.empty?)
|
232
|
+
end),
|
233
|
+
|
234
|
+
FastlaneCore::ConfigItem.new(key: :server,
|
235
|
+
env_name: "FL_UPLOAD_TO_DYNATRACE_SERVER_URL",
|
236
|
+
description: "The API endpoint for the Dynatrace environment (e.g. https://environmentID.live.dynatrace.com or https://dynatrace-managed.com/e/environmentID)",
|
224
237
|
verify_block: proc do |value|
|
225
|
-
UI.user_error!("Please provide
|
226
|
-
|
227
|
-
# default_value: false) # the default value if the user didn't provide one
|
228
|
-
end),
|
229
|
-
|
230
|
-
FastlaneCore::ConfigItem.new(key: :server,
|
231
|
-
env_name: "FL_UPLOAD_TO_DYNATRACE_SERVER_URL",
|
232
|
-
description: "The API endpoint for the Dynatrace environment. For example https://<environmentID.live.dynatrace.com/api/config/v1",
|
233
|
-
verify_block: proc do |value|
|
234
|
-
UI.user_error!("Please provide your environment API endpoint. Pass using `server: 'server'`") unless (value and not value.empty?)
|
235
|
-
# is_string: true # true: verifies the input is a string, false: every kind of value
|
236
|
-
# default_value: false) # the default value if the user didn't provide one
|
237
|
-
end),
|
238
|
+
UI.user_error!("Please provide your environment API endpoint. Pass using `server: 'server'`") unless (value and not value.empty?)
|
239
|
+
end),
|
238
240
|
|
239
241
|
FastlaneCore::ConfigItem.new(key: :debugMode,
|
240
242
|
env_name: "FL_UPLOAD_TO_DYNATRACE_DEBUG_MODE",
|
241
|
-
description: "
|
243
|
+
description: "Enable debug logging",
|
244
|
+
default_value: false,
|
242
245
|
is_string: false,
|
243
|
-
optional: true
|
244
|
-
)
|
246
|
+
optional: true)
|
245
247
|
]
|
246
248
|
end
|
247
249
|
|
248
|
-
def self.return_value
|
249
|
-
# If your method provides a return value, you can describe here what it does
|
250
|
-
end
|
251
|
-
|
252
250
|
def self.authors
|
253
|
-
|
254
|
-
["MANassar/@MohamedANassar"]
|
251
|
+
["MANassar/@MohamedANassar", "cynicer"]
|
255
252
|
end
|
256
253
|
|
257
254
|
def self.is_supported?(platform)
|
@@ -5,11 +5,70 @@ module Fastlane
|
|
5
5
|
|
6
6
|
module Helper
|
7
7
|
class DynatraceHelper
|
8
|
-
|
9
|
-
|
10
|
-
|
11
|
-
|
12
|
-
|
8
|
+
def self.get_dss_client(params)
|
9
|
+
dynatraceDir = "dynatrace"
|
10
|
+
versionFile = "version"
|
11
|
+
dtxDssClientBin = "DTXDssClient"
|
12
|
+
dtxDssClientPath = "#{dynatraceDir}/#{dtxDssClientBin}"
|
13
|
+
|
14
|
+
if (params.all_keys.include? :dtxDssClientPath and not params[:dtxDssClientPath].nil?)
|
15
|
+
UI.message "DEPRECATION WARNING: DTXDssClientPath doesn't need to be specified anymore, the DTXDssClient is downloaded and updated automatically."
|
16
|
+
dtxDssClientPath = params[:dtxDssClientPath]
|
17
|
+
else
|
18
|
+
# get latest version info
|
19
|
+
clientUri = URI("#{self.get_server_base_url(params)}/api/config/v1/symfiles/dtxdss-download?Api-Token=#{params[:apitoken]}")
|
20
|
+
response = Net::HTTP.get_response(clientUri)
|
21
|
+
|
22
|
+
if not response.kind_of? Net::HTTPSuccess
|
23
|
+
base_error = "Couldn't update DTXDssClient (invalid response: #{response.message} (#{response.code})) for URL: #{clientUri})"
|
24
|
+
if File.exists?("#{dynatraceDir}/#{dtxDssClientBin}")
|
25
|
+
UI.important base_error
|
26
|
+
UI.important "Using cached DTXDssClient: #{dynatraceDir}/#{dtxDssClientBin}"
|
27
|
+
return dtxDssClientPath
|
28
|
+
else
|
29
|
+
UI.user_error! base_error
|
30
|
+
end
|
31
|
+
end
|
32
|
+
|
33
|
+
remoteClientUrl = JSON.parse(response.body)["dssClientUrl"]
|
34
|
+
UI.message "Remote DSS client: #{remoteClientUrl}"
|
35
|
+
|
36
|
+
# check local state
|
37
|
+
if (!File.directory?(dynatraceDir))
|
38
|
+
Dir.mkdir(dynatraceDir)
|
39
|
+
end
|
40
|
+
|
41
|
+
if (!File.exists?("#{dynatraceDir}/#{versionFile}") or
|
42
|
+
!File.exists?("#{dynatraceDir}/#{dtxDssClientBin}") or
|
43
|
+
File.read("#{dynatraceDir}/#{versionFile}") != remoteClientUrl)
|
44
|
+
# update local state
|
45
|
+
UI.message "Found a different remote DTXDssClient client. Updating local version."
|
46
|
+
File.delete("#{dynatraceDir}/#{versionFile}") if File.exist?("#{dynatraceDir}/#{versionFile}")
|
47
|
+
File.delete("#{dynatraceDir}/#{dtxDssClientBin}") if File.exist?("#{dynatraceDir}/#{dtxDssClientBin}")
|
48
|
+
|
49
|
+
File.write("#{dynatraceDir}/#{versionFile}", remoteClientUrl)
|
50
|
+
|
51
|
+
# get client from served archive
|
52
|
+
open(remoteClientUrl) do |zipped|
|
53
|
+
Zip::InputStream.open(zipped) do |unzipped|
|
54
|
+
entry = unzipped.get_next_entry
|
55
|
+
if (entry.name == dtxDssClientBin)
|
56
|
+
IO.copy_stream(entry.get_input_stream, "#{dynatraceDir}/#{dtxDssClientBin}")
|
57
|
+
FileUtils.chmod("+x", "#{dynatraceDir}/#{dtxDssClientBin}")
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
61
|
+
end
|
62
|
+
end
|
63
|
+
return dtxDssClientPath
|
64
|
+
end
|
65
|
+
|
66
|
+
def self.get_server_base_url(params)
|
67
|
+
if params[:server][-1] == '/'
|
68
|
+
return params[:server][0..-2]
|
69
|
+
else
|
70
|
+
return params[:server]
|
71
|
+
end
|
13
72
|
end
|
14
73
|
end
|
15
74
|
end
|
metadata
CHANGED
@@ -1,14 +1,14 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: fastlane-plugin-dynatrace
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version: 0.
|
4
|
+
version: 1.0.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Dynatrace LLC
|
8
|
-
autorequire:
|
8
|
+
autorequire:
|
9
9
|
bindir: bin
|
10
10
|
cert_chain: []
|
11
|
-
date: 2020-
|
11
|
+
date: 2020-11-23 00:00:00.000000000 Z
|
12
12
|
dependencies:
|
13
13
|
- !ruby/object:Gem::Dependency
|
14
14
|
name: pry
|
@@ -136,7 +136,7 @@ dependencies:
|
|
136
136
|
- - ">="
|
137
137
|
- !ruby/object:Gem::Version
|
138
138
|
version: 2.142.0
|
139
|
-
description:
|
139
|
+
description:
|
140
140
|
email: mobile.agent@dynatrace.com
|
141
141
|
executables: []
|
142
142
|
extensions: []
|
@@ -152,7 +152,7 @@ homepage: https://github.com/Dynatrace/fastlane-plugin-dynatrace
|
|
152
152
|
licenses:
|
153
153
|
- MIT
|
154
154
|
metadata: {}
|
155
|
-
post_install_message:
|
155
|
+
post_install_message:
|
156
156
|
rdoc_options: []
|
157
157
|
require_paths:
|
158
158
|
- lib
|
@@ -167,8 +167,8 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
167
167
|
- !ruby/object:Gem::Version
|
168
168
|
version: '0'
|
169
169
|
requirements: []
|
170
|
-
rubygems_version: 3.1.
|
171
|
-
signing_key:
|
170
|
+
rubygems_version: 3.1.4
|
171
|
+
signing_key:
|
172
172
|
specification_version: 4
|
173
173
|
summary: This action processes and uploads your symbol files to Dynatrace
|
174
174
|
test_files: []
|