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

Error on yarn install if the lockfile is out of date #453

Merged
merged 5 commits into from Jul 24, 2017

Conversation

jmorrell
Copy link
Contributor

This switches to using --frozen-lockfile for yarn installs, which will fail the build if yarn.lock does not match the requirements listed in package.json. Under our current setup Yarn will install the updated dependencies as if the lockfile doesn't exist in this case, which could lead to unexpected failures at runtime.

With this change it will fail the build and print out a helpful message in this case.

Example log and error message:

-----> Creating runtime environment
       
       NPM_CONFIG_LOGLEVEL=error
       NPM_CONFIG_PRODUCTION=true
       NODE_VERBOSE=false
       NODE_ENV=production
       NODE_MODULES_CACHE=true

-----> Installing binaries
       engines.node (package.json):  unspecified
       engines.npm (package.json):   unspecified (use default)
       engines.yarn (package.json):  unspecified (use default)
       
       Resolving node version 6.x via semver.io...
       Downloading and installing node 6.11.1...
       Using default npm version: 3.10.10
       Resolving yarn version (latest)...
       Downloading and installing yarn (0.28.1)...
       Installed yarn 0.28.1

-----> Restoring cache
       Skipping cache restore (not-found)

-----> Building dependencies
       Installing node modules (yarn.lock)
       yarn install v0.28.1
       [1/4] Resolving packages...
       error Your lockfile needs to be updated, but yarn was run with `--frozen-lockfile`.
       info Visit https://yarnpkg.com/en/docs/cli/install for documentation about this command.

-----> Build failed

 !     Outdated Yarn lockfile

       Your application contains a Yarn lockfile: yarn.lock which does not match
       the requirements in your package.json file. This can happen if you use
       npm to install or update a dependency instead of Yarn.

       Please run the following command in your application directory and check
       in the new yarn.lock file:

       $ yarn install
       $ git add yarn.lock
       $ git commit -m "Updated Yarn lockfile"
       $ git push heroku master
    
       https://kb.heroku.com/why-is-my-node-js-build-failing-because-of-an-outdated-yarn-lockfile

@jmorrell jmorrell requested a review from hone July 19, 2017 23:51
@jmorrell
Copy link
Contributor Author

Tests are currently failing because yarn fails on unknown command line flags, so I need to avoid passing in --frozen-lockfile for yarn versions older than X. Will fix.

@@ -59,12 +59,28 @@ log_build_scripts() {
fi
}

yarn_supports_frozen_lockfile() {
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@dzuelke Mind critiquing my bash here?

yarn_supports_frozen_lockfile() {
local yarn_version="$(yarn --version)"
# Yarn versions lower than 0.19 will crash if passed --frozen-lockfile
if [[ "$yarn_version" =~ ^0\.(16|17|18).*$ ]]; then
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

List of all the yarn versions we support: https://nodebin.herokai.com/v1/yarn/linux-x64.txt

Copy link
Contributor

@dzuelke dzuelke left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Bash functions can return exit codes like a normal program. So you can return 0 to indicate success, and any other code to indicate failure. Running if against this then works without [ or [[. You can also just use the true and false shorthands if they're the last statement, as the return code of a function will be its last statement. If you didn't need the mcount … call, the last statement could thus also just be [[ ! "$yarn_version" =~ ^0\.(16|17|18).*$ ]]

# Yarn versions lower than 0.19 will crash if passed --frozen-lockfile
if [[ "$yarn_version" =~ ^0\.(16|17|18).*$ ]]; then
mcount "yarn.doesnt-support-frozen-lockfile"
echo false
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use return 1, or just false, without echo

mcount "yarn.doesnt-support-frozen-lockfile"
echo false
else
echo true
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use return 0, or just true, without echo


echo "Installing node modules (yarn.lock)"
cd "$build_dir"
yarn install --pure-lockfile --ignore-engines 2>&1
if [ "$supports_frozen_lockfile" = true ]; then
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if yarn_supports_frozen_lockfile; then (and, generally, always use [[ with if if you require statements inside)

yarn_node_modules() {
local build_dir=${1:-}
local supports_frozen_lockfile=$(yarn_supports_frozen_lockfile)
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You don't need that one; see below

@jmorrell
Copy link
Contributor Author

If you didn't need the mcount … call, the last statement could thus also just be [[ ! "$yarn_version" =~ ^0.(16|17|18).*$ ]]

I see how I could simplify to that, but I like the clarity of the more verbose option. Thanks for the insights @dzuelke!

Copy link
Contributor

@hunterloftis hunterloftis left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me, just requested a tweak in the explanation text.

lib/failure.sh Outdated
echo ""
warn "Outdated Yarn lockfile

Your application contains a Yarn lockfile: yarn.lock which does not match
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Parentheses might fit the grammar here better than a colon:

Your application contains a Yarn lockfile; yarn.lock which does not match the requirements in your package.json file.

vs:

Your application contains a lockfile (yarn.lock) which does not match the dependencies in package.json.

@jmorrell
Copy link
Contributor Author

updated wording 👍 @hunterloftis

@jmorrell jmorrell merged commit c02a4b9 into master Jul 24, 2017
@jmorrell jmorrell deleted the yarn-lockfile-out-of-date branch July 24, 2017 19:49
@hone
Copy link
Member

hone commented Jul 24, 2017

Thanks for getting this change in! sorry for not reviewing it sooner.

@vlad-elagin
Copy link

Hello.
Can't get my app working with error listed by topic-starter. I tried to delete and re-create lockfile, but without success. Can you help me with this? If so, what information should I provide?

@hone
Copy link
Member

hone commented Aug 7, 2017

@vlad-elagin hi, can you provide your package.json and yarn.lock?

@vlad-elagin
Copy link

Thanks for response! Here they are.

yarn.zip

@vlad-elagin
Copy link

I've got it working, thanks.

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

Successfully merging this pull request may close these issues.

None yet

5 participants