Automated Nuspec Package Creation - jenkins

Problem
So I am working on a feature to allow my team the ability to create NuGet Packages of specific projects automatically upon the project building successfully in Jenkins. I have spent the last 3 days researching how to contruct/create/build nuspec packages and NuGet packages... but nothing seems to point me in quite the same direction I am trying to take this in.
So far, from what I have learned and understood about creating NuGet packages, the primary way to do this is the following steps:
Download nuget.exe and place a copy of it in the target project's root folder.
Open the cmdprompt and navigate to the target project's root folder
Run the following command nuget spec
Open the newly created nuspect file and update all default values to the appropriate values for the target project
Save the changes, then run the following command in the cmdprompt nuget pack packagename.nuspec
Although the above works as expect, it isn't really very automated.
I have taken an approach in which I created a script that has a nuspec template and populates fields, but I still require a lot of input from the user to make this happen.
Question
Is there any way to automatically generate a properly populated nuspec package for a target project that requires minimal input from a user?

There is a package on NuGet that
Works well in a continuous integration environment with a build server; and
Creates a nuspec file for your project.
Source code with a larger readme is on Github

Related

TFS Agent Build Reference errors

I am attempting to create my first ever agent build using on my my asp.net mvc projects. The agent is on my own computer. Everything appears to work fine up until after the nuget restore.
Picture:
It is telling me that my System.Web.MVC assembly could not be located. Since this is of course my first build I am unsure of what to do or what could cause this issue especially since it builds fine locally in VS.
Any help would be greatly appreciated:
TFS Version: 16.122.27102.1
You can follow steps below to locate the cause of the issue and resolve it:
1.The Nuget 4.3.0 you're using is too old. Instead you should use recommended 5.7.0. (Modify your Use Nuget Task)
2.Check log of your restore step.
The missing System.Web.MVC comes from Microsoft.AspNet.Mvc nuget package, so you should make sure this package is actually downloaded/installed. And make sure the hintPath in your csproj is correct compared to the installation path of the nuget package.
Also make sure you're restoring for whole solution instead of one specific project.
Check whether you added packages folder into source control. The packages folder in SolutionDir should not be added into source control! It will affect the restore stop.
3.Check MSBuild arguments of Build task, you can share the arguments and build logs here if convenient.

WiX bootstrapper UI not compiling from TFS build definition

I have a WiX bundle installer in my solution. It consists of several MSI projects and the bootstrapper UI project. When built all at once everything works fine.
With a new requirement to authenticode sign everything, I am trying to split the assembly compilation from the installer compilation, so I can sign in between.
I am trying to do this with two separate build configurations. One that builds only the application assemblies, and another that builds only the installer projects. They both are working properly when I run them by hand from visual studio.
The problem is when I try to call them from separate tasks in a TFS build definition. The assemblies, including the bootstrapper UI, all compile successfully in the first task. But in the second installer only task, the WiX project will try to recompile the referenced bootstrapper UI project and fail with missing type or namespace errors.
I've tried including and removing the boostrapper UI project from the installer only build configuration. I get the same errors in either case. It's the wixproj itself that is kicking off the underlying bootstrapper UI build.
Ok, I think this is what you're trying to do, please correct me in the comments and I can refine the answer accordingly.
It sounds like you have a single solution that when built in one Configuration (say, CODE) it will only compile the .net projects and in another configuration (say, PACKAGE), it builds only the WIX projects. I think this separation is part of the problem.
From your description it also sounds like the wix projects have project references to the other code projects (for payload harvesting most likely - but at the very least, establishing build dependency order).
Any project (wix or code) that references another project will automatically cause that project to build - in the absence of solution configuration it will default to using the same configuration as the primary project. This means that if project A has a configuration called CODE and project B references with a configuration called PACKAGE references it, then building project B will cause A to try to build with configuration PACKAGE - if it doesn't have this configuration then it (successfully) won't build and project A will then fail to find the dependencies it expects.
In your solution, you should have two configurations, one of which is a superset of the other. So your CODE configuration for building only code is a subset of the PACKAGE configuration for building your wix projects. When you set this up in configuration manager and build the solution then you guarantee that the projects build with the correct configuration instead of inferring a configuration from the primary.
Then instead of two build steps in your TFS build you can do it as one. If you still need to split it (because you digitally sign the assemblies in between), then know that msbuild does incremental builds by comparing timestamps of inputs to outputs. This means that if you build project A then digitally sign it, building project B (that references A) will attempt to build project A but it will determine that the output of A is newer than the input and not replace the assembly. Ultimately this means it's safe for you to build your solution under configuration CODE, sign the assemblies then build the solution again under configuration PACKAGE (which is a superset of CODE) without the signed assemblies being replaced.
On a related note, the wix targets file has hook points to sign the bundle as part of the wix project build. That may be better than trying to use PowerShell to sign it after the fact.

using tfs build pull a prebuilt common components into another build

