Skip to content

Commit

Permalink
Merge pull request #485 from bugsnag/release/v7.4.0
Browse files Browse the repository at this point in the history
Release v7.4.0
  • Loading branch information
lemnik authored Nov 10, 2022
2 parents 3055331 + 794eda2 commit 2184f1c
Show file tree
Hide file tree
Showing 33 changed files with 917 additions and 625 deletions.
12 changes: 12 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,15 @@
## 7.4.0 (2022-11-10)

### Enhancements

* Support using objcopy instead of objdump to extract native symbols (when supported by the current NDK).
[#484](https://github.com/bugsnag/bugsnag-android-gradle-plugin/pull/484)

### Bug Fixes

* Fix FileAlreadyExistsException errors when building ReactNative projects with Hermes
[#482](https://github.com/bugsnag/bugsnag-android-gradle-plugin/pull/482)

## 7.3.1 (2022-10-05)

* Fixed a bug where using ndkBuild generated empty some mapping files which could not be uploaded
Expand Down
14 changes: 8 additions & 6 deletions detekt-baseline.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,24 @@
<CurrentIssues>
<ID>ComplexCondition:AndroidManifestParser.kt$AndroidManifestParser$apiKey == null || "" == apiKey || versionCode == null || buildUuid == null || versionName == null || applicationId == null</ID>
<ID>ComplexCondition:BugsnagPlugin.kt$BugsnagPlugin$!jvmMinificationEnabled &amp;&amp; !ndkEnabled &amp;&amp; !unityEnabled &amp;&amp; !reactNativeEnabled</ID>
<ID>LongParameterList:BugsnagGenerateNdkSoMappingTask.kt$BugsnagGenerateNdkSoMappingTask.Companion$( project: Project, variant: BaseVariant, output: ApkVariantOutput, objdumpPaths: Provider&lt;Map&lt;String, String>>, searchPaths: List&lt;File>, soMappingOutputPath: String )</ID>
<ID>LongParameterList:BugsnagGenerateNdkSoMappingTask.kt$BugsnagGenerateNdkSoMappingTask.Companion$( project: Project, variant: BaseVariant, output: ApkVariantOutput, ndk: NdkToolchain, searchPaths: List&lt;File>, soMappingOutputPath: String )</ID>
<ID>LongParameterList:BugsnagUploadSoSymTask.kt$BugsnagUploadSoSymTask.Companion$( project: Project, variant: BaseVariantOutput, ndkToolchain: NdkToolchain, uploadType: UploadType, generateTaskProvider: TaskProvider&lt;out AbstractSoMappingTask>, httpClientHelperProvider: Provider&lt;out BugsnagHttpClientHelper>, ndkUploadClientProvider: Provider&lt;out UploadRequestClient>, )</ID>
<ID>MagicNumber:BugsnagPluginExtension.kt$BugsnagPluginExtension$60000</ID>
<ID>MagicNumber:BugsnagReleasesTask.kt$BugsnagReleasesTask$200</ID>
<ID>MagicNumber:MappingFileProvider.kt$9</ID>
<ID>ReturnCount:BugsnagPlugin.kt$BugsnagPlugin$ @Suppress("SENSELESS_COMPARISON") internal fun isUnityLibraryUploadEnabled( bugsnag: BugsnagPluginExtension, android: BaseExtension ): Boolean</ID>
<ID>MaxLineLength:NdkToolchain.kt$NdkToolchain.Companion$/* * SdkComponents.ndkDirectory * https://developer.android.com/reference/tools/gradle-api/7.2/com/android/build/api/dsl/SdkComponents#ndkDirectory() * sometimes fails to resolve when ndkPath is not defined (Cannot query the value of this property because it has * no value available.). This means that even `map` and `isPresent` will break. * * So we also fall back use the old BaseExtension if it appears broken */</ID>
<ID>ReturnCount:BugsnagGenerateUnitySoMappingTask.kt$BugsnagGenerateUnitySoMappingTask.Companion$ @Suppress("SENSELESS_COMPARISON") internal fun isUnityLibraryUploadEnabled( bugsnag: BugsnagPluginExtension, android: BaseExtension ): Boolean</ID>
<ID>ReturnCount:BugsnagPlugin.kt$BugsnagPlugin$ private fun registerUploadSourceMapTask( project: Project, variant: BaseVariant, output: BaseVariantOutput, bugsnag: BugsnagPluginExtension, manifestInfoProvider: Provider&lt;RegularFile> ): TaskProvider&lt;out BugsnagUploadJsSourceMapTask>?</ID>
<ID>ReturnCount:ManifestUuidTaskV2Compat.kt$internal fun createManifestUpdateTask( bugsnag: BugsnagPluginExtension, project: Project, variantName: String, variantOutput: VariantOutput ): TaskProvider&lt;BugsnagManifestUuidTask>?</ID>
<ID>ReturnCount:SharedObjectMappingFileFactory.kt$SharedObjectMappingFileFactory$ fun generateSoMappingFile(project: Project, params: Params): File?</ID>
<ID>SpreadOperator:DexguardCompat.kt$(buildDir, *path, variant.dirName, outputDir, "mapping.txt")</ID>
<ID>SwallowedException:NdkToolchain.kt$NdkToolchain.Companion$catch (e: Exception) { null }</ID>
<ID>SwallowedException:NdkToolchain.kt$NdkToolchain.Companion$catch (e: Exception) { return@provider extensions.getByType(BaseExtension::class.java).ndkDirectory.absoluteFile }</ID>
<ID>TooGenericExceptionCaught:AbstractSoMappingTask.kt$AbstractSoMappingTask$e: Exception</ID>
<ID>TooGenericExceptionCaught:BugsnagHttpClientHelper.kt$exc: Throwable</ID>
<ID>TooGenericExceptionCaught:BugsnagMultiPartUploadRequest.kt$BugsnagMultiPartUploadRequest$exc: Throwable</ID>
<ID>TooGenericExceptionCaught:BugsnagReleasesTask.kt$BugsnagReleasesTask$exc: Throwable</ID>
<ID>TooGenericExceptionCaught:MappingFileProvider.kt$exc: Throwable</ID>
<ID>TooGenericExceptionCaught:SharedObjectMappingFileFactory.kt$SharedObjectMappingFileFactory$e: Exception</ID>
<ID>TooGenericExceptionCaught:SharedObjectMappingFileFactory.kt$SharedObjectMappingFileFactory$ex: Throwable</ID>
<ID>TooGenericExceptionCaught:NdkToolchain.kt$NdkToolchain.Companion$e: Exception</ID>
<ID>TooManyFunctions:BugsnagPlugin.kt$BugsnagPlugin : Plugin</ID>
<ID>UnusedPrivateMember:BugsnagPlugin.kt$BugsnagPlugin$private fun BaseVariantOutput.findVersionCode(): Int</ID>
</CurrentIssues>
</SmellBaseline>
6 changes: 6 additions & 0 deletions features/fixtures/config/ndk/objcopy.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dependencies {
implementation 'com.bugsnag:bugsnag-android:5.26.0'
}

android.ndkVersion = "23.0.7599858"
bugsnag.useLegacyNdkSymbolUpload = false
6 changes: 6 additions & 0 deletions features/fixtures/config/ndk/old_sdk_upload_failure.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
dependencies {
implementation 'com.bugsnag:bugsnag-android:5.9.4'
}

android.ndkVersion = "23.0.7599858"
bugsnag.useLegacyNdkSymbolUpload = true
3 changes: 3 additions & 0 deletions features/fixtures/config/ndk/standard.gradle
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
dependencies {
implementation 'com.bugsnag:bugsnag-android:5.9.4'
}
7 changes: 3 additions & 4 deletions features/fixtures/ndkapp/app/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -66,10 +66,6 @@ android {
}
}

dependencies {
implementation 'com.bugsnag:bugsnag-android:5.9.4'
}

bugsnag {
uploadNdkMappings = true
endpoint = "http://localhost:9339/builds"
Expand All @@ -95,3 +91,6 @@ bugsnag {
]
}
}

def ndkConfig = System.env.BUGSNAG_NDK_CONFIG ?: "standard"
apply from: "../../config/ndk/${ndkConfig}.gradle"
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:exported="true"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
Expand Down
21 changes: 16 additions & 5 deletions features/fixtures/rn-monorepo/abc/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ buildscript {
ext {
buildToolsVersion = "30.0.2"
minSdkVersion = 21
compileSdkVersion = 30
targetSdkVersion = 30
compileSdkVersion = 31
targetSdkVersion = 31
}
repositories {
mavenCentral()
Expand All @@ -26,9 +26,20 @@ allprojects {
repositories {
mavenCentral()
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../../node_modules/react-native/android")
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
exclusiveContent {
// We get React Native's Android binaries exclusively through npm,
// from a local Maven repo inside node_modules/react-native/.
// (The use of exclusiveContent prevents looking elsewhere like Maven Central
// and potentially getting a wrong version.)
filter {
includeGroup "com.facebook.react"
}
forRepository {
maven {
url("$rootDir/../../node_modules/react-native/android")
}
}
}
maven {
// Android JSC is installed from npm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:exported="true"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
Expand Down
21 changes: 16 additions & 5 deletions features/fixtures/rn-monorepo/xyz/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ buildscript {
ext {
buildToolsVersion = "29.0.2"
minSdkVersion = 16
compileSdkVersion = 29
targetSdkVersion = 29
compileSdkVersion = 31
targetSdkVersion = 31
}
repositories {
google()
Expand All @@ -21,9 +21,20 @@ buildscript {
allprojects {
repositories {
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
exclusiveContent {
// We get React Native's Android binaries exclusively through npm,
// from a local Maven repo inside node_modules/react-native/.
// (The use of exclusiveContent prevents looking elsewhere like Maven Central
// and potentially getting a wrong version.)
filter {
includeGroup "com.facebook.react"
}
forRepository {
maven {
url("$rootDir/../node_modules/react-native/android")
}
}
}
maven {
// Android JSC is installed from npm
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@
<activity
android:name=".MainActivity"
android:label="@string/app_name"
android:exported="true"
android:configChanges="keyboard|keyboardHidden|orientation|screenSize|uiMode"
android:launchMode="singleTask"
android:windowSoftInputMode="adjustResize">
Expand Down
21 changes: 16 additions & 5 deletions features/fixtures/rn065/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,8 @@ buildscript {
ext {
buildToolsVersion = "30.0.2"
minSdkVersion = 21
compileSdkVersion = 30
targetSdkVersion = 30
compileSdkVersion = 31
targetSdkVersion = 31
ndkVersion = "20.1.5948944"
}
repositories {
Expand All @@ -29,9 +29,20 @@ allprojects {
repositories {
mavenCentral()
mavenLocal()
maven {
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
url("$rootDir/../node_modules/react-native/android")
// All of React Native (JS, Obj-C sources, Android binaries) is installed from npm
exclusiveContent {
// We get React Native's Android binaries exclusively through npm,
// from a local Maven repo inside node_modules/react-native/.
// (The use of exclusiveContent prevents looking elsewhere like Maven Central
// and potentially getting a wrong version.)
filter {
includeGroup "com.facebook.react"
}
forRepository {
maven {
url("$rootDir/../node_modules/react-native/android")
}
}
}
maven {
// Android JSC is installed from npm
Expand Down
24 changes: 24 additions & 0 deletions features/ndk_app.feature
Original file line number Diff line number Diff line change
Expand Up @@ -110,3 +110,27 @@ Scenario: Mapping files uploaded for custom sharedObjectPaths
And 1 requests are valid for the android mapping API and match the following:
| appId |
| com.bugsnag.android.ndkapp |

Scenario: Mapping fails when using obcopy and an incompatible SDK
When I build the NDK app using the "old_sdk_upload_failure" config
And I wait for 3 seconds
Then I should receive no requests

Scenario: objcopy is used to produce symbols when configured
When I build the NDK app using the "objcopy" config
And I wait to receive 6 builds

Then 1 requests are valid for the build API and match the following:
| appVersionCode | appVersion | buildTool |
| 1 | 1.0 | gradle-android |

And 4 requests are valid for the android so symbol mapping API and match the following:
| projectRoot | sharedObjectName |
| /\S+/ | libnative-lib.so |
| /\S+/ | libnative-lib.so |
| /\S+/ | libnative-lib.so |
| /\S+/ | libnative-lib.so |

And 1 requests are valid for the android mapping API and match the following:
| appId |
| com.bugsnag.android.ndkapp |
36 changes: 34 additions & 2 deletions features/steps/gradle_plugin_steps.rb
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,13 @@
}
end

When("I build the NDK app using the {string} config") do |config|
Maze::Runner.environment['BUGSNAG_NDK_CONFIG'] = config
steps %Q{
And I run the script "features/scripts/build_ndk_app.sh" synchronously
}
end

When("I set the fixture JVM arguments to {string}") do |jvm_args|
steps %Q{
When I set environment variable "CUSTOM_JVM_ARGS" to "#{jvm_args}"
Expand All @@ -59,7 +66,7 @@ def setup_and_run_script(module_config, bugsnag_config, script_path, variant = n
end

When("I build the failing {string} on AGP {string} using the {string} bugsnag config") do |module_config, agp_version, bugsnag_config|
steps %Q{
steps %Q{
When I set environment variable "AGP_VERSION" to "#{agp_version}"
And I build the failing "#{module_config}" using the "#{bugsnag_config}" bugsnag config
}
Expand Down Expand Up @@ -105,6 +112,16 @@ def setup_and_run_script(module_config, bugsnag_config, script_path, variant = n
end
end

Then('{int} requests are valid for the android so symbol mapping API and match the following:') do |request_count, data_table|
requests = get_requests_with_field('build', 'soFile')
assert_equal(request_count, requests.length, 'Wrong number of android .so symbol mapping API requests')
Maze::Assertions::RequestSetAssertions.assert_requests_match requests, data_table

requests.each do |request|
valid_android_so_symbol_mapping_api?(request[:body])
end
end

Then('{int} requests are valid for the JS source map API and match the following:') do |request_count, data_table|
requests = get_requests_with_field('build', 'sourceMap')
assert_equal(request_count, requests.length, 'Wrong number of JS source map API requests')
Expand Down Expand Up @@ -167,24 +184,39 @@ def valid_build_api?(request_body)

def valid_android_mapping_api?(request_body)
valid_mapping_api?(request_body)
assert_not_nil(request_body['buildUUID'])
assert_not_nil(request_body['proguard'])
end

def valid_android_ndk_mapping_api?(request_body)
valid_mapping_api?(request_body)
assert_not_nil(request_body['buildUUID'])
assert_not_nil(request_body['soSymbolFile'])
end

def valid_android_so_symbol_mapping_api?(request_body)
valid_mapping_api?(request_body)
assert_not_nil(request_body['soFile'])

gzipped_part = request_body['soFile']
archive = Zlib::GzipReader.new(StringIO.new(gzipped_part))

# check that decompressed this is a valid ELF file:
# https://en.wikipedia.org/wiki/Executable_and_Linkable_Format#File_header
header = archive.read(4)
assert_equal("\x7f\x45\x4c\x46", header, 'not a valid ELF file')
end

def valid_android_unity_ndk_mapping_api?(request_body)
valid_mapping_api?(request_body)
assert_not_nil(request_body['buildUUID'])
assert_not_nil(request_body['soSymbolTableFile'])
end

def valid_mapping_api?(request_body)
assert_equal($api_key, request_body['apiKey'])
assert_not_nil(request_body['appId'])
assert_not_nil(request_body['versionCode'])
assert_not_nil(request_body['buildUUID'])
assert_not_nil(request_body['versionName'])
end

Expand Down
2 changes: 1 addition & 1 deletion gradle.properties
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ POM_NAME=Bugsnag Android Gradle Plugin
POM_ARTIFACT_ID=bugsnag-android-gradle-plugin
POM_PACKAGING=jar
GROUP=com.bugsnag
VERSION_NAME=7.3.1
VERSION_NAME=7.4.0
POM_DESCRIPTION=Gradle plugin to automatically upload ProGuard mapping files to Bugsnag.
POM_URL=https://github.com/bugsnag/bugsnag-android-gradle-plugin/
POM_SCM_URL=https://github.com/bugsnag/bugsnag-android-gradle-plugin/
Expand Down
Original file line number Diff line number Diff line change
@@ -1,10 +1,10 @@
package com.bugsnag.android.gradle

import org.gradle.api.file.RegularFileProperty
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.InputFile

interface AndroidManifestInfoReceiver {
@get:Input
@get:InputFile
val manifestInfo: RegularFileProperty
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,13 +2,26 @@ package com.bugsnag.android.gradle

import com.bugsnag.android.gradle.internal.BugsnagHttpClientHelper
import org.gradle.api.provider.Property
import org.gradle.api.tasks.Input
import org.gradle.api.tasks.Internal

interface BugsnagFileUploadTask {
@get:Input
val failOnUploadError: Property<Boolean>

@get:Input
val overwrite: Property<Boolean>

@get:Input
val endpoint: Property<String>

@get:Input
val retryCount: Property<Int>

@get:Input
val timeoutMillis: Property<Long>

@get:Internal
val httpClientHelper: Property<BugsnagHttpClientHelper>

fun configureWith(bugsnag: BugsnagPluginExtension) {
Expand Down
Loading

0 comments on commit 2184f1c

Please sign in to comment.