First, I will describe our setup (it is an extremely simplified version of the corporate development pipeline). We develop a .NET application, which is dependent on some shared components. The shared components typically develop together with the application. We want turn these shared component to NuGet packages.
So, I publish version 1.0.0.4 of package A and want to consume it in my application. My packages.config looks like this.
<package id="A" version="1.0.0.4"/>
So far so good. I probably commit packages.config to version control at this point to remember my dependencies. Now I run the next build of package A, which publishes the version 1.0.0.5. Now I want my application to automatically update package A to 1.0.0.5 before the build.
However, my packages config now contains an exact verion 1.0.0.4 and it's version-controlled. My questions are:
Can I somehow specify that I want version 1.0 or higher in packages config? In other words, can I avoid change of packages.config with every new build of every package?
Can I somehow update the dependencies before build to the the newest version? Can I do it automatically using a script?
I am quite new to NuGet and I come from the ant+ivy/maven world, where this feature is kinid of automatic, so I am still hoping I am missing something obvious in NuGet, although scanning through the discussions on stackoverflow doesn't sound too encouraging.
I've found Using Nuget in development environment - best practices / how to and How to automatically update NuGet packages to latest available version and NuGet issues with packages.config, project references and the solutionwide packages folder, which do not give clear answers.
You can use the allowedVersions attribute to automatically use newer package versions within a range, like this:
<packages>
<package id="SomePackage" version="2.1.0" allowedVersions="[2,3)" />
</packages>
In this example, any package from the 2.x series will be used, but not from the 3.x series. You can be more specific with the contraint e.g. `allowedVersions="[2.1,2.4)" if you wanted to take any package from 2.1, 2.2, and 2.3 but not 2.4.
See http://docs.nuget.org/docs/reference/versioning for more details
I don't think you can change the packages.config to implicitly allow a higher version. Also, the project files have references to the packages folder which include the package version in the path, so those need to be changed after a package update.
You can perform an update of the packages.config and the projects files by running nuget update.
You could automate this in the nightly builds and checking in the resulting changes as well. However, it's debatable whether that's a good idea. At the minimum, you should gate the update operations by running a build to make sure the new version doesn't cause a build break.
Related
We have a large solution with many projects, and many developers working together.
We need a way to validate Nuget package versions to insure no developer accidentally breaks the build with a package update.
Ideally, is there a way to validate and interupt/stop during Nuget package installation if it is a known incompatible package? We know we can do a validation at build time, but Ideally I'd like to actually be able to stop/inform the developer the newer version is not supported in the build to prevent them from going off and building with the newer package, only at build time to discover they've wasted time on a new package that might have differing calls etc.
If this is not possible, what would be the easiest way to do this at build time? I'm thinking a pre-build script but interested in other ideas. Effectively, the script would look across other project package versions to compare and inform if an incorrect version (and stop a publish to a shared location during build).
I'm looking on creating NuGet packages as part of my CI builds. My intent is to be able to deploy the final application for testing, and once passed, allow that build to be promoted to a release version by removing the -prerelease designation. How can I take an existing NuGet prerelease package and convert it to a non prerelease?
I wonder if the package contain the hash file that is causing an issue. I think your only choice is to generate a new package.
Just open the nupkg file in Package Explorer and edit the version number.
I have done that many times to covert a -rc to production.
Works fine
Our development team has been fairly small and, until now, all working on a single Visual Studio 2012 solution. We are growing and wanting to create better separation with multiple solutions for different project teams.
However, there are occasions where the code in one solution will want to utilize code from another. We have decided using internal (i.e. private) NuGet packages will be a good way to manage these dependencies.
However, the question has come up on how to deal with multiple versions of the same package that are in different SDLC stages (e.g. Development, QA, Staging, Production, etc.)
Example: If we have these three solutions...
CoreStuff
CoolProject1
CoolProject2
If working in CoolProject1, and we need to utilize code from CoreStuff, we can add the NuGet package. Presumably this package will be the latest Production (stable) version of CoreStuff.
However, what if a developer working on CoolProject2 is aware of some changes in CoreStuff that are currently in Development and wants to utilize that version?
Not sure if the best approach is to create separate packages for each (seems to require changing your package references back and forth depending on what stage the solution is in) or somehow utilize multiple versions of the same package (not sure if that's easy to manage with NuGet).
Anyone tackle something like this?
The first thing to remember is that NuGet will not automatically update your package references, so if you have already 'linked' your solution to the latest stable package of CoreStuff (say 1.2.2) then there won't be any problems if a newer (unstable) version is provided (assuming that the package you're using doesn't disappear from the package repository). Obviously if you upgrade your package reference then you will get the unstable package.
So the simplest solution is to make sure that you 'link' your project to the stable package by getting it via the NuGet package manager before the other package is released. While the UI only allows you to get the latest version, the Package Manager Console can get any version of a package so you could use that to explicitly provide the version number, e.g.:
Install-Package CoreStuff -Version 1.2.2 -Project CoolProject1
If that is not a solution then there are several other options to tackle this problem:
Give the development version a different semantic version that indicates it is a unstable version, e.g. 1.2.3-alpha. In this case CoolProject1 could pull in package CoreStuff.1.2.2 (which should be latest stable version in your repository) and CoolProject2 could pull in CoreStuff.1.2.3-alpha (which would be the latest unstable version).
Have multiple repositories, e.g. one for stable (released) packages and one for unstable (development) versions. Then you can select your packages from the desired repositories. If you wanted to you could make it so that only your release process can push packages up to the stable repository and your CI build pushes up to the unstable one (so that you always have the latest packages available)
If the developer of CoolProject2 just wants to develop against the latest version (but will wait to release CoolProject2 until after CoreStuff v.next has been released) then he could potentially create a local package repository (i.e. a directory on his drive) and put the new package of core stuff there. That way other developers won't even see the package.
The most important thing will be to make sure that you don't get CoreStuff.1.2.2 and CoreStuff.v-next in the same repository if CoreStuff.v-next simply has a higher version number, because in that case the NuGet UI won't let you pick v1.2.2 (but the Package Manager Console does!).
If you would want to switch from one package type to another you'd have to do a manual update (which you always have to do when changing to the next package version anyway), but that's not a bad thing given that this forces a developer to at least check that the update of the package doesn't break anything.
We have two separate .NET solutions:
Running a build for the first solution produces our end product: a bunch of DLLs. These DLLs are delivered to our customers via a NuGet package.
The second solution serves as a product-test solution: the NuGet package is installed to it, and it is built and executed - thus it makes use of our product exactly the same way as our customers would do.
The challenge here is that there should be a way our latest NuGet package gets installed automatically to the product-test solution, preferably during the build of this product-test solution.
Based on the ideas from a similar question, I got this far with configuring the product-test solution:
First I enabled NuGet Package Restore. This lets me get rid of the "packages" directory completely from VCS since the package with the version defined in packages.config file would be downloaded automatically by NuGet before build.
Then I added the following pre-build event in Visual Studio: $(SolutionDir).nuget\nuget update -prerelease $(ProjectDir)packages.config. This lets me pull in the latest version of our NuGet package during build.
I currently use the above scenario to run local builds using Visual Studio and unattended builds using TeamCity. The solution seems to work for both scenarios on the first sight, but actually it does not produce the expected result: when the product-test solution is built, in the bin directory I don't get the latest version of the DLLs, only the latest-1 version.
The problem is that although the nuget update command updates everything as expected, including the packages.config and the .csproj file, their new content is not picked up by the build, therefore - as my guess goes - the HintPath settings from the .csproj file still reflect a "before build" state, therefore old DLLs are copied to the bin directory. I assume the .csproj file is processed only once: before the pre-build event is triggered, and the changes made by the pre-build event are ignored until the next build.
I considered the following solutions:
Apparently pre-build is not "pre" enough. If there was an even earlier point I could insert the nuget update command, my above solution would probably work.
I read that I could override the HintPath-s in the .csproj file by defining a ReferencePath. But I doubt I could easily figure out the right path or I could set it early enough so the build picks it up.
As a workaround I could run the builds twice: duplicate the build step for the product-test solution in TeamCity and I could always build the solution twice locally in Visual Studio.
Has someone figured out how to automatically update a NuGet package to the latest version during build?
Have a look at a blog post I just did regarding this process. Instead of configuring stuff on the server, I did it by augmenting the Nuget.Targets file that's put in place with the Nuget Package Restore option. Beauty of this approach is it executes locally AND on the server (so you get to see any possible side-effects before breaking the build)
Posted details here: http://netitude.bc3tech.net/2014/11/28/auto-update-your-nuget-packages-at-build-time/
I think that put automatic update to pre-build step it's not NuGet style. You can understand that you need this operation every time when you do it. Mostly because it can increase build time. For example when you use TDD and often rebuild project and run tests, you expect that it will be done quickly. Additionally it can update unexpected packages and break something, after that you can spend a lot of time to find the problem.
I suggest to do update as the separate step. On TeamCity you can use NuGet installer build step. For performing update just check two checkboxes in the bottom area of step configuration:
Additionally if you want keep result of update after successful build and passing test, you can add later build step which commits this changes to VCS (using cmd or PowerShell for example).
When you are working locally, I thing the better way run update packages once before you start working with project. You can use Package Manager Console for this, with command Update-Package -IncludePrerelease.
The MSBuild-solution I figured out is to override the BuildDependsOn property. Therefore, I created an UpdateNugetPackages.target which looks like this:
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="14.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<PropertyGroup>
<BuildDependsOn>
UpdateNugetPackages;
$(BuildDependsOn);
</BuildDependsOn>
<UpdateCommand>"$(SolutionDir)pathToYourNugetExe.exe" update "$(SolutionDir)NameOfYourSolution.sln"</UpdateCommand>
</PropertyGroup>
<Target Name="UpdateNugetPackages">
<Exec Command="$(UpdateCommand)"></Exec>
</Target>
</Project>
The UpdateCommand defines where, and with which arguments the nuget.exe gets called. Feel free to adopt this for your own needs.
This target has then be referenced in your .csproj File. As simple as that:
<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
...
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<!-- After the initial decleration of the BuildDependsOn-Property. -->
<Import Project="UpdateNugetPackages.target" Condition="Exists('UpdateNugetPackages.target')" />
Keep in mind, that the import order matters. You have to import your target-file (UpdateNugetPackages.targets), with overrides (or actually decorates) the BuildDependsOn property, after the target-file Microsoft.Common.targets which defines it. Otherwise, the property will be redefined and will remove your changes, as the initial definition in Microsoft.Common.targets does not include any existing value in BuildDependsOn. Microsoft.Common.targets is imported by Microsoft.CSharp.targets for a C# project. Thus, your import has to go after the import of Microsoft.CSharp.targets.
I know Package Manager like NuGet help us when we want to use third party components.
From Nuget Codeplex Page:
NuGet is a free, open source developer focused package management
system for the .NET platform intent on simplifying the process of
incorporating third party libraries into a .NET application during
development.
There are a large number of useful 3rd party open source libraries out
there for the .NET platform, but for those not familiar with the OSS
ecosystem, it can be a pain to pull these libraries into a project.
Let’s take ELMAH as an example. It’s a fine error logging utility
which has no dependencies on other libraries, but is still a challenge
to integrate into a project. These are the steps it takes:
Find ELMAH
Download the correct zip package.
“Unblock” the package.
Verify its hash against the one provided by the hosting environment.
Unzip the package contents into a specific location in the solution.
Add an assembly reference to the assembly.
Update web.config with the correct settings which a developer needs to search for.
And this is for a library that has no dependencies. Imagine doing this
for NHibernate.Linq which has multiple dependencies each needing
similar steps. We can do much better!
NuGet automates all these common and tedious tasks for a package as
well as its dependencies. It removes nearly all of the challenges of
incorporating a third party open source library into a project’s
source tree
these steps are simple tasks that we do when we want to setup a project. its only for automation of adding 3rd party components and decrees chance of Error in configuration files? or it has much more responsibilities !?
It's value is hidden in the open: a package manager such as NuGet helps you dealing with software dependencies using automation. Many make the assumption that it's only meant for open source or third party components, but you could equally as well use it for your own internal packages.
The great thing about NuGet is (to name a few benefits):
NuGet encourages reuse of components because you implicitly rely on actual "releases" (even if pre-release), instead of branching sources
you can get rid of binaries bloating your VCS repositories (package restore feature)
it forces package creators to think about the way the package will be consumed and leaves them dealing with configuration of the component during package installation (who knows best how to configure the package than the package creators?). Think about ELMAH as an example.
automating package creation and publication on a package repository effectively is a form of continuous delivery (for software components). OctopusDeploy even takes it a step further and enables packaging entire Web sites ready for deployment.
NuGet encourages and sometimes enforces you to follow some ALM best practices. E.g. a package has a version, so you have to think about your versioning strategy (e.g. SemVer.org)
NuGet integrates with SymbolSource.org (which also has a Community edition to set up your own): this allows one to easily debug released packages without having to ship this info all the time
having one or more package repositories makes it easy for the organization to maintain a dependency matrix, or even build an inventory of OSS licenses that are in use by several projects
NuGet notifies you about available package updates
Creating packages makes people think about component architecture (all dependencies should be packaged as well)
Dependencies of a package are automatically resolved (so you can't forget any)
NuGet is smart enough to add assembly binding redirects when required
The above list is non-exhaustive, but I hope I covered the key benefits in this answer. I'm sure there are more.
Cheers,
Xavier
Reason to use NuGet is you don't have to ship all the libraries in your project, reducing the project size. With NuGet Power Tools, by specifying the package versions in the Packages.config file, you will be able to download all the required libraries the first time you run the project.
Live Exapmle : Reduced project size matters while deployment of project.Like if solution
have 500Mb of code and 200Mb of packages size then extra 200mb really
cost to upload project each time.Instead of uploading concrete
dll files we need to just set their reference in packages.config file.