Deploy Web Service to Nuget Package - c#

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.

Related

Shipping msbuild task as nuget

I need your help.
I'm developing an msbuild task that performs certain actions upon msbuild.
I want my users to be able to download and install a nuget package and once the package is installed the build task will be part of the build process.
I know how to release a nuget package and i know how to includes a custom targets file together with the nuget, what i don't know is how to add the import statement to the csproj upon nuget installation:
Is there a way to do so or am i asking for too much?
Thanx!
Gilad
The docs aren't in the easiest to find place, but here's a link to the docs on including MSBuild props/targets files in your package.
Basically, you put the file in the package in the location build\<tfm>\<package_id>.props. For example build\netstandard2.0\MyPackage.props. If you want your build targets to be included in all TFMs, you can use build\<package_id>.props, but if your package also contains other assets like lib/ or contentFiles/, the "no-TFM" build files will cause "asset-target fallback" to fail, so if your package has only net472 libs, and the build files, a project targeting netcoreapp3.0 will get only the build assets, none of the net472 assets. If your build files are in a TFM folder, then NuGet's asset target fallback will select both the lib and build assets. So, I strongly encourage everyone to always use the TFM folder.
The docs need to be improved, but the table explaining lists build, buildTransitive, and buildMultiTargeting. Projects using packages.config only use build assets under build. Projects using PackageReference only use build and buildMultiTargeting assets when the project references the package directly. Assets under buildTransitive get selected when the package is pulled in transitively, rather than directly. The difference between build and buildMultiTargeting is complex. If you understand the concept of "inner-build" and "outer-build" in multi-targeting SDK style projects, that's the difference (build is inner-build), otherwise only use build.
I should update the docs to have this information.

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".

Refer assemblies(artifacts) from artifactory in .NET

I'm trying to make my .Net project work with Artifactory. So far I've uploaded the reference assemblies(.dll) files to artifactory using Jenkins. Now to build my solution, I want to refer those uploaded reference assemblies(artifacts) from artifactory, rather than referring them from the local path.
I tried using the MSBuild artifactory plugin, but it has a partial support for Jenkins.
Is there a way to do this?
You can not reference dll directly from Artifactory. To use them as dependencies in your project you have two options :
first one is to download them locally before your build (you can
setup a prebuild step for that)
second one is to create a nuget
package containing these dlls, to upload this nuget package to
Artifactory (this is where the MsBuild Artifactory plugin can help
you) and use it as a nuget dependency within your project where the
nuget feed used by Visual Studio will be configured to reach
Artifactory nuget repository.

TFS 2015 "vNext" Build for web project in solution

I am trying to achieve setting up a vNext build definition on TFS 2015 (the project is actually a .NET 4.6.1 web project, but I want to use the new TFS build setup). I am struggling with finding documentation on only deploying a specific web project in my solution (2 web projects, 3 class libraries and subsequent tests).
In the XAML build approach, I would specify the .sln and the .csproj file relevant to the build in the Process > 2. Build > Projects input. The "Visual Studio Build" step does not allow for multiple project inputs in the same way, and this seems to be where I am getting stuck. If I only specify the .csproj, Nuget packages do not get restored and the build fails.
Is there any known documentation for deploying a C# web project (.csproj) ONLY via these vNext builds?
MSBuild arguments previously used in XAML Build:
/p:AllowUntrustedCertificate=True /p:AuthType=NTLM /p:Configuration=Development /p:DeployOnBuild=True /p:PublishProfile="DEV" /toolsversion:14.0 /p:VisualStudioVersion=14.0 /p:GenerateBuildInfoConfigFile=false
The solution I am searching for would accomplish the following:
Builds at the very least the Web.csproj with project dependencies
Restores Nuget packages
Transforms web configs
Deploys Web project to two separate servers (non-Azure!) via, ideally, web deploy
Thanks in advanced for any help. Hopefully this is possible!
Note: I am not on Azure and Azure is not an option. I know there are tons of documented use case scenarios for Azure users, which is great... but, yeah.
You can add a "NuGet Installer" task at the top of your build definition to restore the nuget packages for your solution and specify the .csproj in Visual Studio Build Step.
If you want to build the entire solution, you can add following arguments in "MSBuild Arguments":
/p:DeployOnBuild=true /p:WebPublishMethod=Package /p:PackageAsSingleFile=true /p:SkipInvalidConfigurations=true /p:PackageLocation="$(build.artifactstagingdirectory)\\"
This will create the deploy packages for your projects separately in "$(build.artifactstagingdirectory)\" folder like following:
Then you can choose the package for the project you want to deploy. And with the deploy package, you can add two "Command Line" tasks in your build definition and call "Project.deploy.cmd" under "$(build.artifactstagingdirectory)\" folder to deploy the project to your servers. Reference about deploy from command: Executing the Command File. Web.config will be transformed by default if you have configured it correctly.
By the way, I recommend you to deploy your projects by using the release management system instead of deploying them in build.

Directory structure for a NuGet published github hosted project

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.

Categories

Resources