Skip to content
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

Uploading source maps for updates not working #319

Closed
karbone4 opened this issue Feb 15, 2023 · 4 comments
Closed

Uploading source maps for updates not working #319

karbone4 opened this issue Feb 15, 2023 · 4 comments

Comments

@karbone4
Copy link

karbone4 commented Feb 15, 2023

Summary

I use expo-dev-client. When I build my app, source maps are uploaded, and I can see clearly the error on sentry thanks to postPublish script.
I followed instructions on the doc https://docs.expo.dev/guides/using-sentry/#uploading-source-maps-for-updates for uploading source maps, but it isn't working 😔. I can't see where is the error due to wrong source maps :
image

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

managed

What platform(s) does this occur on?

Android, iOS

SDK Version (managed workflow only)

47

Environment

expo-env-info 1.0.5 environment info:
System:
OS: macOS 13.2
Shell: 5.8.1 - /bin/zsh
Binaries:
Node: 16.17.1 - ~/.nvm/versions/node/v16.17.1/bin/node
Yarn: 1.22.19 - ~/projects/cocolis-react-native/node_modules/.bin/yarn
npm: 9.3.1 - ~/.nvm/versions/node/v16.17.1/bin/npm
Watchman: 2022.11.07.00 - /opt/homebrew/bin/watchman
Managers:
CocoaPods: 1.11.3 - /opt/homebrew/bin/pod
SDKs:
iOS SDK:
Platforms: DriverKit 22.2, iOS 16.2, macOS 13.1, tvOS 16.1, watchOS 9.1
IDEs:
Android Studio: 2021.3 AI-213.7172.25.2113.9014738
Xcode: 14.2/14C18 - /usr/bin/xcodebuild
npmPackages:
expo: ^47.0.0 => 47.0.8
react: 18.1.0 => 18.1.0
react-dom: 18.1.0 => 18.1.0
react-native: 0.70.5 => 0.70.5
npmGlobalPackages:
eas-cli: 3.5.2
expo-cli: 6.1.0
Expo Workflow: managed

"@sentry/react-native": "4.9.0",
"sentry-expo": "~6.0.0",

Reproducible demo or steps to reproduce from a blank project

  1. eas build with postPublish hook script → upload source maps to sentry
  2. Error stack trace is ok
    image
  3. eas update (generate bundles in dist folder)
    It generates :
  • ios-$hash.js
  • ios-$hash.map
  • android-$hash.js
  • android-$hash.map
  1. Upload source maps using doc :
node_modules/@sentry/cli/bin/sentry-cli releases \
    files [email protected]+14 \
    upload-sourcemaps \
    --dist 14 \
    --rewrite \
    dist/bundles/android-$hash.js dist/bundles/android-$hash.map
node_modules/@sentry/cli/bin/sentry-cli releases \
    files [email protected]+8 \
    upload-sourcemaps \
    --dist 8 \
    --rewrite \
    dist/bundles/ios-$hash.js dist/bundles/ios-$hash.map

I use nativeVersion as dist because in my Sentry.init, dist is set to nativeVersion. I tried to change it to eas update id but it does the same.
I already tested to rename bundle files for matching build bundle files, but it didn't work either.

  • ios-$hash.js → main.jsbundle
  • ios-$hash.map → main.jsbundle.map
  • android-$hash.js → index.android.bundle
  • android-$hash.map → index.android.bundle.map
  1. Now the source maps are uploaded but js is 0B for both os.
    image
    image
  2. No stack trace :
    image
@kbrandwijk
Copy link
Contributor

As per the instructions in our docs, you should rename the bundles only, not the map files.

@fuelkoy
Copy link

fuelkoy commented Feb 16, 2023

Related to #313?

@karbone4
Copy link
Author

I misunderstood the doc. Now it works, thanks !

I did a script in order to upload source map from eas update if anyone wants it (run it ts-node my-script.ts) :

import { exec } from 'child_process';
// eslint-disable-next-line import/no-extraneous-dependencies
import { Command } from 'commander';
import util from 'util';

import { expo } from '../../app.json';
import { build } from '../../eas.json';
import { version } from '../../package.json';

const promisifiedExec = util.promisify(exec);

const uploadAndroidSourceMap = async (easBuild: any, updates: any) => {
    const appVersion = version;

    const androidVersionCode = expo.android.versionCode;
    const androidPackageName = easBuild.env.ANDROID_PACKAGE_NAME;
    const androidUpdateId = updates.find((update: any) => update.platform === 'android').id;
    await promisifiedExec(`mv dist/bundles/android*.js dist/bundles/index.android.bundle`);
    await promisifiedExec(`node_modules/@sentry/cli/bin/sentry-cli \
        releases \
        files ${androidPackageName}@${appVersion}+${androidVersionCode} \
        upload-sourcemaps \
        --dist ${androidUpdateId} \
        --rewrite \
        dist/bundles/index.android.bundle dist/bundles/android-*.map`);
};

