-
Notifications
You must be signed in to change notification settings - Fork 258
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
Enable repeatable package restores using a lock file #5602
Comments
It appears that the current specification document is incorrect regarding how version ranges work with direct dependencies. It says that given the following package reference:
That it would pick the highest version, 5.0.0. This is not what I observe. Instead, that version range would resolve to the lowest version, 4.0.0. Floating version numbers appear to be the only case where any sort of highest version logic is applied. I also don't see anything indicating that highest would be expected in any of the documentation I've found: https://docs.microsoft.com/en-us/nuget/consume-packages/dependency-resolution |
Thanks @bording for reporting the discrepancy. This was an oversight from my end. I have corrected the same in the spec.
|
What happens if the NuGet.config file is on one machine but not on another, or is changed after the lock file is create - does the lock file still take effect? |
IMO, sources definition should not matter for a lock file. Irrespective of which source the packages are coming from, finally it should be the same package that goes into the build. To make sure whether its the same package or not I am thinking about putting the hash of the package in the lock file. Open to other ideas. |
@anangaur Sorry, didn't explain myself very well :-) What happens in the following situation: -
What happens to the lock file? Does it still get used or is it discarded and deleted? |
@isaacabraham Haven't put much thought on it but I am leaning towards generating the file by default and not as an option. |
why not just have a command line option to create or consume a project wide Something like:
and later (say on a build server)
It would be up to the consumer to regenerate/edit the assets file and check it into source control and to configure their builds to use it. This would seem to allow the requested functionality with the minimum amount of changes.... |
Asset file is not just the restore graph but has multiple overloaded functionality and lot of contents irrelevant to a typical lock file. For example it contains all the warnings/errors applicable for the project restore. In addition to this, the assets file is not easy to understand or modify. (IMO even the lock file should not be manually edited). I have seen different assets file getting generated for the same dependencies (the lines get re-ordered) and hence it will be difficult to manage the merge conflicts. Assets file in the current form will not be able to handle floating versions. |
True, just having a |
I would really like to have this feature in the NuGet client. Are there any updates (or perhaps even a roadmap) you can share? |
This would be a great feature for nuget to support CI/CD workflows. Is there any ETA on when this feature will be available? |
@forki @isaacabraham Wanted to bring the conversation here :) The current proposal is having the lock file at project level with the intention to lock the transitive dependencies per project. However, I have heard the problems it could have at runtime and I am contemplating to bring it at solution level. Currently NuGet restore does a project level restore - may be that has to change if we want to bring the lock file to solution level? @jainaashish |
@anangaur hi :-) OK. I'll try to (briefly) outline some of the reasons that come to mind why I think locking dependencies at either project or solution level will be a mistake. I'm sure @forki will have his own thoughts as well.
Alternatively, consider the situation where you e.g. have two solutions, one for your "main" codebase and another for integration and unit tests (which I have seen before). Do you really want to maintain a separate dependency chain for both of them? What happens when they get out of sync?
In summaryAsk yourself this - how often in a repository do you explicitly want different versions of the same dependency? I suppose I would say this (because of my involvement with Paket) but decoupling yourself from projects and solutions will free you from all of these issues. Instead, consider pinning dependencies at the folder level (typically repository level). You then get consistency across all of your projects and solutions and scripts, because there's there's only one dependency graph across the whole repo. For those cases where you need to go "outside the box" and must have different dependency graphs within a repo, consider something like Paket's Groups feature, which allows you to explicitly have distinct dependency chains (with their own section in the lock file). However, this is the exception to the rule - it doesn't happen very often. Just my two cents - you may well feel differently, and it's entirely your choice how you proceed. Good luck! :-) |
I agree with @isaacabraham. I know of code bases for a single application split into multiple solutions with some of these solutions even overlapping, so locking dependencies neither at project level nor at solution level works in such scenarios. |
@isaacabraham Thanks for the detailed reply. I am fully in agreement in what you mentioned above. This is something required as part of the following: https://github.com/NuGet/Home/wiki/Manage-allowed-packages-for-a-solution-%28or-globally%29 This issue is primarily to lock down the transitive dependencies (at install time) so that restores are repeatable across space and time. I do see both of these workitems are related but I am trying to kind of segregate these out and attack one problem at a time. Right now the proposal is to have NuGet generate the lock file at the time of install at project level as that is how NuGet restore works but I have been hearing a lot of voices to make the lock file generated at solution level. From twitter and from Paket experience, I understand that's your recommendation too. |
@anangaur Hi. Sorry - but no, that's not my recommendation really. My comment just above states:
So I hope I'm clear here - working at either projects or solutions will not, in my opinion, provide a satisfactory solution that is either simple to understand, consistent and repeatable. Again, though, I'll repeat: That's my opinion. It's entirely up to you how you proceed. |
Sure. Thanks for the explanation. Will keep your recommendation in mind while I iterate over it. I will update the thread as we make progress. Appreciate your input here. |
my recommendation:
|
I want to pile on "please don't introduce any functionality at solution level". Single solution typically represents a very small part of a bigger product that wants to harmonize the dll versions. Solutions should remain a superficial "ide convenience" feature instead of getting critical new responsibilities. |
@springy76 My apologies. My earlier suggestion was misplaced. I guess, for now, you can try the deletion or what @jainaashish suggested. We will investigate the issue and get back. @springy76 , @Flavien Can you tell us more details like SDK versions (and repro steps)? |
EDIT: Damn I wish I'd have seen this issue sooner. First I saw of this was the blog post on Nuget.org. Its great you guys are so much more transparent about things but I have a real bone to pick with y'all on the Nuget team. Omg. Whats the point of checkin of package.json.lock if you're not going to use it by default! We need packages to be locked down at the time the developer picks a package via install or updates via update. Do you guys ever check out npm? They did this several years ago via It feels like the Nuget team is so opinionated about things that keep being proven wrong again and again. I've had my clashes with various members in the past about issues like this and I'm continually overruled then vindicated several months if not year or so later on issues. I realize Nuget has some significant challenges especially with the multitude of platforms and whatnot. But this particular feature is a no-brainer guys... Should be OPT-OUT if not desired and I can't imagine any scenario where that is legitimately the case. Now its baked in as OPT-IN so everybody keeps going forward slamming their heads into their desks while the Build server starts installing unwanted new versions of DLLs that are different from the developer's machines... Here's how its gonna go: |
And to be clear: package lock files should only be generated at INSTALL or UPDATE time. When a restore happens, and a package lock doesnt exist (solve issue of old libraries) then CREATE IT. If this happens on build server, nothing you can do about it. If this happens on DEV machine, it shows up as new file. (Except on TFS where you HAVE to remember to promote the thing... another id10tic feature) You should have to OPT-OUT of this behavior. Secondly I recommend, like Maybe theres more to it, I cant imagine it... thats 99% of developer intended workflow regarding a package manager in relation to the build/release phase and SHOULD utilize LOCKED package modes. You made this opt-in instead of opt-out so the build output of a lot of projects will continue to be nondeterministic as time moves on which is just silly. TL;DR the RESTORE should ALWAYS respect package.lock thats why it exists. INSTALL and UPDATE should always WRITE and UPDATE the dependency versions within packages.lock if needed, and any changes get exposed in the VCS checkin. If you didnt intend for that to happen... DONT CHECKIN THE PACKAGES.LOCK file! Very simple. You guys have made it mind numbingly irritating by now having to double check a csproj setting upon install/update/restore to even write the file, AND you make it so we have to now go into every build definition and double check that this feature is turned on. |
@ericnewton76 check out https://fsprojects.github.io/Paket/ - .NET has this for years. |
@ericnewton76 Thanks for your detailed feedback. Let me try to answer your queries (as I understand them) one by one and we can delve into specifics, as required. Why opt-in and and not have it opt-out? Why the presence of lock file is enough?We did not want to suddenly start producing a new file with an incremental release i.e. as part of 4.x. In addition, the lock file feature is not complete unless we solve the problem of centrally managing package versions and thereby having a central lock file per repo/solution. Once done, we will evaluate to make the lock file default. Btw, the presence of lock file is enough to opt in to this feature. The property
|
Thanks for the reply. Sorry if my tone seemed too adversarial. I can be passionate about this stuff and its hard to guard my words sometimes.
Granted, npm formally brought on the However, if you introduce this lock file in v4.8 then whats the difference really? It seems like MS in general is afraid to kick the major version up due to marketing concerns or something else instead of technology needs. I won't say thats what Nuget team does but it seems to be the norm. Nothing wrong with Nuget v10... LOL. Anybody that complains just doesnt understand how software is built then.
That's fine... that'll happen on the developer's machine and the RESTORE command should complain like a stuck pig. At least squeal with a warning message that says a new packagereference is found and should be installed properly to have a proper dependency graph analysis performed. And then go ahead and basically do an install. When Problem is: The goal is a deterministic build. Both of your current options listed don't solve that... they just add more configuration switches to underlying mechanisms that don't help you achieve a stable build. And when the feature releases formally, now you have this extra cruft that has to be supported ad-infinium to preserve that exact behavior when it might not be true later. Probably a difference of opinion here... you guys are trying to go for least disruptive change for something that will 100% make their lives better, but by not jumping in feet first, you're equivocating on a feature that is a must-have. In addition, did you try this out in-house first? Did you guys scratch their heads saying "omg! this would be bad for it to precisely match up my dependencies! and when it doesnt match, its notifying me that my hand edited package reference accidentally checked in due to TFS lunacy is warning me that something is awry!" I have a feeling it was the opposite. Please note I'm trying to be humorous here, to keep this deep subject in the realm of amusement. You have to honestly ask yourself, would a developer whos tested precise versions of packages for days, possibly weeks, on his own machine, be okay with an algorithm making decisions for him about inaccurate package versions by library developers that probably will introduce inadvertent breaking changes into his runtime when he presses that build button to release to production on a thursday night at 10pm?
|
This didn't get documented in the release notes for 4.9.0 because it was mistakenly in 5.0 milestone. For now, setting to 4.9.3 - will fix release notes in 4.9.0 when we ship release notes for 4.9.3 and then reset this back to 4.9.0 Will be closing this issue. Please spin off any follow up discussions in other issues. |
Wasn't the problem referenced above the same problem as this? |
are there plans for a |
@fowl2 Can you try
|
I'm still struggling with this error:
(happens with any package randomly) I'm using NuGet 5.0.0.6 and have cleared my caches and fallback folders numerous times. I am still getting this error on my CI build no matter what I try. Any ideas what's wrong? |
Can specify the exact steps? Or may be provide a repro? |
It would also be good to know the sources you are using. One of the reasons could be that the sources have different packages (with different SHA) and depending on which source was used to restore, you might see failures. |
Here is a repro: https://github.com/Flavien/nuget-lockfile-repro. I have generated the lock file by building the project on Visual Studio (Windows) 16.0.0.0 Preview 5.0. NuGet version is 5.0.0. When I clone this on my Ubuntu WSL and run
Here is
The only source I have on Visual Studio is: nuget.org (https://api.nuget.org/v3/index.json).
|
@anangaur - Yet it was OK to start breaking/normalizing version numbers in a minor release? |
There seem to be discrepancies across platforms or systems. I locked on Windows 10 and can restore fine on that same system. However, restoring on Arch Linux fails for Edit: solved by following #7921 (comment) |
@MarkKoz Just a heads up, the package Dotnet.ReproducibleBuilds.Isolated aims to configure these msbuild settings for you to avoid non-reproducibility issues. Among other things, it turns off that hidden nuget cache you ran into. |
Thanks @aaronla-ms. I'm glad MS is investing in solving this issue. I'll look into adding this to my projects. |
Discussions should happen on this issue. Please link other issues with similar asks to this one.
July 2018 - Announced feature
December 2018 - Blog
The text was updated successfully, but these errors were encountered: