@sentry/react-native 7.2.0 → 7.4.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/RNSentry.podspec +1 -1
- package/android/build.gradle +1 -1
- package/android/libs/replay-stubs.jar +0 -0
- package/android/replay-stubs/build.gradle +1 -1
- package/android/src/main/java/io/sentry/react/RNSentryVersion.java +1 -1
- package/dist/js/client.d.ts.map +1 -1
- package/dist/js/client.js +4 -7
- package/dist/js/client.js.map +1 -1
- package/dist/js/integrations/default.d.ts.map +1 -1
- package/dist/js/integrations/default.js +2 -1
- package/dist/js/integrations/default.js.map +1 -1
- package/dist/js/options.d.ts +13 -0
- package/dist/js/options.d.ts.map +1 -1
- package/dist/js/options.js.map +1 -1
- package/dist/js/playground/modal.d.ts.map +1 -1
- package/dist/js/playground/modal.js +2 -2
- package/dist/js/playground/modal.js.map +1 -1
- package/dist/js/replay/mobilereplay.d.ts.map +1 -1
- package/dist/js/replay/mobilereplay.js +10 -7
- package/dist/js/replay/mobilereplay.js.map +1 -1
- package/dist/js/sdk.d.ts.map +1 -1
- package/dist/js/sdk.js +1 -0
- package/dist/js/sdk.js.map +1 -1
- package/dist/js/tools/metroconfig.d.ts +1 -1
- package/dist/js/tools/metroconfig.d.ts.map +1 -1
- package/dist/js/tools/metroconfig.js.map +1 -1
- package/dist/js/tools/vendor/metro/utils.js +1 -1
- package/dist/js/tools/vendor/metro/utils.js.map +1 -1
- package/dist/js/touchevents.js.map +1 -1
- package/dist/js/tracing/reactnativetracing.js.map +1 -1
- package/dist/js/tracing/reactnavigation.js.map +1 -1
- package/dist/js/version.d.ts +1 -1
- package/dist/js/version.js +1 -1
- package/dist/js/version.js.map +1 -1
- package/dist/js/wrapper.d.ts.map +1 -1
- package/dist/js/wrapper.js +1 -0
- package/dist/js/wrapper.js.map +1 -1
- package/ios/RNSentry.mm +9 -1
- package/ios/RNSentryExperimentalOptions.h +9 -0
- package/ios/RNSentryExperimentalOptions.m +9 -0
- package/ios/RNSentryReplay.h +5 -1
- package/ios/RNSentryReplay.mm +10 -6
- package/ios/RNSentryVersion.m +1 -1
- package/package.json +11 -11
- package/plugin/build/withSentryAndroidGradlePlugin.d.ts +1 -1
- package/plugin/build/withSentryAndroidGradlePlugin.js +1 -1
- package/scripts/expo-upload-sourcemaps.js +1 -1
- package/scripts/sentry-xcode.sh +2 -1
- package/sentry.gradle +274 -276
- package/ts3.8/dist/js/options.d.ts +13 -0
- package/ts3.8/dist/js/version.d.ts +1 -1
package/sentry.gradle
CHANGED
|
@@ -15,13 +15,269 @@ project.ext.shouldSentryAutoUpload = { ->
|
|
|
15
15
|
return shouldSentryAutoUploadGeneral() && shouldSentryAutoUploadNative()
|
|
16
16
|
}
|
|
17
17
|
|
|
18
|
+
interface InjectedExecOps {
|
|
19
|
+
@Inject //@javax.inject.Inject
|
|
20
|
+
ExecOperations getExecOps()
|
|
21
|
+
}
|
|
22
|
+
|
|
18
23
|
def config = project.hasProperty("sentryCli") ? project.sentryCli : [];
|
|
19
24
|
|
|
25
|
+
plugins.withId('com.android.application') {
|
|
26
|
+
def androidComponents = extensions.getByName("androidComponents")
|
|
27
|
+
|
|
28
|
+
androidComponents.onVariants(androidComponents.selector().all()) { v ->
|
|
29
|
+
if (!v.name.toLowerCase().contains("debug")) {
|
|
30
|
+
// separately we then hook into the bundle task of react native to inject
|
|
31
|
+
// sourcemap generation parameters. In case for whatever reason no release
|
|
32
|
+
// was found for the asset folder we just bail.
|
|
33
|
+
def bundleTasks = tasks.findAll { task -> (task.name.startsWith("createBundle") || task.name.startsWith("bundle")) && task.name.endsWith("JsAndAssets") && !task.name.contains("Debug") && task.enabled }
|
|
34
|
+
bundleTasks.each { bundleTask ->
|
|
35
|
+
def shouldCleanUp
|
|
36
|
+
def sourcemapOutput
|
|
37
|
+
def bundleOutput
|
|
38
|
+
def packagerSourcemapOutput
|
|
39
|
+
def bundleCommand
|
|
40
|
+
def props = bundleTask.getProperties()
|
|
41
|
+
def reactRoot = props.get("workingDir")
|
|
42
|
+
if (reactRoot == null) {
|
|
43
|
+
reactRoot = props.get("root").get() // RN 0.71 and above
|
|
44
|
+
}
|
|
45
|
+
def modulesOutput = "$reactRoot/android/app/src/main/assets/modules.json"
|
|
46
|
+
def modulesTask = null
|
|
47
|
+
|
|
48
|
+
(shouldCleanUp, bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand) = forceSourceMapOutputFromBundleTask(bundleTask)
|
|
49
|
+
|
|
50
|
+
// Lets leave this here if we need to debug
|
|
51
|
+
// println bundleTask.properties
|
|
52
|
+
// .sort{it.key}
|
|
53
|
+
// .collect{it}
|
|
54
|
+
// .findAll{!['class', 'active'].contains(it.key)}
|
|
55
|
+
// .join('\n')
|
|
56
|
+
|
|
57
|
+
def currentVariants = extractCurrentVariants(bundleTask, v)
|
|
58
|
+
if (currentVariants == null) return
|
|
59
|
+
|
|
60
|
+
def previousCliTask = null
|
|
61
|
+
def applicationVariant = null
|
|
62
|
+
|
|
63
|
+
def nameCleanup = "${bundleTask.name}_SentryUploadCleanUp"
|
|
64
|
+
def nameModulesCleanup = "${bundleTask.name}_SentryCollectModulesCleanUp"
|
|
65
|
+
// Upload the source map several times if necessary: once for each release and versionCode.
|
|
66
|
+
currentVariants.each { key, currentVariant ->
|
|
67
|
+
def variant = currentVariant[0]
|
|
68
|
+
def releaseName = currentVariant[1]
|
|
69
|
+
def versionCode = currentVariant[2]
|
|
70
|
+
applicationVariant = currentVariant[3]
|
|
71
|
+
|
|
72
|
+
try {
|
|
73
|
+
if (versionCode instanceof String) {
|
|
74
|
+
versionCode = Integer.parseInt(versionCode)
|
|
75
|
+
versionCode = Math.abs(versionCode)
|
|
76
|
+
}
|
|
77
|
+
} catch (NumberFormatException e) {
|
|
78
|
+
project.logger.info("versionCode: '$versionCode' isn't an Integer, using the plain value.")
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
// The Sentry server distinguishes source maps by release (`--release` in the command
|
|
82
|
+
// below) and distribution identifier (`--dist` below). Give the task a unique name
|
|
83
|
+
// based on where we're uploading to.
|
|
84
|
+
def nameCliTask = "${bundleTask.name}_SentryUpload_${releaseName}_${versionCode}"
|
|
85
|
+
def nameModulesTask = "${bundleTask.name}_SentryCollectModules_${releaseName}_${versionCode}"
|
|
86
|
+
|
|
87
|
+
// If several outputs have the same releaseName and versionCode, we'd do the exact same
|
|
88
|
+
// upload for each of them. No need to repeat.
|
|
89
|
+
try { tasks.named(nameCliTask); return } catch (Exception e) {}
|
|
90
|
+
|
|
91
|
+
/** Upload source map file to the sentry server via CLI call. */
|
|
92
|
+
def cliTask = tasks.register(nameCliTask) {
|
|
93
|
+
onlyIf { shouldSentryAutoUploadGeneral() }
|
|
94
|
+
description = "upload debug symbols to sentry"
|
|
95
|
+
group = 'sentry.io'
|
|
96
|
+
|
|
97
|
+
def extraArgs = []
|
|
98
|
+
|
|
99
|
+
def sentryPackage = resolveSentryReactNativeSDKPath(reactRoot)
|
|
100
|
+
def copyDebugIdScript = config.copyDebugIdScript
|
|
101
|
+
? file(config.copyDebugIdScript).getAbsolutePath()
|
|
102
|
+
: "$sentryPackage/scripts/copy-debugid.js"
|
|
103
|
+
def hasSourceMapDebugIdScript = config.hasSourceMapDebugIdScript
|
|
104
|
+
? file(config.hasSourceMapDebugIdScript).getAbsolutePath()
|
|
105
|
+
: "$sentryPackage/scripts/has-sourcemap-debugid.js"
|
|
106
|
+
|
|
107
|
+
def injected = project.objects.newInstance(InjectedExecOps)
|
|
108
|
+
doFirst {
|
|
109
|
+
// Copy Debug ID from packager source map to Hermes composed source map
|
|
110
|
+
injected.execOps.exec {
|
|
111
|
+
def args = ["node",
|
|
112
|
+
copyDebugIdScript,
|
|
113
|
+
packagerSourcemapOutput,
|
|
114
|
+
sourcemapOutput]
|
|
115
|
+
def osCompatibilityCopyCommand = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c'] : []
|
|
116
|
+
commandLine(*osCompatibilityCopyCommand, *args)
|
|
117
|
+
}
|
|
118
|
+
|
|
119
|
+
// Add release and dist for backward compatibility if no Debug ID detected in output soruce map
|
|
120
|
+
def process = ["node", hasSourceMapDebugIdScript, sourcemapOutput].execute(null, new File("$reactRoot"))
|
|
121
|
+
def exitValue = process.waitFor()
|
|
122
|
+
project.logger.lifecycle("Check generated source map for Debug ID: ${process.text}")
|
|
123
|
+
|
|
124
|
+
project.logger.lifecycle("Sentry Source Maps upload will include the release name and dist.")
|
|
125
|
+
extraArgs.addAll([
|
|
126
|
+
"--release", releaseName,
|
|
127
|
+
"--dist", versionCode
|
|
128
|
+
])
|
|
129
|
+
}
|
|
130
|
+
|
|
131
|
+
doLast {
|
|
132
|
+
injected.execOps.exec {
|
|
133
|
+
workingDir reactRoot
|
|
134
|
+
|
|
135
|
+
def propertiesFile = config.sentryProperties
|
|
136
|
+
? config.sentryProperties
|
|
137
|
+
: "$reactRoot/android/sentry.properties"
|
|
138
|
+
|
|
139
|
+
if (config.flavorAware) {
|
|
140
|
+
propertiesFile = "$reactRoot/android/sentry-${variant}.properties"
|
|
141
|
+
project.logger.info("For $variant using: $propertiesFile")
|
|
142
|
+
} else {
|
|
143
|
+
environment("SENTRY_PROPERTIES", propertiesFile)
|
|
144
|
+
}
|
|
145
|
+
|
|
146
|
+
Properties sentryProps = new Properties()
|
|
147
|
+
try {
|
|
148
|
+
sentryProps.load(new FileInputStream(propertiesFile))
|
|
149
|
+
} catch (FileNotFoundException e) {
|
|
150
|
+
project.logger.info("file not found '$propertiesFile' for '$variant'")
|
|
151
|
+
}
|
|
152
|
+
|
|
153
|
+
def cliPackage = resolveSentryCliPackagePath(reactRoot)
|
|
154
|
+
def cliExecutable = sentryProps.get("cli.executable", "$cliPackage/bin/sentry-cli")
|
|
155
|
+
|
|
156
|
+
// fix path separator for Windows
|
|
157
|
+
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
|
158
|
+
cliExecutable = cliExecutable.replaceAll("/", "\\\\")
|
|
159
|
+
}
|
|
160
|
+
|
|
161
|
+
//
|
|
162
|
+
// based on:
|
|
163
|
+
// https://github.com/getsentry/sentry-cli/blob/master/src/commands/react_native_gradle.rs
|
|
164
|
+
//
|
|
165
|
+
def args = [cliExecutable]
|
|
166
|
+
|
|
167
|
+
args.addAll(!config.logLevel ? [] : [
|
|
168
|
+
"--log-level", config.logLevel // control verbosity of the output
|
|
169
|
+
])
|
|
170
|
+
args.addAll(!config.flavorAware ? [] : [
|
|
171
|
+
"--url", sentryProps.get("defaults.url"),
|
|
172
|
+
"--auth-token", sentryProps.get("auth.token") ?: System.getenv("SENTRY_AUTH_TOKEN")
|
|
173
|
+
])
|
|
174
|
+
args.addAll(["react-native", "gradle",
|
|
175
|
+
"--bundle", bundleOutput, // The path to a bundle that should be uploaded.
|
|
176
|
+
"--sourcemap", sourcemapOutput // The path to a sourcemap that should be uploaded.
|
|
177
|
+
])
|
|
178
|
+
args.addAll(!config.flavorAware ? [] : [
|
|
179
|
+
"--org", sentryProps.get("defaults.org"),
|
|
180
|
+
"--project", sentryProps.get("defaults.project")
|
|
181
|
+
])
|
|
182
|
+
|
|
183
|
+
args.addAll(extraArgs)
|
|
184
|
+
|
|
185
|
+
project.logger.lifecycle("Sentry-CLI arguments: ${args}")
|
|
186
|
+
def osCompatibility = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c', 'node'] : []
|
|
187
|
+
if (!System.getenv('SENTRY_DOTENV_PATH') && file("$reactRoot/.env.sentry-build-plugin").exists()) {
|
|
188
|
+
environment('SENTRY_DOTENV_PATH', "$reactRoot/.env.sentry-build-plugin")
|
|
189
|
+
}
|
|
190
|
+
commandLine(*osCompatibility, *args)
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
|
|
194
|
+
enabled true
|
|
195
|
+
}
|
|
196
|
+
|
|
197
|
+
modulesTask = tasks.register(nameModulesTask, Exec) {
|
|
198
|
+
description = "collect javascript modules from bundle source map"
|
|
199
|
+
group = 'sentry.io'
|
|
200
|
+
|
|
201
|
+
workingDir reactRoot
|
|
202
|
+
|
|
203
|
+
def sentryPackage = resolveSentryReactNativeSDKPath(reactRoot)
|
|
204
|
+
|
|
205
|
+
def collectModulesScript = config.collectModulesScript
|
|
206
|
+
? file(config.collectModulesScript).getAbsolutePath()
|
|
207
|
+
: "$sentryPackage/dist/js/tools/collectModules.js"
|
|
208
|
+
def modulesPaths = config.modulesPaths
|
|
209
|
+
? config.modulesPaths.join(',')
|
|
210
|
+
: "$reactRoot/node_modules"
|
|
211
|
+
def args = ["node",
|
|
212
|
+
collectModulesScript,
|
|
213
|
+
sourcemapOutput,
|
|
214
|
+
modulesOutput,
|
|
215
|
+
modulesPaths
|
|
216
|
+
]
|
|
217
|
+
|
|
218
|
+
if ((new File(collectModulesScript)).exists()) {
|
|
219
|
+
project.logger.info("Sentry-CollectModules arguments: ${args}")
|
|
220
|
+
commandLine(*args)
|
|
221
|
+
|
|
222
|
+
def skip = config.skipCollectModules
|
|
223
|
+
? config.skipCollectModules == true
|
|
224
|
+
: false
|
|
225
|
+
enabled !skip
|
|
226
|
+
} else {
|
|
227
|
+
project.logger.info("collectModulesScript not found: $collectModulesScript")
|
|
228
|
+
enabled false
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
// chain the upload tasks so they run sequentially in order to run
|
|
233
|
+
// the cliCleanUpTask after the final upload task is run
|
|
234
|
+
if (previousCliTask != null) {
|
|
235
|
+
previousCliTask.configure { finalizedBy cliTask }
|
|
236
|
+
} else {
|
|
237
|
+
bundleTask.configure { finalizedBy cliTask }
|
|
238
|
+
}
|
|
239
|
+
previousCliTask = cliTask
|
|
240
|
+
cliTask.configure { finalizedBy modulesTask }
|
|
241
|
+
}
|
|
242
|
+
|
|
243
|
+
def modulesCleanUpTask = tasks.register(nameModulesCleanup, Delete) {
|
|
244
|
+
description = "clean up collected modules generated file"
|
|
245
|
+
group = 'sentry.io'
|
|
246
|
+
|
|
247
|
+
delete modulesOutput
|
|
248
|
+
}
|
|
249
|
+
|
|
250
|
+
/** Delete sourcemap files */
|
|
251
|
+
def cliCleanUpTask = tasks.register(nameCleanup, Delete) {
|
|
252
|
+
description = "clean up extra sourcemap"
|
|
253
|
+
group = 'sentry.io'
|
|
254
|
+
|
|
255
|
+
delete sourcemapOutput
|
|
256
|
+
delete "$buildDir/intermediates/assets/release/index.android.bundle.map"
|
|
257
|
+
// react native default bundle dir
|
|
258
|
+
}
|
|
259
|
+
|
|
260
|
+
// register clean task extension
|
|
261
|
+
cliCleanUpTask.configure { onlyIf { shouldCleanUp } }
|
|
262
|
+
// due to chaining the last value of previousCliTask will be the final
|
|
263
|
+
// upload task, after which the cleanup can be done
|
|
264
|
+
previousCliTask.configure { finalizedBy cliCleanUpTask }
|
|
265
|
+
|
|
266
|
+
def packageTasks = tasks.matching {
|
|
267
|
+
task -> ("package${applicationVariant}".equalsIgnoreCase(task.name) || "package${applicationVariant}Bundle".equalsIgnoreCase(task.name)) && task.enabled
|
|
268
|
+
}
|
|
269
|
+
packageTasks.configureEach { packageTask ->
|
|
270
|
+
packageTask.dependsOn modulesTask
|
|
271
|
+
packageTask.finalizedBy modulesCleanUpTask
|
|
272
|
+
}
|
|
273
|
+
}
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
}
|
|
277
|
+
|
|
20
278
|
// gradle.projectsEvaluated doesn't work with --configure-on-demand
|
|
21
279
|
// the task are create too late and not executed
|
|
22
280
|
project.afterEvaluate {
|
|
23
|
-
def releases = extractReleasesInfo()
|
|
24
|
-
|
|
25
281
|
if (config.flavorAware && config.sentryProperties) {
|
|
26
282
|
throw new GradleException("Incompatible sentry configuration. " +
|
|
27
283
|
"You cannot use both `flavorAware` and `sentryProperties`. " +
|
|
@@ -44,253 +300,6 @@ project.afterEvaluate {
|
|
|
44
300
|
println "* Flavor aware sentry properties *"
|
|
45
301
|
println "**********************************"
|
|
46
302
|
}
|
|
47
|
-
|
|
48
|
-
// separately we then hook into the bundle task of react native to inject
|
|
49
|
-
// sourcemap generation parameters. In case for whatever reason no release
|
|
50
|
-
// was found for the asset folder we just bail.
|
|
51
|
-
def bundleTasks = tasks.findAll { task -> (task.name.startsWith("createBundle") || task.name.startsWith("bundle")) && task.name.endsWith("JsAndAssets") && !task.name.contains("Debug") && task.enabled }
|
|
52
|
-
bundleTasks.each { bundleTask ->
|
|
53
|
-
def shouldCleanUp
|
|
54
|
-
def sourcemapOutput
|
|
55
|
-
def bundleOutput
|
|
56
|
-
def packagerSourcemapOutput
|
|
57
|
-
def bundleCommand
|
|
58
|
-
def props = bundleTask.getProperties()
|
|
59
|
-
def reactRoot = props.get("workingDir")
|
|
60
|
-
if (reactRoot == null) {
|
|
61
|
-
reactRoot = props.get("root").get() // RN 0.71 and above
|
|
62
|
-
}
|
|
63
|
-
def modulesOutput = "$reactRoot/android/app/src/main/assets/modules.json"
|
|
64
|
-
def modulesTask = null
|
|
65
|
-
|
|
66
|
-
(shouldCleanUp, bundleOutput, sourcemapOutput, packagerSourcemapOutput, bundleCommand) = forceSourceMapOutputFromBundleTask(bundleTask)
|
|
67
|
-
|
|
68
|
-
// Lets leave this here if we need to debug
|
|
69
|
-
// println bundleTask.properties
|
|
70
|
-
// .sort{it.key}
|
|
71
|
-
// .collect{it}
|
|
72
|
-
// .findAll{!['class', 'active'].contains(it.key)}
|
|
73
|
-
// .join('\n')
|
|
74
|
-
|
|
75
|
-
def currentVariants = extractCurrentVariants(bundleTask, releases)
|
|
76
|
-
if (currentVariants == null) return
|
|
77
|
-
|
|
78
|
-
def previousCliTask = null
|
|
79
|
-
def applicationVariant = null
|
|
80
|
-
|
|
81
|
-
def nameCleanup = "${bundleTask.name}_SentryUploadCleanUp"
|
|
82
|
-
def nameModulesCleanup = "${bundleTask.name}_SentryCollectModulesCleanUp"
|
|
83
|
-
// Upload the source map several times if necessary: once for each release and versionCode.
|
|
84
|
-
currentVariants.each { key, currentVariant ->
|
|
85
|
-
def variant = currentVariant[0]
|
|
86
|
-
def releaseName = currentVariant[1]
|
|
87
|
-
def versionCode = currentVariant[2]
|
|
88
|
-
applicationVariant = currentVariant[3]
|
|
89
|
-
|
|
90
|
-
try {
|
|
91
|
-
if (versionCode instanceof String) {
|
|
92
|
-
versionCode = Integer.parseInt(versionCode)
|
|
93
|
-
versionCode = Math.abs(versionCode)
|
|
94
|
-
}
|
|
95
|
-
} catch (NumberFormatException e) {
|
|
96
|
-
project.logger.info("versionCode: '$versionCode' isn't an Integer, using the plain value.")
|
|
97
|
-
}
|
|
98
|
-
|
|
99
|
-
// The Sentry server distinguishes source maps by release (`--release` in the command
|
|
100
|
-
// below) and distribution identifier (`--dist` below). Give the task a unique name
|
|
101
|
-
// based on where we're uploading to.
|
|
102
|
-
def nameCliTask = "${bundleTask.name}_SentryUpload_${releaseName}_${versionCode}"
|
|
103
|
-
def nameModulesTask = "${bundleTask.name}_SentryCollectModules_${releaseName}_${versionCode}"
|
|
104
|
-
|
|
105
|
-
// If several outputs have the same releaseName and versionCode, we'd do the exact same
|
|
106
|
-
// upload for each of them. No need to repeat.
|
|
107
|
-
try { tasks.named(nameCliTask); return } catch (Exception e) {}
|
|
108
|
-
|
|
109
|
-
/** Upload source map file to the sentry server via CLI call. */
|
|
110
|
-
def cliTask = tasks.create(nameCliTask) {
|
|
111
|
-
onlyIf { shouldSentryAutoUploadGeneral() }
|
|
112
|
-
description = "upload debug symbols to sentry"
|
|
113
|
-
group = 'sentry.io'
|
|
114
|
-
|
|
115
|
-
def extraArgs = []
|
|
116
|
-
|
|
117
|
-
def sentryPackage = resolveSentryReactNativeSDKPath(reactRoot)
|
|
118
|
-
def copyDebugIdScript = config.copyDebugIdScript
|
|
119
|
-
? file(config.copyDebugIdScript).getAbsolutePath()
|
|
120
|
-
: "$sentryPackage/scripts/copy-debugid.js"
|
|
121
|
-
def hasSourceMapDebugIdScript = config.hasSourceMapDebugIdScript
|
|
122
|
-
? file(config.hasSourceMapDebugIdScript).getAbsolutePath()
|
|
123
|
-
: "$sentryPackage/scripts/has-sourcemap-debugid.js"
|
|
124
|
-
|
|
125
|
-
doFirst {
|
|
126
|
-
// Copy Debug ID from packager source map to Hermes composed source map
|
|
127
|
-
exec {
|
|
128
|
-
def args = ["node",
|
|
129
|
-
copyDebugIdScript,
|
|
130
|
-
packagerSourcemapOutput,
|
|
131
|
-
sourcemapOutput]
|
|
132
|
-
def osCompatibilityCopyCommand = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c'] : []
|
|
133
|
-
commandLine(*osCompatibilityCopyCommand, *args)
|
|
134
|
-
}
|
|
135
|
-
|
|
136
|
-
// Add release and dist for backward compatibility if no Debug ID detected in output soruce map
|
|
137
|
-
def process = ["node", hasSourceMapDebugIdScript, sourcemapOutput].execute(null, new File("$reactRoot"))
|
|
138
|
-
def exitValue = process.waitFor()
|
|
139
|
-
project.logger.lifecycle("Check generated source map for Debug ID: ${process.text}")
|
|
140
|
-
|
|
141
|
-
project.logger.lifecycle("Sentry Source Maps upload will include the release name and dist.")
|
|
142
|
-
extraArgs.addAll([
|
|
143
|
-
"--release", releaseName,
|
|
144
|
-
"--dist", versionCode
|
|
145
|
-
])
|
|
146
|
-
}
|
|
147
|
-
|
|
148
|
-
doLast {
|
|
149
|
-
exec {
|
|
150
|
-
workingDir reactRoot
|
|
151
|
-
|
|
152
|
-
def propertiesFile = config.sentryProperties
|
|
153
|
-
? config.sentryProperties
|
|
154
|
-
: "$reactRoot/android/sentry.properties"
|
|
155
|
-
|
|
156
|
-
if (config.flavorAware) {
|
|
157
|
-
propertiesFile = "$reactRoot/android/sentry-${variant}.properties"
|
|
158
|
-
project.logger.info("For $variant using: $propertiesFile")
|
|
159
|
-
} else {
|
|
160
|
-
environment("SENTRY_PROPERTIES", propertiesFile)
|
|
161
|
-
}
|
|
162
|
-
|
|
163
|
-
Properties sentryProps = new Properties()
|
|
164
|
-
try {
|
|
165
|
-
sentryProps.load(new FileInputStream(propertiesFile))
|
|
166
|
-
} catch (FileNotFoundException e) {
|
|
167
|
-
project.logger.info("file not found '$propertiesFile' for '$variant'")
|
|
168
|
-
}
|
|
169
|
-
|
|
170
|
-
def cliPackage = resolveSentryCliPackagePath(reactRoot)
|
|
171
|
-
def cliExecutable = sentryProps.get("cli.executable", "$cliPackage/bin/sentry-cli")
|
|
172
|
-
|
|
173
|
-
// fix path separator for Windows
|
|
174
|
-
if (Os.isFamily(Os.FAMILY_WINDOWS)) {
|
|
175
|
-
cliExecutable = cliExecutable.replaceAll("/", "\\\\")
|
|
176
|
-
}
|
|
177
|
-
|
|
178
|
-
//
|
|
179
|
-
// based on:
|
|
180
|
-
// https://github.com/getsentry/sentry-cli/blob/master/src/commands/react_native_gradle.rs
|
|
181
|
-
//
|
|
182
|
-
def args = [cliExecutable]
|
|
183
|
-
|
|
184
|
-
args.addAll(!config.logLevel ? [] : [
|
|
185
|
-
"--log-level", config.logLevel // control verbosity of the output
|
|
186
|
-
])
|
|
187
|
-
args.addAll(!config.flavorAware ? [] : [
|
|
188
|
-
"--url", sentryProps.get("defaults.url"),
|
|
189
|
-
"--auth-token", sentryProps.get("auth.token") ?: System.getenv("SENTRY_AUTH_TOKEN")
|
|
190
|
-
])
|
|
191
|
-
args.addAll(["react-native", "gradle",
|
|
192
|
-
"--bundle", bundleOutput, // The path to a bundle that should be uploaded.
|
|
193
|
-
"--sourcemap", sourcemapOutput // The path to a sourcemap that should be uploaded.
|
|
194
|
-
])
|
|
195
|
-
args.addAll(!config.flavorAware ? [] : [
|
|
196
|
-
"--org", sentryProps.get("defaults.org"),
|
|
197
|
-
"--project", sentryProps.get("defaults.project")
|
|
198
|
-
])
|
|
199
|
-
|
|
200
|
-
args.addAll(extraArgs)
|
|
201
|
-
|
|
202
|
-
project.logger.lifecycle("Sentry-CLI arguments: ${args}")
|
|
203
|
-
def osCompatibility = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c', 'node'] : []
|
|
204
|
-
if (!System.getenv('SENTRY_DOTENV_PATH') && file("$reactRoot/.env.sentry-build-plugin").exists()) {
|
|
205
|
-
environment('SENTRY_DOTENV_PATH', "$reactRoot/.env.sentry-build-plugin")
|
|
206
|
-
}
|
|
207
|
-
commandLine(*osCompatibility, *args)
|
|
208
|
-
}
|
|
209
|
-
}
|
|
210
|
-
|
|
211
|
-
enabled true
|
|
212
|
-
}
|
|
213
|
-
|
|
214
|
-
modulesTask = tasks.create(nameModulesTask, Exec) {
|
|
215
|
-
description = "collect javascript modules from bundle source map"
|
|
216
|
-
group = 'sentry.io'
|
|
217
|
-
|
|
218
|
-
workingDir reactRoot
|
|
219
|
-
|
|
220
|
-
def sentryPackage = resolveSentryReactNativeSDKPath(reactRoot)
|
|
221
|
-
|
|
222
|
-
def collectModulesScript = config.collectModulesScript
|
|
223
|
-
? file(config.collectModulesScript).getAbsolutePath()
|
|
224
|
-
: "$sentryPackage/dist/js/tools/collectModules.js"
|
|
225
|
-
def modulesPaths = config.modulesPaths
|
|
226
|
-
? config.modulesPaths.join(',')
|
|
227
|
-
: "$reactRoot/node_modules"
|
|
228
|
-
def args = ["node",
|
|
229
|
-
collectModulesScript,
|
|
230
|
-
sourcemapOutput,
|
|
231
|
-
modulesOutput,
|
|
232
|
-
modulesPaths
|
|
233
|
-
]
|
|
234
|
-
|
|
235
|
-
if ((new File(collectModulesScript)).exists()) {
|
|
236
|
-
project.logger.info("Sentry-CollectModules arguments: ${args}")
|
|
237
|
-
commandLine(*args)
|
|
238
|
-
|
|
239
|
-
def skip = config.skipCollectModules
|
|
240
|
-
? config.skipCollectModules == true
|
|
241
|
-
: false
|
|
242
|
-
enabled !skip
|
|
243
|
-
} else {
|
|
244
|
-
project.logger.info("collectModulesScript not found: $collectModulesScript")
|
|
245
|
-
enabled false
|
|
246
|
-
}
|
|
247
|
-
}
|
|
248
|
-
|
|
249
|
-
// chain the upload tasks so they run sequentially in order to run
|
|
250
|
-
// the cliCleanUpTask after the final upload task is run
|
|
251
|
-
if (previousCliTask != null) {
|
|
252
|
-
previousCliTask.finalizedBy cliTask
|
|
253
|
-
} else {
|
|
254
|
-
bundleTask.finalizedBy cliTask
|
|
255
|
-
}
|
|
256
|
-
previousCliTask = cliTask
|
|
257
|
-
cliTask.finalizedBy modulesTask
|
|
258
|
-
}
|
|
259
|
-
|
|
260
|
-
def modulesCleanUpTask = tasks.create(name: nameModulesCleanup, type: Delete) {
|
|
261
|
-
description = "clean up collected modules generated file"
|
|
262
|
-
group = 'sentry.io'
|
|
263
|
-
|
|
264
|
-
delete modulesOutput
|
|
265
|
-
}
|
|
266
|
-
|
|
267
|
-
def packageTasks = tasks.findAll {
|
|
268
|
-
task -> (
|
|
269
|
-
"package${applicationVariant}".equalsIgnoreCase(task.name)
|
|
270
|
-
|| "package${applicationVariant}Bundle".equalsIgnoreCase(task.name)
|
|
271
|
-
) && task.enabled
|
|
272
|
-
}
|
|
273
|
-
packageTasks.each { packageTask ->
|
|
274
|
-
packageTask.dependsOn modulesTask
|
|
275
|
-
packageTask.finalizedBy modulesCleanUpTask
|
|
276
|
-
}
|
|
277
|
-
|
|
278
|
-
/** Delete sourcemap files */
|
|
279
|
-
def cliCleanUpTask = tasks.create(name: nameCleanup, type: Delete) {
|
|
280
|
-
description = "clean up extra sourcemap"
|
|
281
|
-
group = 'sentry.io'
|
|
282
|
-
|
|
283
|
-
delete sourcemapOutput
|
|
284
|
-
delete "$buildDir/intermediates/assets/release/index.android.bundle.map"
|
|
285
|
-
// react native default bundle dir
|
|
286
|
-
}
|
|
287
|
-
|
|
288
|
-
// register clean task extension
|
|
289
|
-
cliCleanUpTask.onlyIf { shouldCleanUp }
|
|
290
|
-
// due to chaining the last value of previousCliTask will be the final
|
|
291
|
-
// upload task, after which the cleanup can be done
|
|
292
|
-
previousCliTask.finalizedBy cliCleanUpTask
|
|
293
|
-
}
|
|
294
303
|
}
|
|
295
304
|
|
|
296
305
|
def resolveSentryReactNativeSDKPath(reactRoot) {
|
|
@@ -327,29 +336,6 @@ def resolveSentryCliPackagePath(reactRoot) {
|
|
|
327
336
|
return cliPackage
|
|
328
337
|
}
|
|
329
338
|
|
|
330
|
-
/** Compose lookup map of build variants - to - outputs. */
|
|
331
|
-
def extractReleasesInfo() {
|
|
332
|
-
def releases = [:]
|
|
333
|
-
|
|
334
|
-
android.applicationVariants.each { variant ->
|
|
335
|
-
|
|
336
|
-
variant.outputs.each { output ->
|
|
337
|
-
def defaultVersionCode = output.getVersionCode()
|
|
338
|
-
def versionCode = System.getenv("SENTRY_DIST") ?: defaultVersionCode
|
|
339
|
-
def defaultReleaseName = "${variant.getApplicationId()}@${variant.getVersionName()}+${versionCode}"
|
|
340
|
-
def releaseName = System.getenv("SENTRY_RELEASE") ?: defaultReleaseName
|
|
341
|
-
def variantName = variant.getName()
|
|
342
|
-
def outputName = output.getName()
|
|
343
|
-
if (releases[variantName] == null) {
|
|
344
|
-
releases[variantName] = [:]
|
|
345
|
-
}
|
|
346
|
-
releases[variantName][outputName] = [outputName, releaseName, versionCode, variantName]
|
|
347
|
-
}
|
|
348
|
-
}
|
|
349
|
-
|
|
350
|
-
return releases
|
|
351
|
-
}
|
|
352
|
-
|
|
353
339
|
/** Extract from arguments collection bundle and sourcemap files output names. */
|
|
354
340
|
static extractBundleTaskArgumentsLegacy(cmdArgs, Project project) {
|
|
355
341
|
def bundleOutput = null
|
|
@@ -461,7 +447,7 @@ def forceSourceMapOutputFromBundleTask(bundleTask) {
|
|
|
461
447
|
}
|
|
462
448
|
|
|
463
449
|
/** compose array with one item - current build flavor name */
|
|
464
|
-
static extractCurrentVariants(bundleTask,
|
|
450
|
+
static extractCurrentVariants(bundleTask, variant) {
|
|
465
451
|
// examples: bundleLocalReleaseJsAndAssets, createBundleYellowDebugJsAndAssets
|
|
466
452
|
def pattern = Pattern.compile("(?:create)?(?:B|b)undle([A-Z][A-Za-z0-9_]+)JsAndAssets")
|
|
467
453
|
|
|
@@ -474,9 +460,21 @@ static extractCurrentVariants(bundleTask, releases) {
|
|
|
474
460
|
}
|
|
475
461
|
|
|
476
462
|
def currentVariants = null
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
463
|
+
if (variant.name.equalsIgnoreCase(currentRelease)) {
|
|
464
|
+
currentVariants = [:]
|
|
465
|
+
def variantName = variant.name
|
|
466
|
+
variant.outputs.each { output ->
|
|
467
|
+
def defaultVersionCode = output.versionCode.getOrElse(0)
|
|
468
|
+
def versionCode = System.getenv('SENTRY_DIST') ?: defaultVersionCode
|
|
469
|
+
def appId = variant.applicationId.get()
|
|
470
|
+
def versionName = output.versionName.getOrElse('') // may be empty if not set
|
|
471
|
+
def defaultReleaseName = "${appId}@${versionName}+${versionCode}"
|
|
472
|
+
def releaseName = System.getenv('SENTRY_RELEASE') ?: defaultReleaseName
|
|
473
|
+
|
|
474
|
+
def outputName = output.baseName
|
|
475
|
+
|
|
476
|
+
if (currentVariants[outputName] == null) currentVariants[outputName] = []
|
|
477
|
+
currentVariants[outputName] = [outputName, releaseName, versionCode, variantName]
|
|
480
478
|
}
|
|
481
479
|
}
|
|
482
480
|
|
|
@@ -249,6 +249,19 @@ export interface BaseReactNativeOptions {
|
|
|
249
249
|
* @deprecated This option will be removed in the next major version. Use `beforeSend` instead.
|
|
250
250
|
*/
|
|
251
251
|
useThreadsForMessageStack?: boolean;
|
|
252
|
+
/**
|
|
253
|
+
* If set to `true`, the SDK propagates the W3C `traceparent` header to any outgoing requests,
|
|
254
|
+
* in addition to the `sentry-trace` and `baggage` headers. Use the {@link CoreOptions.tracePropagationTargets}
|
|
255
|
+
* option to control to which outgoing requests the header will be attached.
|
|
256
|
+
*
|
|
257
|
+
* **Important:** If you set this option to `true`, make sure that you configured your servers'
|
|
258
|
+
* CORS settings to allow the `traceparent` header. Otherwise, requests might get blocked.
|
|
259
|
+
*
|
|
260
|
+
* @see https://www.w3.org/TR/trace-context/
|
|
261
|
+
*
|
|
262
|
+
* @default false
|
|
263
|
+
*/
|
|
264
|
+
propagateTraceparent?: boolean;
|
|
252
265
|
}
|
|
253
266
|
export type SentryReplayQuality = 'low' | 'medium' | 'high';
|
|
254
267
|
export interface ReactNativeTransportOptions extends BrowserTransportOptions {
|