Enable repeatable package restores using a lock file

With PackageReference, NuGet always tries to produce the same closure of package dependencies if the input bundle reference list has not changed. Still, in that location are a few scenarios where it may not be able to do then. While these cases are express, nosotros received multiple requests to completely lock down the total packet dependency graph for projects to produce repeatable restores (builds). We have been working on your feedback, iterating quite a few times, on the approach and design over the past few months. Nosotros are happy to announce that we accept at present introduced the ability to lock your project's package dependency graph via a lock file – packages.lock.json. With this characteristic, NuGet uses the lock file to restore packages for PackageReference based projects. This file should be checked into your source code repository. If present during restore, and if the input package references does non change for a given projection, NuGet now uses the lock file to determine the dependencies instead of re-evaluating the package graph. Depending on your scenario, you lot can configure NuGet to either overwrite the lock file (default) or to fail the restore operation whenever the package graph changes.

Which versions of NuGet support restore with lock file?

The lock file functionality is available with the following NuGet distributions:

  • NuGet.exe version4.nine and above.
  • Visual Studio 2017 version15.9 and above.
  • .Cyberspace SDK version2.1.500 and higher up.

Why use a lock file?

At that place are a few cases where NuGet may not exist able to get the same package graph with every restore across machines. Most of these cases happen when consumers or repositories do not follow NuGet all-time practices. For example:

  1. nuget.config mismatch: This may atomic number 82 to an inconsistent set of package repositories (or sources) beyond restoresouth. Based on the packages' version availability on these repositories, NuGet may end up resolving to different versions of the packages upon restore.

  2. Intermediate versions: A missing version of the package, matching PackageReference version requirements, is published: * Day one: If you lot specified <PackageReference Include="My.Sample.Lib" Version="4.0.0"/> only the versions available on the NuGet repositories were 4.1.0, 4.2.0 and 4.3.0, NuGet resolves to four.i.0 as information technology the nearest minimum version. * Day 2: Version 4.0.0 gets published. NuGet now restores version 4.0.0 as it is an exact friction match.

  3. Package deletion: Though nuget.org does not allow parcel deletions, non all bundle repositories have this constraint. Deletion of a bundle version results in NuGet finding the all-time match when it cannot resolve to the deleted version.

  4. Floating versions: When you use floating versions like <PackageReference Include="My.Sample.Lib" Version="4.*"/>, you lot might get different versions after new versions are bachelor. While the intention here is to float to the latest version on every restore of packages, there are scenarios where users require the graph to be locked to a sure latest version and float to a afterward version, if bachelor, just upon an explicit gesture.

  5. Package content mismatch: If the same package (id and version) is present with different content across repositories, and then NuGet cannot ensure the same bundle (with the same content hash) gets resolved every time. It likewise does not warn/error out in such cases. Using the lock file will help you lot in resolving to the same versions ever. External factors would non affect your package graph. In addition, if the lock file changes anytime, you have the power to find what exactly changed by doing a unequal with the previous version. This is particularly helpful when a transitive bundle version, buried deep into the full bundle graph, changes because you brought in a new directly dependency.

How to enable the lock file?

To enable the apply of lock file with NuGet, set the MSBuild property RestorePackagesWithLockFile in your project file:

<PropertyGroup>     <RestorePackagesWithLockFile>true</RestorePackagesWithLockFile> </PropertyGroup>

If this property is prepare, NuGet restore volition generate a lock file – packages.lock.json file at the projection root directory. image

Note:

  • You must commit/check-in this file in the source code repository and so that it is always available for restore.
  • The lock file is a tool (NuGet) generated file and should never be manually edited.
  • Lock file should not be put within a bundle. It does not take whatsoever significance within a package and volition never be used by NuGet.

How does NuGet apply the lock file?

NuGet does a quick bank check to see if there were whatever changes in the package dependencies as mentioned in the project file (or dependent projects' files) and if there were no changes, information technology just restores the packages mentioned in the lock file without re-evaluating the full package graph. If NuGet detects a change in the defined dependencies equally enumerated in the project file(s), it re-evaluates the package graph and updates the lock file to reflect the new bundle graph applicable for the project. This is the default mode and is useful when yous are in a development environs actively modifying your packet and project dependencies. Y'all tin, however, at any point, diff against the previous version of the lock file, if modified, to know the exact dependency changes happening to the package graph. For

Continuous Integration (CI/CD) and other build scenarios, where you would always desire the same repeatable restore, you should use the locked mode. You tin can become into the locked mode by setting the MSBuild property RestoreLockedMode to truthful:

          <PropertyGroup>        <RestoreLockedMode Condition=<"'$(ContinuousIntegrationBuild)' == 'true'">true</RestoreLockedMode> </PropertyGroup>        

Note: The in a higher place instance assumes you take a MSBuild property ContinuousIntegrationBuild that is set to truthful for CI/CD builds. Alternatively, for CI/CD builds, you tin can utilise the post-obit command line options to enable locked style: For dotnet.exe, run:

          dotnet.exe restore --locked-style                  

For msbuild.exe, run:

          msbuild.exe /t:restore /p:RestoreLockedMode=true                  

If locked mode is set, restore will either get the exact packages as listed in the lock file or fail if it cannot. For example, if you updated the defined packet dependencies for the project after lock file was created or due to any of the reasons mentioned in this post.

SHA validation

In add-on to locking the bundle dependencies graph, NuGet likewise persists the content hash of all the packages in the lock file. During restore, information technology verifies that the content hashes lucifer between the lock file and bodily restored packages. In case of discrepancy, NuGet restore throws an error. This prevents whatsoever inadvertent utilise of packages with same ID and version but with different content (package content mismatch).

What adjacent?

packages.config

Currently, the lock file feature is only limited to PackageReference based projects. However, the full parcel closure is already listed in the packages.config file and the only piece missing is content hash of the packages restored. Nosotros understand this is an important validation and hence we are working on a similar characteristic for packages.config. The data in the lock file volition have a lot of repetitive contents as in the packages.config file but we plan to continue a consequent lock file experience, as with PackageReference. Yous tin can runway the progress of this characteristic, here.

Solution or repo lock file

Nosotros believe this characteristic goes a long style towards addressing the repeatable restore business organisation that many of you had. Still, nosotros are aware that managing multiple project lock files for a huge solution or a repo can be daunting. We have started to think most providing meliorate and easier mode to manage bundle dependencies centrally i.due east. at a solution or fifty-fifty a repo level – and thereby providing a cardinal lock file. Yous can observe our early thoughts in the spec: Centrally managing NuGet package versions. We would love to get your early feedback so that we can steer information technology towards the best experience possible.

We want to hear your feedback!

Please provide whatsoever feedback on this feature by commenting on this GitHub effect. If you accept any other question, comment or feedback you lot can attain out to me at anangaur@microsoft.com or tag @nuget in your tweets. You can ever create a new issue on our Github repository to starting time a new discussion or report a bug. To keep yourself updated on all planned NuGet features/experiences, do subscribe to NuGet/Announcements repo. We actively seek participation for all new features and we announce these features on this repo every bit they get ready for the customs review.