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

[PackageReference] Centrally manage NuGet package versions for a solution or a repo #6764

Closed
anangaur opened this issue Apr 2, 2018 · 186 comments

Comments

@anangaur
Copy link
Member

anangaur commented Apr 2, 2018

PackageReference enhancements are summarized as part of this Epic issue: #6763

@bording
Copy link

bording commented Apr 3, 2018

@anangaur Have you seen https://github.com/Microsoft/MSBuildSdks/tree/master/src/CentralPackageVersions? This seems like it enables the kind of control this requirement is talking about.

@anangaur
Copy link
Member Author

anangaur commented Apr 3, 2018

@bording true that. Thanks.
@jeffkl @jainaashish we should sync up on this

@jainaashish
Copy link
Contributor

pretty neat, just wondering how does it work out with VS, if it all it does?

@anangaur
Copy link
Member Author

anangaur commented Apr 3, 2018

Lets see how can we make this mainstream in NuGet and if satisfies all the requirements.

@terrajobst
Copy link

terrajobst commented Apr 3, 2018

Do we have a strawman for this, design-wise? I'm not sure where that information would be when this is supported across repo boundaries (as the title suggest we do). At that point, this looks like a feature of the feed. It's almost like we'd like to have snapshotted feeds at that point.

@anangaur
Copy link
Member Author

anangaur commented Apr 3, 2018

@terrajobst No designs as such. My current thinking right now is to be able to define it per solution level in a file. And sometimes instead of defining it in the file, it could be imported from some global file present anywhere accessible by NuGet/MSBuild.

The purpose of keeping the term repo is to help not constrain anything for a 'solution' level. There would be some cases where an app is distributed across solutions in a repo.

I agree that if this file starts being a list all versions of packages allowed across a team/product - its becomes similar to just being a curated feed/repository.

@terrajobst
Copy link

If we had better tooling for maintaining/populating feeds, creating snapshotted feeds is probably the most logical model. And the file that people need to check in is a nuget.config with the proper feed :-)

@anangaur anangaur changed the title PackageReference - Enable allowed packages/versions across solution/repo/app PackageReference] Centrally manage NuGet package versions for a solution or a repo May 4, 2018
@anangaur anangaur changed the title PackageReference] Centrally manage NuGet package versions for a solution or a repo [PackageReference] Centrally manage NuGet package versions for a solution or a repo May 4, 2018
@PatoBeltran PatoBeltran mentioned this issue Nov 28, 2018
@tebeco
Copy link

tebeco commented Dec 31, 2019

Hello @anangaur @nkolev92

As i changed computer and try to find the docs for Directory.Packages.props i found both :

is the Dup' intended ?

Also i spotted this in the Wiki page :
(Sorry the zoom)
image

but i have no idea where to submit an issue/PR for the Wiki part

@nkolev92
Copy link
Member

As i changed computer and try to find the docs for Directory.Packages.props i found both :

It is expected. This is tracking an implementation with similar functionality as the SDK you linked.

Also i spotted this in the Wiki page :

I edited the wiki to point back to this issue because that spec is just a more elaborate version of the one linked in this issue. :)
Lots of people came across the spec you linked but could never figure out the right issue back.

@tebeco
Copy link

tebeco commented Dec 31, 2019

not sure i understand the wiki part of your comment.
Is it normal to contains twice "github.com" and so that when you click, you are redirected to the wiki home instead of the issue ?

@nkolev92
Copy link
Member

oh, I totally missed that. my bad :)
Fixed now :)

@npehrsson
Copy link

Any ETA for this?

@ds1709
Copy link

ds1709 commented Feb 17, 2020

Maybe it will be usefull. I have project with two depencies, PackageA and PackageB. They in turn depends (transitive) from Newtonsoft.Json 8.0.1 and Newtonsoft.Json 9.0.1. Because of this, from build to build I have different version of Newtonsoft.Json in output directory. There's more fun when I add package reference on Newtonsoft.Json 12.0.1 directly in project.
In this scenario I need maximum of package version control.

@tebeco
Copy link

tebeco commented Feb 17, 2020

@ds1709,
As of today you can just use MsBuild variables for that,
There're 2 possible ways since MsBuild 15.x (2017) :

  • Use an explicit variable per package at a global level
  • Use a target that will apply the Version with an Update

I have created a repository to anticipate the Centralized Nuget Package here:
https://github.com/dotnet-experimentations/CentrallyManagingNuGetPackageVersions

  • if you check the folder WithMsBuild on branch master, it's the version of the code using target / Update / Version
  • if you check the folder WithMsBuild on branch explicit-variables, it's the version of the code using simple MsBuild Variable at repository level it's simpler, but it won't work in some scenario (like mixing TargetFramework and TargetFrameworks).

It's a bit long to explain but basically:

  • Directory.Build.props are applied first.
  • TargetFrameworks is transformed to TargetFramework (no 's') by a target

=> this mean you could end up with $(TargetFramework) being unset => empty string if you attempt to use them from Directory.Build.props
=> this is why the <project include="dependencies.props" /> is done in Directory.Build.targets

The approach with Target+Update on the other hand, needs value to be Include(d) first to be updated
=> The line order is important (at the end of the files)

What I mean by Include/Update + Line Order is how ItemGroup works
You need to "Include" something, to be able to match it in a later Update :

<ItemGroup>
  <YourItem Include="MATCH A NAME HERE" OneProps="OneValueOnInclude" />

  <YourItem Update="MATCH A NAME HERE" OneProps="The Later Updated Value" />
</ItemGroup>

@stevenbrix
Copy link

Will the VS support for this work for any SDK style project? I know there is no SDK-style for C++ projects, but we are thinking of rolling our own, and would like to make sure that experiences like this will still work

@jeffkl jeffkl added this to the Sprint 2022-04 milestone Apr 4, 2022
@JonDouglas
Copy link
Contributor

JonDouglas commented Apr 13, 2022

Hi friends,

With the help of you all and our wonderful team, we have shipped this today.

https://devblogs.microsoft.com/nuget/introducing-central-package-management/

You should be able to get it with the latest .NET 6, VS, and a future NuGet version.

You can find new documentation on the topic here as well:

https://docs.microsoft.com/en-us/nuget/consume-packages/Central-Package-Management

For feedback, new feature requests, or bugs, please file them in another issue or on developer community!

🎉🚢🚢🚢 🎉

@ransagy
Copy link

ransagy commented Apr 13, 2022

Does that mean the requirements are now set higher than when it was in preview, hopefully only in a recommendation kind of way rather than a block? Because technically none of the listed versions are available in stable form.

VersionOverride aside, it does work with older VS and CLI tools.

@japj
Copy link

japj commented Apr 13, 2022

It seems nuget 6.2 and visual studio 2022 17.2 are not released yet?

Is this supported in the latest 17.2 preview? (I can’t find it in the 17.2 preview release notes)

@JonDouglas
Copy link
Contributor

JonDouglas commented Apr 13, 2022

Hi all,

For more clarity, this feature has landed in preview in many of these release vehicles. Some are not out yet and some will come out relatively soon.

You should be able to use the latest VS 17.2 preview 3 with this feature. Some binaries may take one more release cycle to release for availability. For example, NuGet 6.2 usually releases with 17.2 stable but a preview will be out soon. .NET 6.0.300 SDK should show up here soon too. Note: It's the SDK version, not the runtime version. :)

Sorry for the confusion, I will update the blog.

@JonDouglas
Copy link
Contributor

Does that mean the requirements are now set higher than when it was in preview, hopefully only in a recommendation kind of way rather than a block? Because technically none of the listed versions are available in stable form.

VersionOverride aside, it does work with older VS and CLI tools.

This means that code has been formally merged in preview releases and we will be keeping eyes on feedback around the time the stable releases happen so people can take formal dependencies on it without it being "preview" or "experimental". We introduced a few features as well.

