Skip to content
Merged
9 changes: 5 additions & 4 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

## Unreleased

### Fixes

- Fix `SENTRY_ALLOW_FAILURE` environment variable not being respected in Xcode build scripts ([#5616](https://github.com/getsentry/sentry-react-native/pull/5616))
- Fix iOS dSYM upload for main app in Expo EAS builds by adding inputPaths to build phase ([#5617](https://github.com/getsentry/sentry-react-native/pull/5617))

### Features

- Extends the experimental support of UI profiling to iOS ([#5611](https://github.com/getsentry/sentry-react-native/pull/5611))
Expand Down Expand Up @@ -53,10 +58,6 @@
- [changelog](https://github.com/getsentry/sentry-javascript-bundler-plugins/blob/main/CHANGELOG.md#490)
- [diff](https://github.com/getsentry/sentry-javascript-bundler-plugins/compare/4.8.0...4.9.0)

### Fixes

- Fix `SENTRY_ALLOW_FAILURE` environment variable not being respected in Xcode build scripts ([#5616](https://github.com/getsentry/sentry-react-native/pull/5616))

## 7.11.0

### Features
Expand Down
4 changes: 4 additions & 0 deletions packages/core/plugin/src/withSentryIOS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,10 @@ export const withSentryIOS: ConfigPlugin<string> = (config, sentryProperties: st
xcodeProject.addBuildPhase([], 'PBXShellScriptBuildPhase', 'Upload Debug Symbols to Sentry', null, {
shellPath: '/bin/sh',
shellScript: `/bin/sh ${SENTRY_REACT_NATIVE_XCODE_DEBUG_FILES_PATH}`,
inputPaths: [
'"$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Resources/DWARF/$(PRODUCT_NAME)"',
'"$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)"',
],
Copy link
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

magical 2 lines fix :D

});
}

Expand Down
98 changes: 98 additions & 0 deletions packages/core/test/expo-plugin/modifyXcodeProject.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -77,3 +77,101 @@ describe('Configures iOS native project correctly', () => {
expect(warnOnce).toHaveBeenCalled();
});
});

describe('Upload Debug Symbols to Sentry build phase', () => {
let mockXcodeProject: any;
let addBuildPhaseSpy: jest.Mock;
const expectedShellScript =
"/bin/sh `${NODE_BINARY:-node} --print \"require('path').dirname(require.resolve('@sentry/react-native/package.json')) + '/scripts/sentry-xcode-debug-files.sh'\"`";

const getOptions = () => {
const callArgs = addBuildPhaseSpy.mock.calls[0];
return callArgs[4];
};

beforeEach(() => {
addBuildPhaseSpy = jest.fn();
mockXcodeProject = {
pbxItemByComment: jest.fn().mockReturnValue(null),
addBuildPhase: addBuildPhaseSpy,
};
});

afterEach(() => {
jest.clearAllMocks();
});

it('creates Upload Debug Symbols build phase with correct shell script', () => {
mockXcodeProject.addBuildPhase([], 'PBXShellScriptBuildPhase', 'Upload Debug Symbols to Sentry', null, {
shellPath: '/bin/sh',
shellScript: expectedShellScript,
});

expect(addBuildPhaseSpy).toHaveBeenCalledWith(
[],
'PBXShellScriptBuildPhase',
'Upload Debug Symbols to Sentry',
null,
{
shellPath: '/bin/sh',
shellScript: expectedShellScript,
},
);
});

it('does not include inputPaths in options before fix', () => {
mockXcodeProject.addBuildPhase([], 'PBXShellScriptBuildPhase', 'Upload Debug Symbols to Sentry', null, {
shellPath: '/bin/sh',
shellScript: expectedShellScript,
});

const options = getOptions();

expect(options.inputPaths).toBeUndefined();
});

it('skips creating build phase if it already exists', () => {
mockXcodeProject.pbxItemByComment = jest.fn().mockReturnValue({
shellScript: 'existing',
});

expect(addBuildPhaseSpy).not.toHaveBeenCalled();
});

it('includes inputPaths with escaped quotes to avoid pbxproj serialization issues', () => {
mockXcodeProject.addBuildPhase([], 'PBXShellScriptBuildPhase', 'Upload Debug Symbols to Sentry', null, {
shellPath: '/bin/sh',
shellScript: expectedShellScript,
inputPaths: [
'"$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Resources/DWARF/$(PRODUCT_NAME)"',
'"$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)"',
],
});

const options = getOptions();

expect(options.inputPaths).toBeDefined();
expect(options.inputPaths).toHaveLength(2);
});

it('inputPaths values are wrapped in escaped quotes', () => {
mockXcodeProject.addBuildPhase([], 'PBXShellScriptBuildPhase', 'Upload Debug Symbols to Sentry', null, {
shellPath: '/bin/sh',
shellScript: expectedShellScript,
inputPaths: [
'"$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Resources/DWARF/$(PRODUCT_NAME)"',
'"$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)"',
],
});

const options = getOptions();

// Verify paths are wrapped in quotes to prevent pbxproj corruption
expect(options.inputPaths[0]).toMatch(/^".*"$/);
expect(options.inputPaths[1]).toMatch(/^".*"$/);
expect(options.inputPaths[0]).toBe(
'"$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)/Contents/Resources/DWARF/$(PRODUCT_NAME)"',
);
expect(options.inputPaths[1]).toBe('"$(DWARF_DSYM_FOLDER_PATH)/$(DWARF_DSYM_FILE_NAME)"');
});
});
Loading