4

EAS Update + Sentry Source Maps

 11 months ago
source link: https://gist.github.com/nandorojo/8371475fe9912cb6b8d4f326664f1fc6
Go to the source link to view the article. You can view the picture content, updated content and better typesetting reading experience. If the link is broken, please click the button below to view the snapshot at that time.
neoserver,ios ssh client
EAS Update + Sentry Source Maps

EAS Update + Sentry Sourcemap upload

  1. Copy the TS file into your app. I put it in scripts/eas-update.ts
  2. Call the script with npx ts-node scripts/eas-update.ts <eas-script-here>
npx ts-node scripts/eas-update.ts npx eas-cli@latest update -p ios

You should provide the following env variables too:

  • EAS_UPDATE_MESSAGE
  • EAS_UPDATE_BRANCH
EAS_UPDATE_MESSAGE="works!" EAS_UPDATE_BRANCH=staging npx ts-node scripts/eas-update.ts npx eas-cli@latest update -p ios

All set. Be sure to call this script from the root of your Expo app.

For instance, you might add the following to your package.json's scripts:

{
  "scripts": {
    "eas-update": "npx ts-node scripts/eas-update.ts npx eas-cli@latest update -p ios"
  }
}

If you do that, just be sure to set EAS_UPDATE_MESSAGE and EAS_UPDATE_BRANCH when calling yarn eas-update.

Context

Meant to solve this issue: expo/sentry-expo#253

Tested with SDK 48 and it's working for me.

Do you fill in release in Sentry.init? Could you share your whole options object? I cant't get it working

@nandorojo I try above solution but source maps was not properly upload.

image

Amazing work! That did the job for me, but for some reason, file paths were including the entire system path, not just the relative project path, so I had to add this part in line 98:

    // Add this function to modify the source map file paths
    const modifySourceMapPaths = (sourceMapPath: string) => {
      const sourceMap = JSON.parse(fs.readFileSync(path.resolve(appDir, `dist/bundles/${sourceMapPath}`), "utf8"));

      sourceMap.sources = sourceMap.sources.map((filePath: string) => {
        return path.relative(appDir, filePath);
      });

      fs.writeFileSync(path.resolve(appDir, `dist/bundles/${sourceMapPath}`), JSON.stringify(sourceMap));
    };

    // Call the function for each source map
    if (iosMap) modifySourceMapPaths(iosMap);
    if (androidMap) modifySourceMapPaths(androidMap);

Author

FYI: if you use hermes, sentry may say the source map is 0 bytes.

@matheuscouto weird. are you on windows?

Author

For Sentry.init, I just use the dsn.

I wish Expo had a real integration for this. It’s so annoying haha

Definitely seems something that could be already built-in hahaha

I edited some things because i use remote version and had to use javascript because ts-node wasn't compiling due to strict rules in my project.

Still seems like Sentry is not catching the dist on update

// ... same code ...

  const versionCommand = "npx";

  const versionArgs = ["eas-cli@latest", "build:version:get", "-p", "all"];

  const getRemoteVersions = async () => {
    try {
      const getRemoteVersionsCmd = spawnAsync(versionCommand, versionArgs, {
        stdio: ["inherit", "pipe", "pipe"],
        env: process.env,
        cwd: process.cwd(),
      });
      const {
        child: { stdout, stderr },
      } = getRemoteVersionsCmd;

      if (!(stdout && stderr)) {
        throw new Error("Failed to spawn eas-cli");
      }
      let output = [];
      console.log();
      console.log(
        chalk.green("[eas-update-sentry] Running the follwing command:"),
      );
      console.log(versionCommand, versionArgs.join(" "));
      console.log();

      stdout.on("data", (data) => {
        const stringData = data.toString("utf8");
        console.log(chalk.green("[eas-update-sentry]"), stringData);
        output = [
          ...output,
          stringData
            .split("\n")
            .map((s) => s.trim())
            .at(0),
        ];
      });
      await getRemoteVersionsCmd;

      const versions = output.reduce((acc, curr) => {
        const values = curr.split(" - ");
        if (values[0] === "Android versionCode") {
          acc.android = values[1];
        }
        if (values[0] === "iOS buildNumber") {
          acc.ios = values[1];
        }
        return acc;
      }, {});

      return versions;
    } catch (err) {
      throw new Error("Failed to fetch remote versions");
      process.exit();
    }
  };

  // ... same code .. 

    const buildNumber = await getRemoteVersions();

    await Promise.all([
      uploadIosSourceMap(buildNumber.ios),
      uploadAndroidSourceMap(buildNumber.android),
    ]);
  } catch (error) {
    process.exit();
  }
};

run().then((r) => {
  console.log(chalk.yellow("Done!"));
});

Author

@elevyg have you confirmed that your script is right? a lot of the logic looks very different than mine so i can’t say that it looks right. i would log and confirm that you’re getting the correct values / files as expected and sending them to sentry.

for example, your output might only be adding the first line by using .at(0)? not sure.

Hey @nandorojo, tbh is not working. Sentry is not recognizing the bundle.

But I just run the code and the output that has the .at(0) returned:
[OUTPUT] [ 'Android versionCode - 33', 'iOS buildNumber - 46' ].
So it's working as I expect that part of the code.

Seems like I have an error in the Sentry.init(). I'm waiting until I upgrade to Expo 49 to invest time on resolving this. Looks like Sentry has a major update that might solve the issue (?).

I tried this... But sentry not showing the Stack Trace correctly.. What's wrong? Does this work for you @nandorojo ?

image

image

Author

I think SDK 49 had breaking changes for the output of the dist folder and we need to change it accordingly. Expo needs to fix this themselves ASAP, it’s really a terrible experience

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment


About Joyk


Aggregate valuable and interesting links.
Joyk means Joy of geeK