question-mark
Stuck on an issue?

Lightrun Answers was designed to reduce the constant googling that comes with debugging 3rd party libraries. It collects links to all the places you might be looking at while hunting down a tough bug.

And, if you’re still stuck at the end, we’re happy to hop on a call to see how we can help out.

[Question] How to set up sourcemaps and accurate version with Codepush without deprecated setDist and setRelease functions?

See original GitHub issue

This is basically a bug report on the insufficiency of the Manual Codepush setup setup doc.

I tried to fill in the gaps from this comment: https://github.com/getsentry/sentry-react-native/issues/79#issuecomment-573288459

The solution proposed in the comment uses Sentry.setRelease function which is deprecated (along with setDist), while the docs suggests not waiting for codePush.getUpdateMetadata(), because Sentry.init might not be called before any related crash might happen.

I don’t have question over how to upload sourcemaps, or create a release, rather what is the source of truth I need to use and is there a preferred order or not (from the docs the only thing clear that the codePush.getUpdateMetadata() solution is not).

As per my understanding, this is the broken solution. Feel free if I misunderstood any part how things work in either react-native or Codepush or Sentry.

The goal: having one source of truth version following semver

I wish to use one semver following version to identify my application version (e.g. 1.2.3) and upload its sourcemaps to Sentry. I use Codepush for minor updates.

After every Codepush update I would like to see Sentry.init being called with this version specified above.

Solution 1: using version from package.json

In this case I bump the version number in package.json. Let’s say current version is 1.2.2, I manually bump the version to 1.2.3.

The flow in this case:

  • bump version number from 1.2.2 in package.json to 1.2.3
  • run appcenter codepush react-release...
  • run sentry-cli releases...
  • and in the application itself
    • import version from '../package.json'
    • call Sentry.init({ release: version })
  • and deployed applications update themselves through codepush updates

The problem is that version from package.json is not updated! (see issue: Version from package.json not updated)

This way even though the right version has the right sourcemap the application itself tells otherwise.

Solution 2: hacking version into description of codepush update

In this scenario I pass version from package.json to the description of codepush release:

appcenter codepush release-react --app <my-org/my-app> \
    --description "Version: [<1.2.3>]; my random release information"  # dinamically set it from package.json
    --sourcemap-output
# ...

The flow in this case:

  • bump version number from 1.2.2 in package.json to 1.2.3
  • run appcenter codepush react-release... with description having the version
  • run sentry-cli releases...
  • and in the application itself
    • call codePush.getUpdateMetadata()
    • if localPackage exists unpack version from result through hacky string regexing
    • if localPackage does not exist import version from '../package.json'
    • call Sentry.init({ release: version })
  • and deployed applications update themselves through codepush updates

At least this solution updates version dynamically.

The problem is using description is hacky. Any new colleague might see description and rewrite it, maybe omitting version altogether, or deciding that [] is ugly not knowing that the regex was looking for it…

Solution 3: creating a random .json file somewhere which contains the version

In this scenario I create a version.json file lying around somewhere, manually bump it for every release and gets updated with every codepush release.

The flow in this case:

  • bump version number from 1.2.2 in version.json to 1.2.3
  • run appcenter codepush react-release...
  • run sentry-cli releases... with release name my-app@1.2.3
  • and in the application itself
    • import version from '../version.json'
    • call Sentry.init({ release: 'my-app@' + version })
  • and deployed applications update themselves through codepush updates

The problem with this scenario that version in package.json and version in version.json might go inconsistent (can you delete version from package.json?). Again, new colleague comes, see the duplication and/or inconsistency, decides to refactor by dropping the duplication and things go 💥 .

Solution 4: using only codepush label

This is tricky again. First I will lose the relevant semver version about my app. Second this solution again only works with hope until the first update.

The flow in this case:

  • have a version.json containing latest codepushLabel: { "latestCodepushLabel": "v13" }
  • manually bump version number from "v13" in version.json to "v14" and hope this will coincide with the next label
  • run appcenter codepush react-release...
  • get latest codepushLabel from appcenter by running appcenter codepush deployment list --app <org/project> --output json
  • run sentry-cli releases... with release name my-app@<latestCodepushLabel>
  • and in the application itself
    • call codePush.getUpdateMetadata()
    • if localPackage exists unpack latestCodepushLabel from result
    • if localPackage does not exist import latestCodepushLabel from '../version.json'
    • call Sentry.init({ release: 'my-app@' + latestCodepushLabel })
  • the deployed applications update themselves through codepush updates and we update continuously the release property

Problems

  • at first start we can’t rely on codePush.getUpdateMetadata(), therefore we need to bundle the next version label into the codepush even before the version label itself exists
  • we lose semver version completely as the release string will be something like my-app@v14; so for identifying the proper version, I need to go digging

Solution 5: use version.json and codepushLabel

This results in the fabled release string: my-app@1.2.3+codepush:v14.

In this case we have both of the disadvantages of Solution 3 and Solution 4: semver version comes from version.json while codepushLabel is either coming from version.json or from the latest package, while I need to guess the next codepushLabel version and bundle it into version.json for apps that were not yet updated through codepush.

The questions

  • Which solution is the preferred one by the team?
  • Is there any way to avoid codePush.getUpdateMetadata() before I call Sentry.init if I specify codepush version number?

The reason is that since calling codepush is async code, I might miss crashes that happen before the code completes. For instance if there is a fatal flaw in codepush.getUpdateMetadata function, Sentry.init will never run and I would never get a report.

SDK:

  • @sentry/react-native

SDK version: 2.4.2

react-native version: 0.63.2

Are you using Expo?

  • Yes
  • No

Are you using sentry.io or on-premise?

  • sentry.io (SaaS)
  • on-premise

Issue Analytics

  • State:closed
  • Created 2 years ago
  • Comments:15 (6 by maintainers)

github_iconTop GitHub Comments

3reactions
latobiborcommented, May 13, 2021

@jennmueng Yes, after all this I would recommend the following:

Docs that I would change

The entire part between CodePush title and Making releases. However this part needs a lot of clarification on “why do you need to use codePush.getUpdateMetadata”.

If you need to use codePush.getUpdateMetadata, you will have to wait to initialize the Sentry SDK until the Promise is resolved.

My version would be

Releases are tracked by matching both the release label and the dist label. These two must be set together. Here you can have several strategies:

1. Use version from package.json

In this case we ignore the version label from CodePush and solely use the version property of package.json (or a custom version file).

Your code would look largely like this:

import packageJson from '../package.json';

Sentry.init({
    dsn: '...',
    release: `${packageJson.name}@${packageJson.version}`,
    dist: packageJson.version,
});

2. Use version from package.json and version label from CodePush

In this case we recommend the following format for release property: ${BUNDLE_ID}@${APP_VERSION}+codepush:${DIST}.

To accurately obtain the version label (named here as DIST) you have to asynchronously obtain it using codePush.getUpdateMetadata(). This solution delays initialization of Sentry, so be cautious that you might lose accurate information on crashes that happen in this time.

import packageJson from '../package.json';
import currentCodePushLabel from '../my-first-codepush-version.json';

async initSentry() {
 const update = await codePush.getUpdateMetadata();

 // before the first update `currentCodePushLabel()` will return null, so you need to set this manually
 const dist =  update ? update.label : currentCodePushLabel;
 Sentry.init({
      // ...
      release: `${packageJson.name}@${packageJson.version}+codepush:${dist}`,
      dist: dist
    });
  }
});

3. Totally custom values

In this case just make sure that both release and dist properties are updated and dist accurately represents the code running currently on the device.

1reaction
latobiborcommented, May 7, 2021

@jennmueng , we have checked the package.json solution and it really is getting updated, so we have known an old issue, thanks for that.

We are currently ironing out this solution, that package.json is the source of truth and we ignore the Codepush versionLabel entirely. I am on sick leave though, so probably I will update this issue on Monday, Tuesday most likely. Thanks for your patience.

Read more comments on GitHub >

github_iconTop Results From Across the Web

CodePush for React Native | Sentry Documentation
Learn about using CodePush with our React Native SDK. ... your codebase and match the version on the source maps exactly, or they...
Read more >
getsentry - Bountysource
[Question] How to set up sourcemaps and accurate version with Codepush without deprecated setDist and setRelease functions? $ 0.
Read more >
Sentry React-Native with CodePush not using source maps
Our suggestion is to store them in an app.json, or you can just use the package.json. These values need to be unique to...
Read more >
React Native Client SDK · CodePush - Microsoft Open Source
Plugin Configuration (iOS)​​ Find the following line of code, which loads your JS Bundle from the app binary for production releases: jsCodeLocation =...
Read more >
React Native SDK with CodePush API Reference
If you're manually checking for and installing updates (that isn't using the sync method ... Wrapper function codePush(rootComponent: React.
Read more >

github_iconTop Related Medium Post

No results found

github_iconTop Related StackOverflow Question

No results found

github_iconTroubleshoot Live Code

Lightrun enables developers to add logs, metrics and snapshots to live code - no restarts or redeploys required.
Start Free

github_iconTop Related Reddit Thread

No results found

github_iconTop Related Hackernoon Post

No results found

github_iconTop Related Tweet

No results found

github_iconTop Related Dev.to Post

No results found

github_iconTop Related Hashnode Post

No results found