@kichalla
Copy link

Awesome, thanks for the update!, @JonDouglas.

Quick question regarding Transitive pinning. The article does not mention this so wanted to check. If I want to pin a transitive package to a specific version (for example, I want to pin a package to version 5.0.9 as it has a fixed vulnerability and this is the version used all across my projects), can I do this in Directory.Packages.props? Basically I am interested to know if this is possible or should I go to individual projects and specify this transitive dependency.

@kichalla
Copy link

Adding some details to my earlier post:
For example, let's say there is a package called Foo which is a transitive dependency across several projects in my solution and none of those projects directly reference package Foo. Can I pin Foo to a specific version in Directory.Packages.props so that all the projects in my solution must use that specific version provided I use <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled> in the Directory.Packages.props?

@batzen
Copy link

batzen commented Apr 13, 2022

@JonDouglas The blog states that transitive pinning is opt-in. That's extremely surprising as that's, again, contrary to what the community voted for. Can you clarify that and explain why the community was overruled again?

@JonDouglas
Copy link
Contributor

@JonDouglas The blog states that transitive pinning is opt-in. That's extremely surprising as that's, again, contrary to what the community voted for. Can you clarify that and explain why the community was overruled again?

We use many different data points to consider risk. As you may have noticed I conducted much of that early research and even interviewed over 10 individuals. It was unanimous from one angle and advocated for. However that's just one data point. We also broke many less vocal users without good reason and plenty of internal systems.

Sometimes we have to decide to move forward and reduce the risk of breaking the world by default. This doesn't mean this conversation is over, it means that we had to do something we believe is best with that data we have for now and can be revisited later.

Keep bringing this up as feedback so we can consider what default makes most sense when we go stable. This is not a "veto", these are the realistic constraints we live with while only being able to share so much data publicly. These flags are cheap to flip, more importantly the feature is now available to all who choose to use it.

I apologize in advance if this shocks you or lets the community down. Please continue to hold us accountable. We have to keep moving forward. We will learn what the best default is with time. Especially as more people officially adopt the feature.

@ghost
Copy link

ghost commented Apr 13, 2022

I also see that the security issue, NU1507, is just a warning. Is there a handy way to promote that to an error?

Also, if packagesourcemapping is enabled but a package is found in multiple sources, will it still generate a NU1507 error? Or is it assumed safe? I'm mostly trying to determine if can/should list * for nuget.org, or if we'll need to list every single package one by one.

@JonDouglas
Copy link
Contributor

@erinlah-ms Right now it's a warning. We didn't want to be too aggressive with it quite yet as we're working to finish other experiences with package source mapping first. We want to bring awareness of best security practices through this warning. If the detection doesn't capture all scenarios, please file an issue and we'll make sure we can ensure we detect more or add more codes for different scenarios.

@nkolev92
Copy link
Member

nkolev92 commented Apr 13, 2022

I also see that the security issue, NU1507, is just a warning. Is there a handy way to promote that to an error?

@erinlah-ms

NuGet respects TreatWarningsAsErrors, WarningsAsErrors and NoWarn.

In your case you might want WarningsAsErrors

@japj
Copy link

japj commented Apr 14, 2022

With respect to package source mapping, what is the expected way to configure this correctly for the combination of nuget.org and AzureDevOps Azure Artifacts (upstream mirror) feed?

the nuget.org feed is there to ensure packages can be discovered, but is actually disabled on the build servers

@ghost
Copy link

ghost commented Apr 14, 2022

Thanks @JonDouglas @nkolev92 . I'm in the process of reviewing with my security team to see if we can employ package source mapping -- as I'm sure you're aware!

For everything else though, we should be good to go. Great work!

@nkolev92
Copy link
Member

@japj
That's really up to you.
When we designed the feature, often times the people had different preferences (ex. map out nuget.org, vs map out their private feed).

