Abstract
There have been situations in recent times when a new release of a 3rd party tool or library has broken our builds, without any new commits on status-im. This means it is very difficult to go back and rebuild a version from an old commit, if that 3rd party tool or library introduces a different behavior, or is altogether incompatible. To combat this, we must ensure that we lock down the versions of the tools and libraries we depend upon.
What follows is the result of an audit done across status-react to raise potential issues and suggest remedy actions. Please comment if you have other suggestions or have come across other issues that haven’t been documented here.
Results
Unlocked git dependencies
Problem:
Even if these repos are maintained by Status, we should still lock versions down, since any future updates in those repos will make builds of older versions of the consumer repo impossible to reproduce
Found instances:
- snorenotify (link to CMakeLists.txt)
- react-native-desktop (link to Dockerfile)
Suggested actions:
Use specific commit SHAs/tags to reference the repos.
Unlocked npm dependencies
Problem:
We fork some repositories in order to customize some aspects, but most of the times we don’t have the discipline to create an official release and we add the reference to packages.json
without the reference to a tag/release. That means that as soon as someone pushes a new commit to that dependency repo, it will be impossible to build the exact same executable in the future when building a past commit
Found instances:
mobile/package.json.orig
and desktop/package.json.orig
Suggested actions:
Create releases for each of the forked repos and use that tag in package.json.orig
Tools which are installed through brew/apt without locked-down versions
Problem:
This isn’t necessarily a problem per-se in every case, but we should be aware of it and acknowledge that we’re accepting the risks implicitly if we don’t lock things down
Found instances (non-exhaustive list):
- Maven (link to installers.sh)
- Protobuf (link to status-go install_deps.sh)
- react-native-cli (link to installers.sh)
- Node, when nvm is not installed (link to installers.sh)
- MacOS-only:
- Clojure CLI (link to installers.sh)
- Android SDK (link to installers.sh)
- Linux-only:
- lein (link to installers.sh)
- g++ (link to installers.sh)
- python-dev (link to installers.sh)
- libssl-dev (link to installers.sh)
- build-essential (link to installers.sh)
- NSIS (link to installers.sh)
- Docker-only:
- lein (Linux, Windows)
- react-native-cli (link to Dockerfile)
- react-native-desktop (Linux, Windows)
Suggested actions:
- Lock down the versions for tools which we know must be locked down (e.g. Node)
- Discuss which others we should strive to lock down (all?, only a subset which is more bound to present problems?) → Could be interesting to have a text file serve as a single source of truth regarding the tool versions used, which would be used in scripts to retrieve the sanctioned versions.
Handling of pre-existing versions of tools
Problem:
Some tools are installed with a specific version indication, but only if the tool isn’t already present in the user’s system, so it may happen that the user already has a version which doesn’t match the one we recommend/expect (e.g. very old version or a newer broken version).
Found instances:
Examples: conan, lein, watchman, node (when nvm not installed), Ruby, Clojure CLI.
Suggested actions:
- Standardize on a single method that checks not only for the existence of a tool, but that it matches a sanctioned version.
- Alert the user if a tool is not the expected version and explicitly ask for his approval to ignore the warning.
- In the specific case of yarn, we might want to look into the yarn policies command to enforce a single yarn version without imposing a version globally on the user’s system.
yarn.lock versions don’t match package.json
Problem:
yarn check
is currently reporting some issues that prevent us from using the command in a CI environment to detect future problems.
Found instances:
$ yarn check
yarn check v1.12.3
warning Pattern ["bignumber.js@github:status-im/bignumber.js#master"] is trying to unpack in the same destination "/home/pedro/.cache/yarn/v4/npm-bignumber-js-4.0.2-cc066a0a3d6bfe0c436c9957f4ea8344bf963c89/node_modules/bignumber.js" as pattern ["bignumber.js@https://github.com/status-im/bignumber.js.git"]. This could result in non-deterministic behavior, skipping.
info [email protected]: The platform "linux" is incompatible with this module.
info "[email protected]" is an optional dependency and failed compatibility check. Excluding it from installation.
error "react-native-firebase#react-native@>= 0.57.0-rc.3" doesn't satisfy found match of "[email protected]"
error "react-native-fs#react-native@^0.51.0" doesn't satisfy found match of "[email protected]"
error "react-native-keychain" is wrong version: expected "3.0.0-rc.3", got "3.0.0"
error Found 3 errors.
For the desktop variant, there are 7 warnings and 36 errors, which deserve some attention. Most of the errors could be fixed by updating yarn.lock to point to babel/[email protected]
.
Suggested actions:
- Fix warning by using the same URL for
bignumber
package on both mobile and desktop environments; - Fix error for
react-native-keychain
by creating our own release and updating version string inyarn.lock
; - Look into fixing
react-native
errors, sincereact-native-firebase
wants >=0.57.0-rc.3 andreact-native-fs
wants ^0.51.0 (the latest version ofreact-native-fs
wants ^0.57.0, so we’d be OK if we were on RN 0.57). We can do this if we’re OK with only upgrading react-native-* libraries if they are compatible with the RN version we currently use (or be willing to upgrade otherwise); - Finally, run this command on the CI build and use it to fail PR builds which generate warnings or errors.
Other notes
In install_node_via_package_manager we’re configuring the source with https://deb.nodesource.com/setup_9.x on Linux, should be 10.x.