const uploadIosSourceMap = async (easBuild: any, updates: any) => {
    const appVersion = version;

    const iosBuildNumber = expo.ios.buildNumber;
    const iosBundleID = easBuild.env.IOS_BUNDLE_ID;
    const iosUpdateId = updates.find((update: any) => update.platform === 'ios').id;
    await promisifiedExec(`mv dist/bundles/ios*.js dist/bundles/main.jsbundle`);
    await promisifiedExec(`node_modules/@sentry/cli/bin/sentry-cli \
        releases \
        files ${iosBundleID}@${appVersion}+${iosBuildNumber} \
        upload-sourcemaps \
        --dist ${iosUpdateId} \
        --rewrite \
        dist/bundles/main.jsbundle dist/bundles/ios-*.map`);
};

const program = new Command().requiredOption('-p, --profile  [value]', 'EAS profile').action(async (options) => {
    if (!Object.keys(build).includes(options.profile)) {
        console.error('Profile must be includes in : ', Object.keys(build));
    }
    const easBuild = build[options.profile as keyof typeof build];
    const { channel } = easBuild;

    const channelUpdates = await promisifiedExec(`eas update:list --branch ${channel} --non-interactive --json`);
    if (channelUpdates.stderr) {
        console.error(channelUpdates.stderr);
    }
    const groupID = JSON.parse(channelUpdates.stdout).currentPage[0].group;
    const updates = await promisifiedExec(`eas update:view ${groupID} --json`);
    if (updates.stderr) {
        console.error(updates.stderr);
    }

    await uploadAndroidSourceMap(easBuild, JSON.parse(updates.stdout));
    await uploadIosSourceMap(easBuild, JSON.parse(updates.stdout));
});

program.parse();

@federico-bubble
Copy link

I misunderstood the doc. Now it works, thanks !

I did a script in order to upload source map from eas update if anyone wants it (run it ts-node my-script.ts) :

import { exec } from 'child_process';
// eslint-disable-next-line import/no-extraneous-dependencies
import { Command } from 'commander';
import util from 'util';

import { expo } from '../../app.json';
import { build } from '../../eas.json';
import { version } from '../../package.json';

const promisifiedExec = util.promisify(exec);

const uploadAndroidSourceMap = async (easBuild: any, updates: any) => {
    const appVersion = version;

    const androidVersionCode = expo.android.versionCode;
    const androidPackageName = easBuild.env.ANDROID_PACKAGE_NAME;
    const androidUpdateId = updates.find((update: any) => update.platform === 'android').id;
    await promisifiedExec(`mv dist/bundles/android*.js dist/bundles/index.android.bundle`);
    await promisifiedExec(`node_modules/@sentry/cli/bin/sentry-cli \
        releases \
        files ${androidPackageName}@${appVersion}+${androidVersionCode} \
        upload-sourcemaps \
        --dist ${androidUpdateId} \
        --rewrite \
        dist/bundles/index.android.bundle dist/bundles/android-*.map`);
};

const uploadIosSourceMap = async (easBuild: any, updates: any) => {
    const appVersion = version;

    const iosBuildNumber = expo.ios.buildNumber;
    const iosBundleID = easBuild.env.IOS_BUNDLE_ID;
    const iosUpdateId = updates.find((update: any) => update.platform === 'ios').id;
    await promisifiedExec(`mv dist/bundles/ios*.js dist/bundles/main.jsbundle`);
    await promisifiedExec(`node_modules/@sentry/cli/bin/sentry-cli \
        releases \
        files ${iosBundleID}@${appVersion}+${iosBuildNumber} \
        upload-sourcemaps \
        --dist ${iosUpdateId} \
        --rewrite \
        dist/bundles/main.jsbundle dist/bundles/ios-*.map`);
};

const program = new Command().requiredOption('-p, --profile  [value]', 'EAS profile').action(async (options) => {
    if (!Object.keys(build).includes(options.profile)) {
        console.error('Profile must be includes in : ', Object.keys(build));
    }
    const easBuild = build[options.profile as keyof typeof build];
    const { channel } = easBuild;

    const channelUpdates = await promisifiedExec(`eas update:list --branch ${channel} --non-interactive --json`);
    if (channelUpdates.stderr) {
        console.error(channelUpdates.stderr);
    }
    const groupID = JSON.parse(channelUpdates.stdout).currentPage[0].group;
    const updates = await promisifiedExec(`eas update:view ${groupID} --json`);
    if (updates.stderr) {
        console.error(updates.stderr);
    }

    await uploadAndroidSourceMap(easBuild, JSON.parse(updates.stdout));
    await uploadIosSourceMap(easBuild, JSON.parse(updates.stdout));
});

program.parse();

Worked for us 🙌

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants