Skip to content

release/13.4.0 #1293

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 14 commits into from
Oct 2, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
343 changes: 220 additions & 123 deletions .circleci/config.yml

Large diffs are not rendered by default.

19 changes: 19 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,24 @@
# Changelog

## [13.4.0](https://github.com/Instabug/Instabug-React-Native/compare/v13.3.0...v13.4.0) (October 2, 2024)

### Added

- Add support for Expo Router navigation tracking ([#1270](https://github.com/Instabug/Instabug-React-Native/pull/1270)).
- Enhance the network interceptor to capture more client error messages ([#1257](https://github.com/Instabug/Instabug-React-Native/pull/1257)).

### Changed

- Bump Instabug iOS SDK to v13.4.2 ([#1285](https://github.com/Instabug/Instabug-React-Native/pull/1285)). See release notes for [13.4.0](https://github.com/Instabug/Instabug-iOS/releases/tag/13.4.0), [13.4.1](https://github.com/Instabug/Instabug-iOS/releases/tag/13.4.1) and [13.4.2](https://github.com/Instabug/Instabug-iOS/releases/tag/13.4.2).
- Bump Instabug Android SDK to v13.4.1 ([#1285](https://github.com/Instabug/Instabug-React-Native/pull/1285)). See release notes for [13.4.0](https://github.com/Instabug/Instabug-Android/releases/tag/v13.4.0) and [13.4.1](https://github.com/Instabug/Instabug-Android/releases/tag/v13.4.1).

### Fixed

- Fix an issue with JavaScript fatal crashes on iOS causing them to be reported as native iOS crashes instead. ([#1290](https://github.com/Instabug/Instabug-React-Native/pull/1290)).
- Correctly resolve the flavor path when uploading sourcemaps on Android. ([#1225](https://github.com/Instabug/Instabug-React-Native/pull/1225)).
- Drop non-error objects reported as crashes since they don't have a stack trace ([#1279](https://github.com/Instabug/Instabug-React-Native/pull/1279)).
- Fix APM network logging on iOS when the response body is missing or empty. ([#1273](https://github.com/Instabug/Instabug-React-Native/pull/1273)).

## [13.3.0](https://github.com/Instabug/Instabug-React-Native/compare/v13.2.0...v13.3.0) (August 4, 2024)

### Added
Expand Down
2 changes: 1 addition & 1 deletion android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ android {
minSdkVersion getExtOrDefault('minSdkVersion').toInteger()
targetSdkVersion getExtOrDefault('targetSdkVersion').toInteger()
versionCode 1
versionName "13.3.0"
versionName "13.4.0"
multiDexEnabled true
ndk {
abiFilters "armeabi-v7a", "x86"
Expand Down
2 changes: 1 addition & 1 deletion android/native.gradle
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
project.ext.instabug = [
version: '13.3.0'
version: '13.4.1'
]

dependencies {
Expand Down
71 changes: 59 additions & 12 deletions android/sourcemaps.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,13 @@ gradle.projectsEvaluated {
def start = name.startsWith(prefixes[0]) ? prefixes[0].length() : prefixes[1].length()
def end = name.length() - suffix.length()
def flavor = name.substring(start, end).uncapitalize()
def defaultVersion = getDefaultVersion(flavor)

task.finalizedBy createUploadSourcemapsTask(flavor)
task.finalizedBy createUploadSourcemapsTask(flavor, defaultVersion.name, defaultVersion.code)
}
}

Task createUploadSourcemapsTask(String flavor) {
Task createUploadSourcemapsTask(String flavor, String defaultVersionName, String defaultVersionCode) {
def name = 'uploadSourcemaps' + flavor.capitalize()

// Don't recreate the task if it already exists.
Expand All @@ -38,13 +39,7 @@ Task createUploadSourcemapsTask(String flavor) {
try {
def appProject = project(':app')
def appDir = appProject.projectDir
def flavorPath = flavor + (flavor.empty ? '' : '/')
def sourceMapDest = "build/generated/sourcemaps/react/${flavorPath}release/index.android.bundle.map"
def sourceMapFile = new File(appDir, sourceMapDest)

if (!sourceMapFile.exists()) {
throw new InvalidUserDataException("Unable to find source map file at: ${sourceMapFile.absolutePath}")
}
def sourceMapFile = getSourceMapFile(appDir, flavor)

def jsProjectDir = rootDir.parentFile
def instabugDir = new File(['node', '-p', 'require.resolve("instabug-reactnative/package.json")'].execute(null, rootDir).text.trim()).getParentFile()
Expand All @@ -53,9 +48,8 @@ Task createUploadSourcemapsTask(String flavor) {
def inferredToken = executeShellScript(tokenShellFile, jsProjectDir)
def appToken = resolveVar('App Token', 'INSTABUG_APP_TOKEN', inferredToken)

def projectConfig = appProject.android.defaultConfig
def versionName = resolveVar('Version Name', 'INSTABUG_VERSION_NAME', "${projectConfig.versionName}")
def versionCode = resolveVar('Version Code', 'INSTABUG_VERSION_CODE', "${projectConfig.versionCode}")
def versionName = resolveVar('Version Name', 'INSTABUG_VERSION_NAME', defaultVersionName)
def versionCode = resolveVar('Version Code', 'INSTABUG_VERSION_CODE', defaultVersionCode)

exec {
def osCompatibility = Os.isFamily(Os.FAMILY_WINDOWS) ? ['cmd', '/c'] : []
Expand All @@ -80,6 +74,59 @@ Task createUploadSourcemapsTask(String flavor) {
return provider.get()
}

File getSourceMapFile(File appDir, String flavor) {
def defaultFlavorPath = flavor.empty ? 'release' : "${flavor}Release"
def defaultSourceMapDest = "build/generated/sourcemaps/react/${defaultFlavorPath}/index.android.bundle.map"
def defaultSourceMapFile = new File(appDir, defaultSourceMapDest)

if (defaultSourceMapFile.exists()) {
return defaultSourceMapFile
}

if (flavor.empty) {
throw new InvalidUserDataException("Unable to find source map file at: ${defaultSourceMapFile.absolutePath}.")
}

def fallbackSourceMapDest = "build/generated/sourcemaps/react/${flavor}/release/index.android.bundle.map"
def fallbackSourceMapFile = new File(appDir, fallbackSourceMapDest)

project.logger.info "Unable to find source map file at: ${defaultSourceMapFile.absolutePath}.\n" +
"Falling back to ${fallbackSourceMapFile.absolutePath}."

if (!fallbackSourceMapFile.exists()) {
throw new InvalidUserDataException("Unable to find source map file at: ${fallbackSourceMapFile.absolutePath} either.")
}

return fallbackSourceMapFile
}

/**
* Infers the app version to use in source map upload based on the flavor.
* This is needed since different flavors may have different version codes and names (e.g. version suffixes).
*
* It checks the version for the flavor's variant.
* If no variant is found it falls back to the app's default config.
*
*
* @param flavor The flavor to get the app version for.
* @return A map containing the version code and version name.
*/
Map<String, String> getDefaultVersion(String flavor) {
def appProject = project(':app')
def defaultConfig = appProject.android.defaultConfig

def variants = appProject.android.applicationVariants

// uncapitalize is used to turn "Release" into "release" if the flavor is empty
def variantName = "${flavor}Release".uncapitalize()
def variant = variants.find { it.name.uncapitalize() == variantName }

def versionName = variant?.versionName ?: defaultConfig.versionName
def versionCode = variant?.versionCode ?: defaultConfig.versionCode

return [name: "${versionName}", code: "${versionCode}"]
}

boolean isUploadSourcemapsEnabled() {
def envValue = System.getenv('INSTABUG_SOURCEMAPS_UPLOAD_DISABLE')?.toBoolean()
def defaultValue = true
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,6 @@
import com.facebook.react.bridge.NativeModule;
import com.facebook.react.bridge.ReactApplicationContext;
import com.facebook.react.uimanager.ViewManager;
import com.instabug.reactlibrary.RNInstabugAPMModule;
import com.instabug.reactlibrary.RNInstabugBugReportingModule;
import com.instabug.reactlibrary.RNInstabugCrashReportingModule;
import com.instabug.reactlibrary.RNInstabugFeatureRequestsModule;
import com.instabug.reactlibrary.RNInstabugReactnativeModule;
import com.instabug.reactlibrary.RNInstabugRepliesModule;
import com.instabug.reactlibrary.RNInstabugSessionReplayModule;
import com.instabug.reactlibrary.RNInstabugSurveysModule;

import java.util.ArrayList;
import java.util.Collections;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
{
"instabug-domain": "api.instabug.com",
"apm-domain": "api-apm.instabug.com"
}
8 changes: 8 additions & 0 deletions examples/default/android/build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -27,5 +27,13 @@ allprojects {
maven {
url("$rootDir/../node_modules/detox/Detox-android")
}

maven {
credentials {
username System.getenv("DREAM11_MAVEN_USERNAME")
password System.getenv("DREAM11_MAVEN_PASSWORD")
}
url "https://mvn.instabug.com/nexus/repository/dream-11"
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
CC3DF8932A1DFC9A003E9914 /* InstabugSurveysTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3DF88B2A1DFC99003E9914 /* InstabugSurveysTests.m */; };
CC3DF8942A1DFC9A003E9914 /* InstabugAPMTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3DF88C2A1DFC99003E9914 /* InstabugAPMTests.m */; };
CC3DF8952A1DFC9A003E9914 /* IBGConstants.m in Sources */ = {isa = PBXBuildFile; fileRef = CC3DF88D2A1DFC9A003E9914 /* IBGConstants.m */; };
CC487A9C2C71FCFC0021F680 /* Instabug.plist in Resources */ = {isa = PBXBuildFile; fileRef = CC487A9B2C71FCFC0021F680 /* Instabug.plist */; };
CCF1E4092B022CF20024802D /* RNInstabugTests.m in Sources */ = {isa = PBXBuildFile; fileRef = CCF1E4082B022CF20024802D /* RNInstabugTests.m */; };
CD36F4707EA1F435D2CC7A15 /* libPods-InstabugExample-InstabugTests.a in Frameworks */ = {isa = PBXBuildFile; fileRef = 3AF7A6E02D40E0CEEA833CC4 /* libPods-InstabugExample-InstabugTests.a */; };
F7BF47401EF3A435254C97BB /* libPods-InstabugExample.a in Frameworks */ = {isa = PBXBuildFile; fileRef = BAED0D0441A708AE2390E153 /* libPods-InstabugExample.a */; };
Expand Down Expand Up @@ -64,6 +65,7 @@
CC3DF88B2A1DFC99003E9914 /* InstabugSurveysTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InstabugSurveysTests.m; sourceTree = "<group>"; };
CC3DF88C2A1DFC99003E9914 /* InstabugAPMTests.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = InstabugAPMTests.m; sourceTree = "<group>"; };
CC3DF88D2A1DFC9A003E9914 /* IBGConstants.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = IBGConstants.m; sourceTree = "<group>"; };
CC487A9B2C71FCFC0021F680 /* Instabug.plist */ = {isa = PBXFileReference; lastKnownFileType = file.bplist; name = Instabug.plist; path = InstabugExample/Instabug.plist; sourceTree = "<group>"; };
CCF1E4082B022CF20024802D /* RNInstabugTests.m */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.c.objc; path = RNInstabugTests.m; sourceTree = "<group>"; };
DBCB1B1D023646D84146C91E /* Pods-InstabugExample-InstabugTests.release.xcconfig */ = {isa = PBXFileReference; includeInIndex = 1; lastKnownFileType = text.xcconfig; name = "Pods-InstabugExample-InstabugTests.release.xcconfig"; path = "Target Support Files/Pods-InstabugExample-InstabugTests/Pods-InstabugExample-InstabugTests.release.xcconfig"; sourceTree = "<group>"; };
ED297162215061F000B7C4FE /* JavaScriptCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = JavaScriptCore.framework; path = System/Library/Frameworks/JavaScriptCore.framework; sourceTree = SDKROOT; };
Expand Down Expand Up @@ -120,6 +122,7 @@
13B07FAE1A68108700A75B9A /* InstabugExample */ = {
isa = PBXGroup;
children = (
CC487A9B2C71FCFC0021F680 /* Instabug.plist */,
13B07FAF1A68108700A75B9A /* AppDelegate.h */,
13B07FB01A68108700A75B9A /* AppDelegate.mm */,
13B07FB51A68108700A75B9A /* Images.xcassets */,
Expand Down Expand Up @@ -296,6 +299,7 @@
buildActionMask = 2147483647;
files = (
81AB9BB82411601600AC10FF /* LaunchScreen.storyboard in Resources */,
CC487A9C2C71FCFC0021F680 /* Instabug.plist in Resources */,
13B07FBF1A68108700A75B9A /* Images.xcassets in Resources */,
);
runOnlyForDeploymentPostprocessing = 0;
Expand Down
Binary file added examples/default/ios/InstabugExample/Instabug.plist
Binary file not shown.
16 changes: 16 additions & 0 deletions examples/default/ios/InstabugTests/InstabugCrashReportingTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,22 @@ - (void)testSetEnabled {
XCTAssertFalse(IBGCrashReporting.enabled);
}

- (void)testSendJSCrash {
NSDictionary *stackTrace = @{};

XCTestExpectation *expectation = [self expectationWithDescription:@"Expected resolve to be called."];

RCTPromiseResolveBlock resolve = ^(id result) {
[expectation fulfill];
};
RCTPromiseRejectBlock reject = ^(NSString *code, NSString *message, NSError *error) {};

[self.bridge sendJSCrash:stackTrace resolver:resolve rejecter:reject];

[self waitForExpectations:@[expectation] timeout:1];
OCMVerify([self.mCrashReporting cp_reportFatalCrashWithStackTrace:stackTrace]);
}

- (void)testSendNonFatalErrorJsonCrash {
NSDictionary<NSString *,NSString * > *jsonCrash = @{};
NSString *fingerPrint = @"fingerprint";
Expand Down
8 changes: 6 additions & 2 deletions examples/default/ios/InstabugTests/InstabugSampleTests.m
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
#import <XCTest/XCTest.h>
#import "OCMock/OCMock.h"
#import "Instabug/Instabug.h"
#import "Instabug/IBGSurvey.h"
#import "InstabugReactBridge.h"
#import <Instabug/IBGTypes.h>
#import "IBGConstants.h"
Expand Down Expand Up @@ -366,7 +365,12 @@ - (void)testNetworkLogIOS {
startTime:startTime * 1000
duration:duration * 1000
gqlQueryName:gqlQueryName
serverErrorMessage:serverErrorMessage]);
serverErrorMessage:serverErrorMessage
isW3cCaughted:nil
partialID:nil
timestamp:nil
generatedW3CTraceparent:nil
caughtedW3CTraceparent:nil]);
}

- (void)testSetFileAttachment {
Expand Down
1 change: 0 additions & 1 deletion examples/default/ios/InstabugTests/RNInstabugTests.m
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
#import <XCTest/XCTest.h>
#import "OCMock/OCMock.h"
#import "Instabug/Instabug.h"
#import "Instabug/IBGSurvey.h"
#import <Instabug/IBGTypes.h>
#import "RNInstabug.h"
#import "RNInstabug/Instabug+CP.h"
Expand Down
10 changes: 5 additions & 5 deletions examples/default/ios/Podfile.lock
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,7 @@ PODS:
- hermes-engine (0.72.3):
- hermes-engine/Pre-built (= 0.72.3)
- hermes-engine/Pre-built (0.72.3)
- Instabug (13.3.0)
- Instabug (13.4.2)
- instabug-reactnative-ndk (0.1.0):
- RCT-Folly (= 2021.07.22.00)
- React-Core
Expand Down Expand Up @@ -475,8 +475,8 @@ PODS:
- RNGestureHandler (2.13.4):
- RCT-Folly (= 2021.07.22.00)
- React-Core
- RNInstabug (13.3.0):
- Instabug (= 13.3.0)
- RNInstabug (13.4.0):
- Instabug (= 13.4.2)
- React-Core
- RNReanimated (3.5.4):
- DoubleConversion
Expand Down Expand Up @@ -704,7 +704,7 @@ SPEC CHECKSUMS:
Google-Maps-iOS-Utils: f77eab4c4326d7e6a277f8e23a0232402731913a
GoogleMaps: 032f676450ba0779bd8ce16840690915f84e57ac
hermes-engine: 10fbd3f62405c41ea07e71973ea61e1878d07322
Instabug: 4f26295103a330ec0236918359eef7ccaa74e2fa
Instabug: 7a71890217b97b1e32dbca96661845396b66da2f
instabug-reactnative-ndk: 960119a69380cf4cbe47ccd007c453f757927d17
libevent: 4049cae6c81cdb3654a443be001fb9bdceff7913
OCMock: 300b1b1b9155cb6378660b981c2557448830bdc6
Expand Down Expand Up @@ -748,7 +748,7 @@ SPEC CHECKSUMS:
ReactCommon: 3ccb8fb14e6b3277e38c73b0ff5e4a1b8db017a9
RNCClipboard: 41d8d918092ae8e676f18adada19104fa3e68495
RNGestureHandler: 6e46dde1f87e5f018a54fe5d40cd0e0b942b49ee
RNInstabug: a4ac0bd09123f6be7d58be541dc220acbaff8dc3
RNInstabug: 8e7eb1df3f35b935dda661f5bb475f37cef595e6
RNReanimated: ab2e96c6d5591c3dfbb38a464f54c8d17fb34a87
RNScreens: b21dc57dfa2b710c30ec600786a3fc223b1b92e7
RNSVG: 80584470ff1ffc7994923ea135a3e5ad825546b9
Expand Down
1 change: 1 addition & 0 deletions examples/default/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@
"@react-navigation/native": "^6.1.6",
"@react-navigation/native-stack": "^6.9.12",
"graphql": "^16.8.1",
"axios": "^1.7.4",
"graphql-request": "^6.1.0",
"instabug-reactnative": "link:../..",
"instabug-reactnative-ndk": "github:https://github.com/Instabug/Instabug-React-Native-NDK",
Expand Down
11 changes: 9 additions & 2 deletions examples/default/src/App.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ import React, { useEffect } from 'react';
import { StyleSheet } from 'react-native';

import { GestureHandlerRootView } from 'react-native-gesture-handler';
import { NavigationContainer } from '@react-navigation/native';
import { NavigationContainer, useNavigationContainerRef } from '@react-navigation/native';
import Instabug, {
CrashReporting,
InvocationEvent,
Expand All @@ -20,6 +20,7 @@ import { QueryClient, QueryClientProvider } from 'react-query';
const queryClient = new QueryClient();

export const App: React.FC = () => {
const navigationRef = useNavigationContainerRef();
useEffect(() => {
Instabug.init({
token: 'deb1910a7342814af4e4c9210c786f35',
Expand All @@ -33,11 +34,17 @@ export const App: React.FC = () => {
});
}, []);

useEffect(() => {
const unregisterListener = Instabug.setNavigationListener(navigationRef);

return unregisterListener;
}, [navigationRef]);

return (
<GestureHandlerRootView style={styles.root}>
<NativeBaseProvider theme={nativeBaseTheme}>
<QueryClientProvider client={queryClient}>
<NavigationContainer onStateChange={Instabug.onStateChange} theme={navigationTheme}>
<NavigationContainer theme={navigationTheme} ref={navigationRef}>
<RootTabNavigator />
</NavigationContainer>
</QueryClientProvider>
Expand Down
32 changes: 32 additions & 0 deletions examples/default/src/screens/apm/NetworkScreen.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import { useQuery } from 'react-query';
import { HStack, VStack } from 'native-base';
import { gql, request } from 'graphql-request';
import { CustomButton } from '../../components/CustomButton';
import axios from 'axios';

export const NetworkScreen: React.FC = () => {
const [endpointUrl, setEndpointUrl] = useState('');
Expand Down Expand Up @@ -45,6 +46,32 @@ export const NetworkScreen: React.FC = () => {
}
}

async function sendRequestToUrlUsingAxios() {
let urlToSend = '';

if (endpointUrl.trim() !== '') {
urlToSend = endpointUrl;
console.log('Sending request to: ', endpointUrl);
} else {
// Use json placeholder URL as a default if endpointUrl is empty
console.log('sending request to default json placeholder');
urlToSend = defaultRequestUrl;
}

try {
// Perform the request using the urlToSend
const response = await axios.get(urlToSend);
// Format the JSON response for better logging
const formattedData = JSON.stringify(response.data, null, 2);

// Log the formatted response
console.log('Response:', formattedData);
} catch (error) {
// Handle errors appropriately
console.error('Error:', error);
}
}

const fetchGraphQlData = async () => {
const document = gql`
query {
Expand Down Expand Up @@ -75,6 +102,11 @@ export const NetworkScreen: React.FC = () => {
value={endpointUrl}
/>
<CustomButton onPress={sendRequestToUrl} title="Send Request To Url" />
<CustomButton
onPress={sendRequestToUrlUsingAxios}
title="Send Request To Url Using Axios"
/>

<CustomButton onPress={() => refetch} title="Reload GraphQL" />
<View>
{isLoading && <Text>Loading...</Text>}
Expand Down
Loading