Directory structure for a NuGet published github hosted project - c#

For a github hosted open sourced C# project which is also available via NuGet, how should one organize the source? Specifically:
should the .nuspec file be in the github repository?
should the .nuspec file be in the same folder as the .csproj file?
how about the NuGet package tree (the /lib, /content stuff), since is generated, should it be in git?
My thinking is that the NuGet part is separate from the github hosting, as in the project source are available but the .nuspec is not, since the publishing in NuGet is not an open source operation per-se. None wants that every fork to build and publish a new NuGet package, so that the open source Foo package ends up in the gallery as 'Rick's Foo' vs. 'John's Foo' vs. 'Alice's Foo' etc.
But on the other hand I do want the github source depot to act as a one-stop repository for the project, if I open my other laptop and enlist from there, I should be able to build/package/push w/o recreating the whole NuGet infrastructure from scratch (ie. only enter my API key, nothing more).
These two requirements are contradicting each other, Did I miss something obvious?

I would do the following:
Commit the .nuspec file next to the .csproj file
Add a nuget.config file which moves the packages folder a level up.
Enable package restore in the solution and do NOT commit the content of the NuGet package repository
Create an msbuild file (or whatever build vehicle you like) which has:
a "build" target which builds the source and creates the nuget package
a "publish" target which pushes the NuGet package to nuget.org and takes your API key as a parameter.
I personally maintain the version number of the nuget package in the .nuspec file and manually update it when I do a "release". This way I can tag the exact release I pushed to the NuGet feed.
With this setup a build in Visual Studio does not produce a NuGet package but all tools are available in the repository to do so.
The Folder Structure looks like this:
.\Docs\ ==> not in source repo
.\Packages\ ==> not under source control
.\Src\ ==> git repo here
.\Src\MySolution.sln
.\Src\.gitignore
.\Src\MuRules.ruleset
.\Src\build.proj ==> msbuild file to build everything.
.\Src\MyProject\MyProject.csproj
.\Src\MyProject\MyProject.nuspec
.\Src\MyProject\nuget.config
.\Build\ ==> not under source control
.\Build\Debug\
.\Build\Release\
.\Build\Publish\
Be aware of this bug in the Package Restore feature, it will ignore the packages location you configured. http://nuget.codeplex.com/workitem/1990 ==> This is fixed in Nuget 2.7

On nuget v2.8, I just need to modify .gitignore and add:
packages/
This will exclude the nuget packages folder from committing. When you build the new checked-out source code, the packages would be downloaded and restored. Make sure package restore setting has been enabled but I think it's been enabled by default on v2.8.

Related

Does nuget create separate packages?

I am still confused about how nuget works. I git clone a C# .sln project and from console, and I ran this nuget command:
nuget restore my_project.sln
it came to my attention that it generates two packages containing all dependencies required by my_project.
One package is located under my_project/src/packages, the other c:/users/my_user_name/.nuget/packages. While the file structures are a little different the DLL files in both packages are identical.
That confused me. Why two packages are generated by default? Where exactly does Visual studio look up for the project's dependencies?
More important, which config file should I update in order to only keep a copy of the dependencies and how can I specify the location in my file system for the packages?
Recent versions of NuGet support package references in project files.
This format will restore packages on demand, using your %USERPROFILE%.nuget folder as a cache. And your solution folder won't be "polluted" by a packages folder with binaries that you probably don't want to commit to source control.
VS2017 allows you to select "PackageReferences" or the older "Packages.Config" format when you create new projects (Tools/Options/NuGetPackageManager/General).
You probably have some projects in your solution that use the older "Packages.config" format, which stores in the packages folder in the solution directory, and newer "PackageReferences" format.
To convert the older projects to the new format, I believe you need to remove all packages from the project, then add them back again. They will be added using the default format you selected, with a prompt for confirmation if you selected "Allow format selection on first package install".

Unnecessary folders from NuGet packages

My c# app target framework is 4.6.2
I downloaded from NuGet some packages, my question:
when I open my app in file explorer, under packages\somepackage\lib I have this:
do I really need net 40 and net45 folders?
can I delete that? how do I know what is unnecessary?
Reason why NuGet keep the folders
Nuget uses two different methods to manage packages of every project:
packages.config
PackageReference
packages.config is only used for old project files which cannot import and reference NuGet packages automatically. NuGet will change the *.csproj file to add the references. Because it changes the code which is under version control and cannot use an absolute path, so it should put the NuGet package cache folders in every solution. In this case, NuGet might have the ability to remove the useless folders. But this is the behavior of legacy NuGet version (version 2.x). NuGet doesn't want to fix a legacy behavior.
PackageReference is the new behavior of NuGet references. NuGet put all the NuGet cache in a common folder so that it will not take too much disk space by the same NuGet packages. In this case, NuGet doesn't know every lib version on your whole computer projects, so it can't remove the useless version folders.
Conclusion: NuGet doesn't know whether it is safe to remove them in PacakgeReference and doesn't want to remove them in packages.config.
Upgrade packages.config to PackageReference
UPDATE:
From VisualStudio 2017 version 15.7 there is an integrated feature that allows you to do this upgrade without using third party tools Migrate from packages.config to PackageReference
In Solution Explorer, right-click on the References node or the packages.config file and select Migrate packages.config to PackageReference...
You can try a Visual Studio extension NuGet PackageReference Upgrader to upgrade your packages.config to PackageReference so that it will not store libs in every solution folders to eat up your disk space.
P.s.
NuGet take me nearly 10GB on my C:\ .

Adding source of a nuget package to the solution

I have a project that consumes a NuGet package from a private NuGet feed. I also have a source code of that package in a separate project/solution. When I work on the project I want to be able to, temporarily add the mentioned source code of the package to the solution, so i can work on changes in both the project and nuget package simultaneously.
In Visual Studio 2015, with dotnet core and project.json/global.json I could add the NuGet package to the project and then modify the global.json to include the source from the disk.
global.json:
{
"projects" : [ "src", "../<path_to_external_source>/src" ]
}
That would, temporarily, change the reference to the project on disk. Before pushing to the build server, I'd just remove one line from global.json and remove projects from solution.
In Visual Studio 2017 and csproj based dotnet core I cant't seem to get that functionality. I have to remove the nuget package, add source code manually through "add/existing project" to solution, then manually add reference instead removed NuGet references. Then reverse all that before pushing to build server.
It's especially problematic when solution has several projects consuming the NuGet package, and I need to go thorugh that process with every one of them.
Is there a way to reproduce the functionality of global.json in VS17?

After clone of web site project nuget restores packages but references are not found VS 2015

We have moved a legacy web site to git in TFS, and anytime the project is cloned nugget restores the packages per the package.config, and adds them to the packages folder. The subsequent build fails due to not being able to find the assemblies added through the nuget restore.
If you do a update-package -reinstall and the project builds successfully. Is this expected behavior or do I have a setup issue? The previous repo had the packages being checked in to eliminate this issue but I'd like to avoid that.
Is this expected behavior or do I have a setup issue?
Yes, this is expected behavior for NuGet, so do not worry that it is a setup problem.
NuGet Restore only restores files in the packages directory (\packages folder ), but does not restore files inside your project or otherwise modify your project. For example, if a package has added some reference DLLs or other files in your project, if you delete any of these files, they will not be re-added when restoring this package. This may cause the your project to not be able to find the missing dependencies when building.
Besides, the expected result is that the references should be used normally without broken after restore packages. In this case, we will not need to spend extra time using update-package -reinstall command line to uninstall and reinstall packages.
So use the "Update-Package -reinstall" command to force reinstall the package references and content files into project in order to resolve those references that were broken after packages restore.

Deploy Web Service to Nuget Package

I have several WCF and WebAPI services as well as MVC websites in a visual studio solution. Currently, we are creating WebDeploy packages for these services and websites to deploy to IIS. I'm starting to look into Octopus Deploy for deploying our services and websites instead of WebDeploy. However, Octopus Deploy uses Nuget packages to deploy.
I'm trying to figure out how I can easily create a Nuget package that contains all the files that would normally be published into a WebDeploy package. This may not be all files in the project directory or the bin directory. I found this blog post describing how to package a csproj into a Nuget package during the build, but I found that the resulting package didn't contain any of my dependency dll's. I realize I could write a nuspec for each of these projects manually and include exactly the files I want, but I'm looking for a more automatic way as this would create more maintenance when my project changes.
Does anyone out there know a good way to generate a nuspec or Nuget package that contains only the files needed to run the application, similar to the way publishing to a WebDeploy package only includes the files it needs?
Octopus Deploy has a CLI called "Octo.exe" that can package up your application into a NUPKG.
You will need to install Octopus Tools which you can download from https://octopus.com/downloads
Please see http://docs.octopusdeploy.com/display/OD/Using+Octo.exe for the documentation and how to use it.
A good example to use Octo.exe is part of a Continuous Integration pipeline when the build has successfully passed you call it to package the application and send it to the Octopus server.
After some playing around with Visual Studio, MSBuild, and TeamCity, I discovered a method that works for me. My issues was that I did not want to package up all the files in my project directory, only those that are necessary to run the application. WebDeploy handles this quite nicely as one of the options when publishing. I already have settings in my csproj file that will create a WebDeploy package on build, but this is a zip file and I don't want the zip file in my Nuget package.
I found 2 ways to deal with this:
In TeamCity, I set up a new Build Configuration that will package any nuspec files I have and publish the resulting Nuget packages to my Octopus Deploy Nuget feed. I figured out that I can use the existing WebDeploy package that gets created by my CI build configuration as an artifact dependency and TeamCity can actually unpack the zip file when grabbing the artifacts as part of that dependency. Then my nuspec file references the entire folder structure that was extracted from the zip file and packages it into a Nupak.
I was able to modify my csproj settings to use a specific publish profile I generated in Visual Studio that would perform a WebDeploy package to file system. This would result in the same folder structure as is in the zip file from #1, but simply copied to a directory. Then my Nuget build configuration could simply grab those dependencies and package them the same way as in #1.
I decided to go with option #1 as it would require minimal changes to my existing csproj and CI build configuration, and it would not break our current method of deploying using WebDeploy.

Categories

Resources