githubpackage.jsonpackage-lock.jsongreenkeeperdependabot

dependabot only updates lock file


We've recently switched from greenkeeper to dependabot for our dependencies checks and we noticed that dependabot is opening PRs changing only package-lock.json leaving package.json as it was.

On the other hand, greenkeeper, was committing changes to both files.

What is going on? Is it normal or we missed something in the settings?


Solution

  • This is a very late reply. We had this working in production for a long time now, but I see there's still interest prompting me that maybe people need some help. So, here it is:

    When using GitHub dependabot (not dependabot-preview, although the conf file might be the same, actually):

    It will look something like this (e.g. npm):

    version: 2
    updates:
      - package-ecosystem: "npm"
        directory: "/"
        schedule:
          interval: "daily"
        # Always increase the version requirement
        # to match the new version.
        versioning-strategy: increase
    

    That's it. Now, package.json and package-lock.json are both written to with a version increase.


    Here's the expanded logic behind it. package.json specifies "permanent dependency constraints" on the apps and libraries, while package-lock.json tracks a particular set of exact versions that meet all those constraints, to avoid unnecessary variation. A frequently used constraint type in package.json might be a "caret range" and look like this: ^1.2.3. The caret character is what is making it a range, rather than an exact version specification. Apart from allowing exact versions "1.2.3", it also allows "1.2.9" or "1.4.1", but not "2.0.6"; dependabot can often meet all the caret (and other) ranges in your package.json, while doing the necessary upgrades, without having to change any of these rather liberal constraints. Now, the default versioning-strategy for packages that are considered libraries rather than apps would be widen, i.e., to widen the range as necessary.

    Continuing the previous example, if dependabot wants to upgrade a library specified through a caret range as ^1.2.3 (or not constrained at all) from "1.2.3" to "1.4.1", dependabot can leave package.json alone, because "1.4.1" is already allowed by ^1.2.3. However, if it is necessary to make a major upgrade to "2.0.6", then the caret range has to be made wider. It would probably end up replaced by something like >=1.2.3 <=2.0.6 in package.json. If your package.json is very thin (few constraints, liberal constraints), dependabot, when using the default versioning strategy, rarely has to update package.json at all.

    But if you change your npm versioning strategy to increase, dependabot will tend to narrow down your caret ranges by increasing their minimums. Instead of ^1.2.3 which stands for >=1.2.3 <2.0.0-0, you could get ^1.4.1 which stands for >=1.4.1 <2.0.0-0 in your package.json.

    Apart from the widen (which really stands for "widen if necessary"), and increase (which kind of stands for "always narrow down so as to exclude older versions than our immediate goal"), there's also a value of increase-if-necessary which allows increasing, but only if it is necessary to meet the upgrade goals. If your package.json is very thin (few constraints, liberal constraints), you might not see much difference between widen and increase-if-necessary because dependabot will generally not judge it necessary to interfere with your required ranges.

    The lesson for some of us is that we should read up on the package.json syntax possibilities to understand how liberal or specific our existing dependency requirements are, and only then we want to judge dependabot's strategy to their updates, and possibly switch to a different strategy.