https://docs.microsoft.com/en-us/nuget/consume-packages/package-source-mapping#package-pattern-precedence and https://docs.microsoft.com/en-us/nuget/consume-packages/package-source-mapping#setting-default-sources has some details about how to configure things.

@ghost
Copy link

ghost commented Apr 14, 2022

@JonDouglas out of curiousity, will the transitive pins be represented in some way in the resulting nuget?

For example, I have a package named CF. It consumes Flubber/1.0.0, which consumes System.Http/4.1.0. But System.Http/4.1.0 has reported security vulns. So suppose I have transitive pinning to pin System.Http/4.3.4. I'll compile against 4.3.4, right?

But what will users of CF/1.0.0 see? Will a reference to CF/1.0.0 pull in System.Http/4.3.4, or System.Http/4.1.0?

@ds1709
Copy link

ds1709 commented Jul 29, 2022

Is there any sence to place PackageVersions inside Directory.Packages.props? AFAIK, it all works fine if I place PackageVersions just inside Directory.Build.props, so I don't need Directory.Packages.props at all. Correct me if I wrong.

@reduckted
Copy link

@ds1709 This comment from @jeffkl on the NuGet blog may be of interest to you.

https://devblogs.microsoft.com/nuget/introducing-central-package-management/#comment-186

@jeffkl
Copy link
Contributor

jeffkl commented Jul 29, 2022

Is there any sense to place PackageVersions inside Directory.Packages.props?

Since MSBuild basically allows you to do anything you want, you can place your PackageVersions in any common import. However, the supported scenario is to place them in a file that NuGet imports for you so that other tooling can take a dependency on it. Tools like Dependabot might only work with certain files as well so I think anyone should just follow the recommendations for features like this.

@CoenraadS
Copy link

CoenraadS commented Aug 27, 2022

Today I was reading about the dotnet CLI experience: https://github.com/NuGet/Home/wiki/Centrally-managing-NuGet-package-versions#dotnet-add

I was encountering the issue that the .csproj is updated, not the Directory.Packages.props

The documentation mentions:

It will add a package reference to the project. The Package version will be added only to the Directory.Packages.props file. To update the version in the Directory.Packages.props file use the --force-version-update option.

I made sure to try on latest dotnet
dotnet --version => 7.0.100-preview.7.22377.5

I run

dotnet add .\ClassLibrary1\ClassLibrary1.csproj package Microsoft.Extensions.Logging.Abstractions --version 3.1.28 --force-version-update

I get the error Unrecognized command or argument '--force-version-update'

@JonDouglas
Copy link
Contributor

@CoenraadS That link is just a old specification. It is quite outdated and the most recent docs are found here:

https://devblogs.microsoft.com/nuget/introducing-central-package-management/

https://docs.microsoft.com/en-us/nuget/consume-packages/central-package-management

We do have dotnet add support mostly completed during some intern projects over the summer, but we will need to insert it into the next release and polish it. We will blog/release notes/add docs when that happens. Sorry for the confusion.

@reduckted
Copy link

Perhaps it would be a good idea to either remove those pages from the wiki, or add a big disclaimer at the top stating that they are out of date.

@JonDouglas
Copy link
Contributor

@reduckted Thanks. I keep forgetting how much SEO this page gets.

Check out #11952 for our next major iteration.

Here is a reference for small enhancements last release - #11752

@CoenraadS
Copy link

CoenraadS commented Aug 28, 2022

Thanks for your responses.

I took a look at the the next iteration items, but didn't see an item for dotnet add. Is there a issue for it that I can use to track it's progress?

Some context, I'm looking to try and adopt CPM in my company, however need a good story for automated package bumping. Perhaps there is some alternative way of working to achieve this?

@martincostello
Copy link

In case it's useful to you, dependabot version updates already support CPM, which makes it viable for automated package bumping.

@CoenraadS
Copy link

CoenraadS commented Aug 28, 2022

Turns out NuKeeper also supports it, which surprises me since that project ceased development about a year ago. My company is already using this so great news :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests