Packing static content in Nuget for PackageReferece projects - nuget

I have a Class Library (net47) project and I'd like to pack into a nuget my dll and several files of static content (js, css, images...). I want to use this dll and the content from the consumer projects. These projects will be MVC PackageReference projects. In these projects the local static files are in the wwwroot folder.
I have tried this: NuGet ContentFiles Demystified but I get my js and css files referenced (they aren't copied to my project content).
In my nuspec I've tried with all build options: EmbeddedResource, Content, None and Compile, but these references are imported always in Compile mode. So I get a compile error when I start debugging.
I know this was possible with Package.config projects and it's very simple but all my consumer projects will be PackageReference.
This is my nuspec
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2011/08/nuspec.xsd">
<metadata>
<id>MyProject</id>
<version>1.0.0</version>
<authors>My</authors>
<owners>My</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>LVP</description>
<copyright>Copyright 2018</copyright>
<tags>Tag1 Tag2</tags>
<contentFiles>
<files include="any/any/bd.js" buildAction="content" flatten="true" copyToOutput="false"/>
</contentFiles>
</metadata>
<files>
<file src="contentFiles/any/any/bd.js" target="contentFiles/any/any/bd.js" />
</files>
</package>
I pack my nuget with this powershell command:
nuget pack MyProject.nuspec
Although I have also tried with the csproj:
nuget pack MyProject.csproj
And my source folder structure is this:
C:\...[projectPath]...\contentFiles\any\any\bd.js
Installation is ignoring my build action.
Why is always trying to compile my content files? Is there a better way to add static content to the consumer project?

Installation is ignoring my build action. Why is always trying to compile my content files? Is there a better way to add static content to the consumer project?
To answer your previous question Packing files on nuget, I have created a sample nuget package and set the build action to content for the content files, after install that nuget package, the build action would be set content:
Then I checked your .nuspec file, found it should be correct. So the issue is not related to your .nuspec file.
Besides, in the above image, you will notice that the path of the content file is nuget local cache:
C:\Users\<UserName>\.nuget\packages\
NuGet will first extract the nuget package from the local cache when install the nuget package to avoid downloading packages that are already on the computer. In other wards, although we have updated the nuget package in the local, nuget will detect the local cache first, if it found the same package in the cache, nuget will install it from cache rather than local feed.
To resolve this issue, please try to remove your nuget package in the local cache before installing the updated nuget package. Generally, when we package the same package again, wed better change the package version in the.nuspec` file so nuget local cache will not catch them.
Update for comment:
I've tried increasing the version number and deleting the nuget cache and the problem persists. My build action is always set to "C# Compiler". I just tried changing the name of the js file and the project imports the new name so I do not think it's a cache problem
After test your nuget package, I found the reason why you get that issue, we should keep the path the src and target paths are the same in the .nuspec file. Since you want set content file to the wwwroot folder, you should set the file in the wwwroot folder, then pack the .nuspec:
<contentFiles>
<files include="any/any/wwwroot/css/bd.css" buildAction="Content" copyToOutput="false" flatten="true" />
<files include="any/any/wwwroot/js/bd.js" buildAction="Content" copyToOutput="false" flatten="true" />
</contentFiles>
Following in my .nuspec scripts(Not need content node):
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2013/05/nuspec.xsd">
<metadata>
<id>BancaDigitalViewProvider</id>
<version>1.0.37</version>
<authors>Ibercaja</authors>
<owners>Ibercaja</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Login View Provider</description>
<copyright>Copyright 2018</copyright>
<tags>Banca Digital View Provider</tags>
<dependencies />
<contentFiles>
<files include="any/any/wwwroot/css/bd.css" buildAction="Content" copyToOutput="false" flatten="true" />
<files include="any/any/wwwroot/js/bd.js" buildAction="Content" copyToOutput="false" flatten="true" />
</contentFiles>
</metadata>
<files>
<file src="contentFiles/any/any/wwwroot/css/bd.css" target="contentFiles/any/any/wwwroot/css/bd.css" />
<file src="contentFiles/any/any/wwwroot/js/bd.js" target="contentFiles/any/any/wwwroot/js/bd.js" />
<file src="bin\debug\BancaDigitalViewProvider.dll" target="lib\net47\BancaDigitalViewProvider.dll" />
</files>
</package>
This is nuget package:
https://1drv.ms/u/s!Ai1sp_yvodHfhTk5xutPpaBZLC-A
You can download it and test.
Then install it to the ASP.NET core MVC project:
Hope this helps.

Related

How can I include a file with a NuGet package, and then add that file to a project when the NuGet package is installed?

I have a project that includes 2 files:
ThisProject.config.example
ThisProject.xsd
This project is packaged as a Nuget package, which is then added to other projects. When this happens I would like these files copied into the projects. The user then copies ThisProject.config.example to ThisProject.config and edits that file.
I understand that within a .nuspec file there are two ways to include files. These are:
<files>
<file src="ThisProject.config.example" target="ThisProject.config.example" />
<file src="ThisProject.xsd" target="ThisProject.xsd"/>
</files>
Doing this, I see that when I install the package into the /packages folder that the files have been copied over. Which is good. However, then it would seem that I need to use a .ps script to add them to the project that the nuget package is installed to?
I haven't tried this yet, but according to THIS link, there are three scripts that can be incorporated into NuGet packages:
Init.ps1
Install.ps1
Uninstall.ps1
But No. 2 and 3 are obsolete from VS 2017 onwards? The link that is provided for explanation points to information on MSBuild. But there is no explicit information on flatfile types so far as I can see.
Then. Supposedly there is a <contentFiles> tag. But according to THIS post (NuGet blog) only works when a package is added to certain project types. And does not work with package.config files...
What is the expected way of adding a file to a project from a NuGet package??
I have found that if you put files within certain folder structures that they are implicitly added to the package and also added to the project root directtory. However I still have not found a way to add the files as items in the project itself. this is an example of the .nuspec file.
<?xml version="1.0"?>
<package >
<metadata>
...
<tags>some tags</tags>
<contentFiles>
<files include="**/*.*" buildAction="None" copyToOutput="true" flatten="true" />
</contentFiles>
</metadata>
<files>
<file src="contentFiles\any\any\config\name.example" target="content\name.example" />
<file src="contentFiles\any\any\config\name.xsd" target="content\name.xsd"/>
</files>
</package>
The MS docs mention it is useful to define both files and contentFiles. I think the requirement is that the nuget package has a folder content, in which files are transferred to the project directory

Why is nuget not adding my file?

I have this nuspec file:
<?xml version="1.0"?>
<package >
<metadata>
<id>My.Package</id>
<version>1.0.1.7</version>
<title>My Package</title>
<authors>My name</authors>
<owners>Mu author</owners>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>My description</description>
<releaseNotes>Release note</releaseNotes>
<copyright>Copyright 2017</copyright>
<tags>tag1 tag2</tags>
<contentFiles>
<files include="myFile.config" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src="myFile.config" target=""/>
</files>
</package>
When I pack this nuspec file, my nupkg file is created and in the NuGet Package Explorer I see that myFile.config is included in my package. All well so far.
But, then, when I install this package, the dll is added to references, but myFile.config is not added to the solution.
Things I've tried without success:
- View the folder on Disk to see if myFile.config is created (not there)
- <file src="myFile.config" target="."/>
- <file src="myFile.config" target=".\"/>
I also want the file to set Copy to Output Directory: Copy always.
What am I missing here?
PS: I am working on a private nuget server.
The target needs to be content since files of the nugpkg's content subdirectory are copied to the consuming project.
Note that this only works for projects using the packages.config style of referencing NuGet packages. For PackageReference (available in VS 2017, default for .NET Core / ASP.NET Core / .NET Standard projects), there is a new contentFiles feature that includes files logically in the build process.
See NuGet's documentation on including content files for more information.

Options for placing and updating PowerShell files in Project folder using NuGet

I am building a NuGet package that only contains a set of PowerShell scripts. The desired behavior is for the scripts to be placed in the project and/or solution folder, removed when the package is uninstalled, and updated when the package is updated. These scripts just need to live in the folder, and be copied to output folder (they are deploy scripts).
I've done this before using content target in a nuspec, but this does not work in netstandard/.NET Core applications (i.e., anything that uses PackageReference). The NuGet documentation mentioned the contentFiles element under the metadata element, but that also does not work with PackageReference. The only thing that I have been able to get working at all is copying the PowerShell scripts in tools/init.ps1. I have something partially working, but it doesn't handle the uninstall or upgrade path. And DTE is never fun.
Is there a way to use content files in netstandard?
If not, does there exist a sample or example of how to properly manage the NuGet lifecycle (copy file, update file, delete file)?
EDIT: This is for a console application, but it also should work in an asp.net application.
EDIT2: This is the nuspec that I have tried to do things via the contentFiles element. When I install the package, I don't see anything in project or solution.
<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Test</id>
<version>1.0.0</version>
<contentFiles>
<files include="Build.ps1" buildAction="Content" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src="Build.ps1" target="content" />
</files>
</package>
Thanks,
Erick
As you have noticed, NuGet packages referenced via PackageReference no longer modify the project when installing. This is also the case for .NET Framework projects using this new feature (it was made public for non-core projects in VS 2017 15.2).
The content/someScript.ps1 file is still necessary for compatibility with "classic" packages.config based project, but a new feature for PackageReference projects is contentFiles.
When packing manually using a nuspec file, copying a file on build can be done by adding a contentFiles section:
<package>
<metadata>
...
<contentFiles>
<files include="**/*.ps1" buildAction="Content" copyToOutput="true" />
</contentFiles>
</metadata>
<files>
<file src="Build.ps1" target="content" />
<file src="Build.ps1" target="contentFiles/any/any" />
</files>
</package>
See the documentation on contentFiles for more details my example on GitHub.

NuGet include tools folder when packing from csproj

I'm trying to create a nuget package from a csproj file. This package will include an install.ps1 script in the tools folder and some files in the content folder.
However, it seems like when packing from a csproj file, nuget will pull the package information (description, tags, etc.) from the corresponding nuspec file, but not anything else. It ignores the tools folder that is in the same directory as the nuspec file as well as the content folder.
When packing this way nuget also seems to ignore files included in the contentFiles section of the nuspec file.
Is this expected behavior? If it is, is there a way for me to pack from a csproj and get the content and tools folders to be included in the package?
I realize I could just use only a nuspec file and this would work, but I have multiple packages I'm trying to build this way and managing the dependencies manually becomes a less than trivial task.
Running NuGet 3.4.4.1321
My nuspec file:
<?xml version="1.0"?>
<package>
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$id$</title>
<authors>authors</authors>
<owners>$owners$</owners>
<projectUrl>http://dummy.url</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>the description</description>
<copyright>$copyright$</copyright>
<releaseNotes>$releaseNotes$</releaseNotes>
<contentFiles>
<files include="content\App.config.install.xdt"/>
<files include="content\App.config.uninstall.xdt"/>
<files include="temp\App.config"/>
</contentFiles>
<tags>wpf testing</tags>
</metadata>
</package>
Turns out the documentation for this confused me a bit. Content Files are not a replacement for Files. In NuGet 3, both can be used simultaneously.
Using the Files tag outside of the metadata tag in my nuspec file allowed me to specify items that go into the tools and content folder.
Updated nuspec:
<?xml version="1.0"?>
<package>
<metadata>
<id>$id$</id>
<version>$version$</version>
<title>$id$</title>
<authors>authors</authors>
<owners>$owners$</owners>
<projectUrl>http://dummy.url</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>the description</description>
<copyright>$copyright$</copyright>
<releaseNotes>$releaseNotes$</releaseNotes>
<tags>wpf testing</tags>
</metadata>
<files>
<file src="App.config.install.xdt" target="content"/>
<file src="App.config.uninstall.xdt" target="content"/>
<file src="tools\install.ps1" target="tools"/>
</files>
</package>
Hopefully this helps in case anyone else gets tripped up by the docs here.
A bit more discussion can be found in this NuGet Issue.
You could do nuget pack -Tool
Tool - Specifies that the output files of the project should be placed in the tool folder.
https://learn.microsoft.com/en-us/nuget/tools/cli-ref-pack

How to exclude a folder from a nuget package

I'm using Octopack / Nuspec file to build my nuget package.
I would like to exclude certain folders which exist in the project. e.g. the "obj" file. I've been trying to get the exclude tag to work, but haven't had any luck. The nuget file builds, but the folder is still there.
Sadly, all the examples on the net specific file types and not folder.
<?xml version="1.0"?>
<package xmlns="http://schemas.microsoft.com/packaging/2010/07/nuspec.xsd">
<metadata>
<id>Foo</id>
<title>Foo</title>
<version>$version$</version>
<authors>NA</authors>
<owners>NA</owners>
<licenseUrl>http://Foo</licenseUrl>
<projectUrl>http://Foo</projectUrl>
<requireLicenseAcceptance>false</requireLicenseAcceptance>
<description>Foo</description>
<releaseNotes>NA</releaseNotes>
</metadata>
<files>
<file src="obj\**\*.*" exclude="*.*" />
</files>
</package>
I needed to create a WebApplication, but deploy it as a standard ASP.NET website using "CodeFile" attributes.
This was basically to update a page in the standard ADFS login site.
<files>
<file src="**" exclude="**\*.dll;**\*.designer.cs;**\*.csproj;**\*.pdb;**\*.user;**\*.vspscc;bin\*.cs;bin\*.aspx;bin\*.config;bin\*.asax;bin\*.pubxml" />
</files>
To directly answer the posters question, if you want to exclude only the obj folder from a Nuget package use the following in your nuspec xml
<files>
<file src="*\**" target="\" exclude="obj\**\*.*"/>
</files>
Depending on the project you are building, you shouldn't need to exclude anything.
If you are building a Windows Service/Console application, OctoPack should only package your bin\release directory.
If you are building a web application, you should use a 'publish' command to have MSBuild sent the binaries and content files to a temporary folder, and OctoPack will package that. This way your obj folders and C# files won't be packaged.
For information on how to do this, please see the section on Web Application Publishing at:
http://octopusdeploy.com/documentation/packaging/octopack