-
Notifications
You must be signed in to change notification settings - Fork 24.4k
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
Validate that JS and Native code versions match for RN releases #15518
Conversation
@facebook-github-bot label Core Team Attention: @shergin Generated by 🚫 dangerJS |
|
I'm not sure I agree with this direction. It could be useful at development time, but we're actually trying to keep the JS compatible with older native code versions for as long as possible, and this would actually prevent that. |
@javache what is the mechanism you use to keep the JS compatible with the native code? Could we use that instead of semver? Also this code doesn't materially affect FB (or anyone else who runs from master since the compared version is always "master") in case that affects your thinking around this. |
True, since we don't use the release branch, this wouldn't necessarily affect us. I would still prefer not having an additional native module, so perhaps this can go in Internally, we're mainly looking at leveraging flow for typing native interfaces and end-to-end testing to ensure compatibility. |
@javache Sounds good, let's move this into PlatformConstants. Native -> Flow defs sounds useful, I think doing the version check will also catch a different class of issues caused by old packager processes, cached bundles, etc... |
8d857d0
to
9ff1f80
Compare
9ff1f80
to
04a9905
Compare
@ide What kind of API were you thinking of to customize that check? It might be a bit tricky since I'm not sure it's even possible to run code before the InitializeCore module. |
@ide Just tested and InitializeCore does get executed before the app index.js, so I don't see a way to customize this behavior at runtime. I'd also like to keep the check in InitializeCore since otherwise other random errors could happen before the version check. |
OK, that makes sense. This looks good to me then. @javache How does this look to you? |
31fb80e
to
2e69a0e
Compare
2e69a0e
to
77522b2
Compare
scripts/bump-oss-version.js
Outdated
exit(1); | ||
} | ||
|
||
// Generate version files to detect mismatches between JS and native. | ||
let [, major, minor, patch, prerelease] = version.match(/^(\d+)\.(\d+)\.(\d+)(?:-rc\.(\d+))?$/); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Prerelease should be a string (not number) that includes -beta.1
, etc... can you change the regex to this?
/^(\d+)\.(\d+)\.(\d+)(?:-(.+))?$/
Also for clearer error messages:
let match = version.match(...);
if (!match) {
echo(`You must pass a correctly formatted version; couldn't parse ${version}`);
exit(1);
}
import java.util.Map; | ||
|
||
public class ReactNativeVersion { | ||
public static final Map<String, Integer> VERSION = MapBuilder.of( |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
<String, @Nullable Object>
since the prerelease value may be a String
Libraries/Core/InitializeCore.js
Outdated
@@ -116,6 +116,24 @@ if (!global.__fbDisableExceptionsManager) { | |||
ErrorUtils.setGlobalHandler(handleError); | |||
} | |||
|
|||
const formatVersion = version => | |||
`${version.major}.${version.minor}.${version.patch}` + | |||
(version.prerelease !== null ? `-rc.${version.prerelease}` : ''); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Just concatenate the prerelease (instead of assuming -rc, see comments later in this review)
@ide Updated |
Waiting for CI to pass. |
@janicduplessis it looks like the Jest setup script needs to be updated (see CircleCI output). |
Updated, tests now pass locally, let's wait for CI again. Ended up just providing an explicit mock for the InitializeCore module since jest automock feature does run the module which is when the error happened. This also makes sure we don't have to deal with the version check during tests. |
Libraries/Core/InitializeCore.js
Outdated
|
||
const ReactNativeVersion = require('./ReactNativeVersion'); | ||
const nativeVersion = require('NativeModules').PlatformConstants.reactNativeVersion; | ||
if (ReactNativeVersion.version.major !== nativeVersion.major || |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
should we keep this behind the DEV flag?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@ide prefered not to, I don't really have a preference
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The main thing is to keep dev and prod similar, particularly around edge cases, error handling, initialization, cleanup. If we move this to a __DEV__
-only check, we should change this to a console.error call instead of throwing an error.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
i would rather let it continue in prod than spectacularly failing at startup. idk
CI failed again, probably need to tell Buck about the new Java file. |
Moved the file to the same package to avoid circular deps which buck doesn't support. |
Ok finally got CI passing :) |
This looks good to me. @facebook-github-bot shipit |
@ide has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
I tried to merge this pull request into the Facebook internal repo but some checks failed. To unblock yourself please check the following: Does this pull request pass all open source tests on GitHub? If not please fix those. Does the code still apply cleanly on top of GitHub master? If not can please rebase. In all other cases this means some internal test failed, for example a part of a fb app won't work with this pull request. I've added the Import Failed label to this pull request so it is easy for someone at fb to find the pull request and check what failed. If you don't see anyone comment in a few days feel free to comment mentioning one of the core contributors to the project so they get a notification. |
@hramos could you or someone else at fb look into why this failed to land? The OSS CI tests look good for it. |
* LICENSE file in the root directory of this source tree. An additional grant | ||
* of patent rights can be found in the PATENTS file in the same directory. | ||
* | ||
* @flow |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This PR is not importing due to the following error:
Flow check failed:
1 Flow error and 0 Flow warnings detected!
=====Flow error #0====
Error: scripts/versiontemplates/ReactNativeVersion.js line 15 col 11-11: Unexpected token {
@hramos has imported this pull request. If you are a Facebook employee, you can view this diff on Phabricator. |
Summary: Basic implementation of the proposal in #15271 Note that this should not affect facebook internally since they are not using OSS releases. Points to consider: - How strict should the version match be, right now I just match exact versions. - Wasn't able to use haste for ReactNativeVersion because I was getting duplicate module provider caused by the template file in scripts/versiontemplates. I tried adding the scripts folder to modulePathIgnorePatterns in package.json but that didn't help. - Redscreen vs. warning, I think warning is useless because if the app crashes you won't have time to see the warning. - Should the check and native modules be __DEV__ only? **Test plan** Tested that it works when version match and that it redscreens when versions don't before getting other errors on Android and iOS. Closes #15518 Differential Revision: D5813551 Pulled By: hramos fbshipit-source-id: 901757e25724b0f22bf39de172b56309d0dd5a95
Basic implementation of the proposal in #15271
Note that this should not affect facebook internally since they are not using OSS releases.
Points to consider:
Test plan
Tested that it works when version match and that it redscreens when versions don't before getting other errors on Android and iOS.