expo / sentry-expo

MIT License
202 stars 83 forks source link

Doesn't work in iOS monorepo #246

Closed nandorojo closed 2 years ago

nandorojo commented 2 years ago

Summary

When upgrading from Expo SDK 42 to 44, sentry-expo didn't seen to upgrade from 4.0.1. As a result, I got a really long error message from expo run:ios, which I'll copy below. It was hard to narrow down the error to sentry, since it all just gets dumped to the terminal in red text. I found sentry as the issue by building from XCode.

I then tried expo install sentry-expo, and it still installed an old version. I had to use yarn add instead.

Screen Shot 2022-03-22 at 3 22 33 PM

^ this is wrong, since 4.1.0 is out.

This is the relevant error from expo run:ios:

line 3: ../node_modules/@sentry/cli/bin/sentry-cli: No such file or directory
Command PhaseScriptExecution failed with a nonzero exit code
View full error message The error was too long for GitHub issues, so I trimmed it down. ```sh 2022-03-22 14:32:35.130 xcodebuild[64066:344956] Requested but did not find extension point with identifier Xcode.IDEKit.ExtensionSentinelHostApplications for extension Xcode.DebuggerFoundation.AppExtensionHosts.watchOS of plug-in com.apple.dt.IDEWatchSupportCore 2022-03-22 14:32:35.130 xcodebuild[64066:344956] Requested but did not find extension point with identifier Xcode.IDEKit.ExtensionPointIdentifierToBundleIdentifier for extension Xcode.DebuggerFoundation.AppExtensionToBundleIdentifierMap.watchOS of plug-in com.apple.dt.IDEWatchSupportCore ** BUILD FAILED ** The following build commands failed: PhaseScriptExecution Upload\ Debug\ Symbols\ to\ Sentry /Users/account/Library/Developer/Xcode/DerivedData/myappDev-fdeajtvriphfoqebckrqlimwjwzw/Build/Intermediates.noindex/myappDev.build/Debug-iphonesimulator/myappDev.build/Script-0C4E603DB83B4ECE9956F47A.sh (in target 'myappDev' from project 'myappDev') (1 failure) Build logs written to /Users/account/Developer/app-folder/applications/expo-app/.expo/xcodebuild.log line 3: ../node_modules/@sentry/cli/bin/sentry-cli: No such file or directory Command PhaseScriptExecution failed with a nonzero exit code ```

Now that I got the right version installed, I still get the error above. The solution was to add a patch to the config plugin (which I'll put at the bottom of this issue).

Managed or bare workflow? If you have ios/ or android/ directories in your project, the answer is bare!

bare

What platform(s) does this occur on?

iOS

SDK Version (managed workflow only)

44

Environment

  expo-env-info 1.0.2 environment info:
    System:
      OS: macOS 12.2.1
      Shell: 5.8 - /bin/zsh
    Binaries:
      Node: 16.13.0 - ~/.nvm/versions/node/v16.13.0/bin/node
      Yarn: 1.22.10 - ~/Developer/madison-hacks/bg-axel/applications/speed/node_modules/.bin/yarn
      npm: 7.19.0 - ~/Developer/madison-hacks/bg-axel/node_modules/.bin/npm
      Watchman: 4.9.0 - /usr/local/bin/watchman
    Managers:
      CocoaPods: 1.11.2 - /usr/local/bin/pod
    SDKs:
      iOS SDK:
        Platforms: DriverKit 21.4, iOS 15.4, macOS 12.3, tvOS 15.4, watchOS 8.5
      Android SDK:
        API Levels: 30
        Build Tools: 29.0.2, 30.0.3, 31.0.0
        System Images: android-30 | Google APIs Intel x86 Atom
    IDEs:
      Android Studio: 4.2 AI-202.7660.26.42.7486908
      Xcode: 13.3/13E113 - /usr/bin/xcodebuild
    npmGlobalPackages:
      eas-cli: 0.39.0
      expo-cli: 5.3.0
    Expo Workflow: bare

Reproducible demo or steps to reproduce from a blank project

I haven't made a repro yet, but I can try to. There are 2 issues at hand here:

  1. expo install sentry-expo / expo upgrade installs an old version. I had to use yarn add sentry-expo <peer deps here>
  2. In a monorepo, @sentry/cli isn't properly resolved from expo run:ios. To get around this, I removed this code from the config plugin with the following patch:
diff --git a/node_modules/sentry-expo/plugin/build/withSentryIOS.js b/node_modules/sentry-expo/plugin/build/withSentryIOS.js
index 59b34ab..d3304fe 100644
--- a/node_modules/sentry-expo/plugin/build/withSentryIOS.js
+++ b/node_modules/sentry-expo/plugin/build/withSentryIOS.js
@@ -53,13 +53,13 @@ function modifyExistingXcodeBuildScript(script) {
         config_plugins_1.WarningAggregator.addWarningIOS('sentry-expo', `Unable to modify build script 'Bundle React Native code and images'. Please open a bug report at https://github.com/expo/sentry-expo.`);
         return;
     }
-    let code = JSON.parse(script.shellScript);
-    code =
-        'export SENTRY_PROPERTIES=sentry.properties\n' +
-            'export EXTRA_PACKAGER_ARGS="--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map"\n' +
-            code.replace(/^.*?(packager|scripts)\/react-native-xcode\.sh\s*(\\'\\\\")?/m, (match) => "`node --print \"require.resolve('@sentry/cli/package.json').slice(0, -13) + '/bin/sentry-cli'\"` react-native xcode --force-foreground\n" +
-                match);
-    script.shellScript = JSON.stringify(code);
+    // let code = JSON.parse(script.shellScript);
+    // code =
+    //     'export SENTRY_PROPERTIES=sentry.properties\n' +
+    //         'export EXTRA_PACKAGER_ARGS="--sourcemap-output $DERIVED_FILE_DIR/main.jsbundle.map"\n' +
+    //         code.replace(/^.*?(packager|scripts)\/react-native-xcode\.sh\s*(\\'\\\\")?/m, (match) => "`node --print \"require.resolve('@sentry/cli/package.json').slice(0, -13) + '/bin/sentry-cli'\"` react-native xcode --force-foreground\n" +
+    //             match);
+    // script.shellScript = JSON.stringify(code);
 }
 exports.modifyExistingXcodeBuildScript = modifyExistingXcodeBuildScript;
 function writeSentryPropertiesTo(filepath, sentryProperties) {

Removing that code may not be the right thing to do, but it was necessary to get the app to build. I'll try to make a repro with a solito monorepo when I have time soon. Let me know if that's necessary, or if you have enough info here. Thanks!

tichopad commented 2 years ago

@nandorojo I've experienced the same issue using sentry-expo and building via EAS for iOS. It looks like the issue stems from @sentry/cli not being able to resolve certain paths in a monorepo setup when building for iOS. Supposedly there was a similar problem on Android, but it got fixed already. See this issue.

Anyway, in the meantime, I fixed it by creating symlinks for certain Sentry and RN-related packages from the app's node_modules folder to the root node_modules folder and in a postinstall script :arrow_down: . The logic and packages linked are inspired by the original expo-yarn-workspaces package.

create-packages-symlinks.js ```javascript const fs = require('fs/promises'); const path = require('path'); const necessaryPackages = [ '@react-native-community/cli-platform-ios', '@react-native-community/cli-platform-android', '@sentry/cli', '@sentry/react-native', 'expo', 'react-native', 'jsc-android', 'hermes-engine', 'sentry-expo', ]; const rootNodeModulesPath = path.resolve(__dirname, '../..', 'node_modules'); const localNodeModulesPath = path.resolve(__dirname, '../node_modules'); (async () => { for (const packageName of necessaryPackages) { const safePackageName = packageName.replace('/', path.sep); const rootLevelPackagePath = path.join(rootNodeModulesPath, safePackageName); const rootLevelPackageStat = await getFileStat(rootLevelPackagePath); if (!rootLevelPackageStat || !rootLevelPackageStat?.isDirectory()) continue; if (packageName.startsWith('@')) { const [scope, name] = packageName.split('/'); const scopePath = path.join(localNodeModulesPath, scope); const relativeRootLevelPackagePath = path.relative(scopePath, rootLevelPackagePath); const localPackagePath = path.join(scopePath, name); await symlinkPackage(relativeRootLevelPackagePath, localPackagePath); } else { const relativeRootLevelPackagePath = path.relative( localNodeModulesPath, rootLevelPackagePath, ); const localPackagePath = path.join(localNodeModulesPath, packageName); await symlinkPackage(relativeRootLevelPackagePath, localPackagePath); } } })(); async function symlinkPackage(toPath, fromPath) { const parentFolderPath = path.resolve(fromPath, '..'); await fs.mkdir(parentFolderPath, { recursive: true }); const localPackageStat = await getFileStat(fromPath); if (localPackageStat) { if (!localPackageStat.isDirectory()) { console.warn(`Expected ${fromPath} to be a directory, but it's a file.`); } return; } await fs.symlink(toPath, fromPath, 'junction'); } async function getFileStat(path) { try { return await fs.stat(path); } catch (error) { if (error.code === 'ENOENT') return null; else throw error; } } ```
Aubind97 commented 2 years ago

Hello, I had the same issue.

It looks like it's (in your case) the Upload\ Debug\ Symbols\ to\ Sentry /Users/account/Library/Developer/Xcode/DerivedData/myappDev-fdeajtvriphfoqebckrqlimwjwzw/Build/Intermediates.noindex/myappDev.build/Debug-iphonesimulator/myappDev.build/Script-0C4E603DB83B4ECE9956F47A.sh file that cause the error.

If you try to manually run the script, an error message told you to add a --org flag.

To solve the problem, I exported SENTRY_PROJECT and SENTRY_ORG as env variable.

export SENTRY_PROJECT='<project_name>'
export SENTRY_ORG='<organisation_name>'

Then, in my case, the --local build works fine.

github-actions[bot] commented 2 years ago

This issue is stale because it has been open for 60 days with no activity. If there is no activity in the next 7 days, the issue will be closed.

github-actions[bot] commented 2 years ago

This issue was closed because it has been inactive for 7 days since being marked as stale. Please open a new issue if you believe you are encountering a related problem.