I'm looking for advice on how to have team build 2013 use a pre-compiled common that is not checked in or part of the workspace.
Everything we build is QNX based and we are refactoring out a common set of components to be shared across all projects. I've looked at Go and NuGet but that seems like a lot effort for something like this.
What is the best way to pull a prebuilt common into a TFS Team Build?
So you would nuget "publish" a package.
https://docs.nuget.org/create/creating-and-publishing-a-package
then your build would nuget restore using a packages.config file (aka, NOT a .sln file)
nuget restore [<solution>|<packages.config file>]
https://docs.nuget.org/consume/command-line-reference
What VS (in a .sln file) is auto-voodooing some of this for you.
But using command line nuget (especially for the restore)....is a way to get a package out of nuget if you're build isn't based on .sln file.
Another way to think about it is...when you run "nuget install" or "nuget update", VS is auto-voodooing you a packages.config file. While you might look at the file and find it interesting, you're not consumed on how it works in the background of VS. But if you want to manually pull nuget packages....you will be very interested in how it is created.
What I would do as a test would be:
Create a dummy .sln,csproj file.
Nuget add a few random packages (using "Manage Nuget Packages for this solution).
Take that packages.config that was auto-voodoo created for you.... and move it to a clean directory.
See if you can run nuget.exe restore on it, and get/pull the packages (aka, you're testing that you can do a pull... without a .sln file being involved).
If that works...than it becomes of matter of creating your own nuget repository..creating your own published-package...and repeating #4 above to get that package out.
Make sense?
So I have these files in a clean directory:
.\packages.config
.\.nuget\NuGet.Config
.\.nuget\NuGet.exe
.\.nuget\NuGet.targets
Then I run in the comamand-window:
.\.nuget\nuget.exe restore .\packages.config -PackagesDirectory .\MyPackages
And all the packages listed in "packages.config" will download to : .\MyPackages
Note, if you have a custom nuget repository, that will need to be configured...but cross that bridge when you get there.

TFSBuild 2010 Package only contains sources - not binaries

The packages created by a TFS 2010 Build only contain our Sources, not the binaries. When this is (automatically) deployed to IIS, the site does not run because it is missing DLLs that are created during the build process.
We have a Web Project created in VS2010. If I select "Build Deployment Package" from a right click in VS we get a zip file in the obj\Release\Package folder that contains the fully build site.
However, if ask our TFS build process to create the package by adding "/p:CreatePackageOnPublish=true /p:DeployOnBuild=true" to the MSBuild arguments (as advised in amongst other places here) we get an zip file in _PublishedWebsites\_Package\.zip that only contains the sources.
My best guess is that the CopyAllFilesToSingleFolderForPackage is picking up the files from the wrong place.
I notice a similar issue asked here - TFS 2010 and creating a package - although his workaround in not appropriate in many cases, I'd guess.
My concern is that this is using a built-in, but poorly documented feature of MSBuild/TFS so when it doesn't work you're a little in the wilderness.
It seems that deployOnBuild runs some "package"-like target on each of the projects. If you have built the projects into a separate directory (which the default TFS 2010 build does by default) the packaging won't pick up the compiled files.
One solution is to get rid of the custom output folder for the MSBuild Command within the TFS build workflow. This will cause the compiled files to be located in-situ and be included in the package.
Now the rest of the TFS workflow is require some changes because it'll be expecting to transfer the files from the output directory, and they won't be there.

Recursively include Nuget DLLs via Gitignore

I am using GIT with a new ASP.NET MVC project. I have a line in my gitignore file to ignore dlls
*.dll
I would like to add something along the lines of the following to include (i.e. do not ignore) DLLs in my NUGET packages folder
!/packages/*.dll
The problem I'm encountering is that not all nuget packages are created equally and, depending on the package in question, DLLs may be nested an arbitrary number of levels in the path hierarchy. It seems that I simply need a recursive solution along the lines of:
!/packages/**/*.dll
!/packages/**/*
I have not yet found a solution that will work via mysysgit (or any windows distribution of git).
Does anyone know of a way to make this work???
Leave your top level gitignore alone by keeping *.dll in it.
Create another .gitignore file in the packages directory and put !*.dll in it.
Another option to consider is NOT including your NuGet dlls in your repository and instead only download them the first time you build your project. This is what we do with all of our NuGet dependencies.
UPDATE
Nuget handles this now without having to manually create your own build events. See the details on this page: http://docs.nuget.org/docs/workflows/using-nuget-without-committing-packages
Original Answer:
We put the NuGet.exe application in a tools folder under our solution, and then add the following to our project pre-build event.
"$(SolutionDir)Tools\NuGet.exe" install "$(ProjectDir)packages.config" -o "$(SolutionDir)Packages"
The first time we build the app it will download all of the dependencies, but with subsequent builds, NuGet is smart enough to see that they already exist at the correct version and skips them.

Resources