This project is read-only.

Feature: "Update Packages" in Build Process Template

Dec 8, 2011 at 1:18 AM
Edited Dec 15, 2011 at 4:50 AM

TfsNugetter looks excellent, but what I am looking for is a build process option that performs an optional NuGet Package Update for all build targets as part of the build process (before any content is built, after the latest version of source has been synced into the build workspace.)

I'm on the verge of implementing this component ourselves internally, but would much prefer adopting a well-rounded public solution such as TfsNugetter. It appears to provide all the features we can think of, except the ability to perform a package update before building.

This request is being born out of the need  to implement proper CI, and we would like proper CI against our nuget packages (without customizing build targets for nuget package updates, which is likely the option we will adopt in the short term.)

Thanks!

 

Shaun Wilson // Senior Software Engineer // Corporate Applications // Blizzard Entertainment

Dec 8, 2011 at 1:21 AM
Edited Dec 15, 2011 at 4:50 AM

Since multiple solutions may be part of a single build definition, it may make sense to implement such an activity to either:

1) Auto-discover nuget configs relative to each build target.

-or-

2) Allow for a list of configs to be input by the user, semicolon separated TFS Paths would work just fine.

 

Shaun Wilson // Senior Software Engineer // Corporate Applications // Blizzard Entertainment

Dec 12, 2011 at 4:19 PM

Shaun,

Are you asking for the build to go and get the NuGet packages utilized by your application at the time of build meaning, the packages versions that your app is expecting

OR

Are you asking for the build to go and get the latest versions of the NuGet packages utilized by your app?

OR

do i not understand what you are asking for? :)

Mark

Dec 15, 2011 at 4:48 AM
Edited Dec 15, 2011 at 5:27 AM

In particular we need behavior #2 as you described it (would be perfect!) the goal is CI against the latest outputs, e.g. we have Solutions (build targets) which utilize NuGet, and as part of our build process we would like to have the latest version of all NuGet packages pulled into the build workspace before Solutions get built out.

It seems like an inappropriate/junior approach for us to edit our csproj or modify pre-build steps in our projects to update packages which would be "the other alternative" to us creating yet another TFS Build activity that probably won't get a lot of TLC/improvement.

I can make the case for #1, but it's not a problem we need to solve. We already have the packages from the time of the development checked into TFS alongside the target solutions (as most people do.)

Sorry for not being more clear :) also, thank you. 

 

Shaun Wilson // Senior Software Engineer // Corporate Applications // Blizzard Entertainment

Dec 17, 2011 at 6:13 PM

Shaun,

Ok, got what you are trying to do.  This is an issue that the NuGet guys have been wrestling with for a while.  Just so happens that this week they released version 1.6 of NuGet which advertises to solve this kind of problem.  They provide an answer for option 1 above.  That is, NuGet will go download the NuGet package version that your application is expecting not necessarily the latest version.  I agree with that portion of their answer for this reason: if you try to get the latest version rather than the one you app was developed with then you could be introducing breaking changes into your app at the time of build.

The way they fix the problem is an issue for me though.  You literally have to modify your project files and include a .targets file and NuGet.exe.  It is done through a right-click menu choice but the project modifications are still required.  To me, this is exchanging one (albeit larger) issue with another one.  In my opinion, the build alone should be able to manage the situation without modifying projects and including extra files to support the build in every project in every solution.  I get that this is a one size fits all approach but still.

I am going to attempt to create a solution that will work on TFS without modification of solutions or projects.  However, this is a general build issue not a NuGetter issue since all of this occurs before NuGetter even starts. 

I do think it should be part of the build so I will update the NuGetter (and TfsVersioning) build templates to include it when I complete it.

Stay tuned...

Mark

Dec 18, 2011 at 10:15 PM

This is important to understand: the very purpose of syncing the -latest- version of all packages is to break the build and find bugs during tests. That is the core purpose of CI. That is precisely what we need. We're aware of their other efforts which do nothing to perform CI.

I can explain CI(Continuous Integration) in more detail if necessary.

I think both 1 and 2 have value, and that it could probably be made a simple option "Get Latest" instead of specific version in build process.

We, and anyone else doing formal CI, require the latest packages whether they break or not. We *want* the update to break and fail the build; in a large company this is part of quality control, it allows us to find breaking changes the moment they go into TFS.

Thanks

 

--- sent from mobile.

 

Dec 19, 2011 at 4:27 PM

I believe I'm good on CI.  The fact that you are trying to break code by introducing potentially major changes in the dependencies as well as the code is somewhat different than what I would call the typical CI approach of maintaining relatively consistent dependencies i.e., changes in "minor", "build" or "revision" may be allowed or even expected whereas, changes in the "major" may not.

Whatever the approach, you're looking to this as solution to a testing issue and the answer that I am working on should provide you with what you are looking for.  It is dependent on the NuGet.exe functionality so we will see after some testing.

Again, this isn't a NuGetter issue/solution.  It is a general application build issue: not having to store nuget packages (dependencies) in source control and still be able to build your application.  But, the answer may satisfy both requirements.

Regards,

Mark

Dec 19, 2011 at 8:39 PM

I believe you are on the right track, but wanted to clarify a couple of points for the sake of completeness/clarity:

"The fact that you are trying to break code by introducing potentially major changes in the dependencies as well as the code is somewhat different than what I would call the typical CI approach [...]"

http://en.wikipedia.org/wiki/Continuous_integration

"Continuous integration – the practice of frequently integrating one's new or changed code with the existing code repository – should occur frequently enough that no intervening window remains between commit and build, and such that no errors can arise without developers noticing them and correcting them immediately"

One of the primary goals of CI is to detect breaking changes the moment they are comitted by (1) replicating changes to all dependents, and dependents to their dependents, in a cascading fashion until all dependent code has been updated so that (2) tests can be run for all dependent code to detect breaking changes relative to particular commits which are then investigated or rolled back before too much integration debt is accumulated.

With NuGet we need to solve this problem non-traditionally. Traditionally, with CI, when dependencies are produced they would be checked into source control such that dependent products would be built against the latest dependencies (packages). With nuget this is a problem because dependencies are retained in versioned subfolders and referenced using hintpaths in various project files. Thus, we need to rely on nuget tooling to perform updates prior to build (as opposed to updating dependents when dependencies are built.) This is a slight deviation to most CI implementations/processes, and it's because of our adoption of NuGet. I'm unwilling to sacrifice NuGet to acheive full CI again (we sacrificed full CI when we adopted NuGet.)

"It is a general application build issue: not having to store nuget packages (dependencies) in source control and still be able to build your application."

I see that NuGet Dev is currently solving a problem where packages are not stored in source control and that they need to be retrieved at the time of build. This isn't our particular problem, we have the nuget packages committed to source control which developers have implemented against. Thus, we can build products without a problem right now. Unfortunately, we cannot perform proper CI because proper CI requires the latest version of packages to be acquired prior to build. This is where I believe TfsNugetter can "come to our rescue". If/Wehn TfsNugetter can perform package updates as part of the build process (regardless of the packages already existing on disk or not) then our CI problem will have been solved, along with the CI problem the rest of the world has yet to bring to everyone's attention. We're not the only development shop which performs CI, and without this behavior I imagine many development teams will not adopt NuGet because they are unwilling to sacrifice their existing CI processes. We sacrificed our CI processes in favor of NuGet package management (we love it!) Unfortunately, the lack of CI has been biting us in the ass for several months and it's a problem we absolutely need to solve.

So, again, thank you so much for tackling this. We've got dozens of libraries and dozens more products which need proper CI at this point.

 

Shaun Wilson // Senior Software Engineer // Corporate Applications // Blizzard Entertainment

Dec 21, 2011 at 7:59 PM

I created a couple of TFS build templates that will restore/install NuGet packages during the build.  That is, NuGet packages do not have to be committed to source control for your application to build.  The packages are downloaded during the build process from the provided NuGet Galleries.

I have also created a second template that goes one step further and updates the packages to the latest version or the latest "safe" version.

All of this is done using standard NuGet functionality but controlled through TFS 2010 build workflow.

As this is not part of functionality specific to NuGetter, the templates were created utilizing the standard TFS default template as a base so the functionality can be copied over to any other template.

The description of the solution can be found on my blog: http://marknic.net and more specifically the page is http://marknic.net/2011/12/21/using-nuget-in-tfs-without-committing-packages-to-source-control/

Dec 24, 2011 at 4:47 PM

I am working on a major system re-write for a "large" insurance company, and we have a very similar problem as described by SEWilson. We will have a "futures" feed for rapid, tight integration cycles, with daily publication and consumption (not for our CI builds, we aren't being that "aggressive", yet :)).

The problem we wish to avoid is a consumer of this "futures" package feed binding themselves to a package version that doesn't make the "stable" feed (probably off our Main daily build, TBD). In other words, we will have quite a few builds (versions) published from our "vNext" branch that never make it to Main. FI to Main will probably be weekly, but is really project milestone driven, so it could be bi-weekly.

Additionally, some package consumers will only want to consume the "stable" feed, so their package dependencies should not be "automatically" updated.

I am thinking the logic should be: If your package dependency version exists in the "stable" feed, Team Build does nothing. If your package dependency version does not exist in the "stable" feed, one of 2 things could happen:

1 - Fail the build and report the issue
2 - Update to the nearest higher version, possibly using the Build Version Patterns defined by this API, or something similar.

So this is our problem on the package consumer side of the equation, again, very similar to SEWilson's problem.

Additionally (distinct problem), we have individual VS solutions that publish multiple packages (currently using MsBuild and a simplistic build activity). We would like to continue to support this capability - is this supported by TFS NuGetter?

Thanks for any help!

Bruce Krakower / Architect / Some Company

 

Dec 24, 2011 at 5:59 PM

Bruce, I wonder if "Some Company" is the same "large" insurance company I am currently consulting to right now. :-)

Wow, there's a lot going on with your message.

Consuming of NuGet packages is not part of NuGetter - that is a general build/compile requirement.  NuGetter's purpose is strictly the creation of packages.  However, to create packages, you very likely have to consume them.  So, as an initial answer to this, I created the build templates that are available through my blog (http://marknic.net). (They are NOT NuGetter specific.  The templates are modifications of the standard TFS default build templates.)

Those templates allow you to dynamically pull down NuGet packages as part of the build process rather than including them in source control.  The second template that I included does the same download as the first plus dynamically updates the packages with the latest (insert your definition of the latest here) packages.  To do all of this, your projects ("**proj) files must be updated on the fly.  All of this is managed using the NuGet application so the capability it provides is the functionality you get here.

Note: you can still use these templates even if you include NuGet packages in source control.  The process will skip over things that are already there.

To control the meaning of "latest" take a look at the NuGet documentation for more specific definitions to what I describe below.  There are a couple command line parms as part of "update" that let you dictate what kind of update process will happen (http://docs.nuget.org/docs/reference/command-line-reference):

  • No additional parameters: the latest published packages will be used
  • "-safe": the latest published, non-breaking change release will be used
  • "-prerelease": the latest non-published but available packages will be used
  • "-safe -prerelease" the latest not yet published/non-breaking change packages will be used

You can include these additional parameters in the templates that I created.  Hopefully the combinations above will satisfy your needs.

<myOpinion>One thing I feel I should add.  I completely understand why you would want to do this dynamic update to the latest version from the point of view of testing but I really don't see it as a CI philosophy since you could be changing application code and dependency assemblies at the same time (during the build) therefore creating situations where failures in the tests could be very difficult to use as indicators of the real problem.  Your code may not even compile.  Also, more importantly, it could mean that the application you have in production does not match the code you have in source control.</myOpinion>

As for using this in NuGetter (or TfsVersioning for that matter) I still need to create updated templates for them.  I've started in NuGetter but haven't finished yet.  As with any project, time/resources is the biggest limiter.  One of my biggest wishes for the new year is a more modular TFS build workflow system where you can include external template "subroutines" rather than creating monolithic templates.

I tried to make the restore/update section in the templates as tight as possible so you could copy/paste them into existing templates.

Lastly, NuGetter relies upon the solution and configuration to determine what it packages.  So, I don't think we have parity with your MSBuild script.  I realize that I don't have a full understanding of your environment but I am trying to figure out the benefit of doing this (other than the obvious getting it all done at once).  I can see very real versioning issues with this approach.  Also, questions like: is it really necessary to always build all of that code all of the time?  If there's a framework that the various target packages have in common, then maybe that should be a separate package and a dependency of the main packages.

Anyway, hopefully this answers some of your questions,  Happy Holidays and Festivus for the Rest of Us!

Mark

 

Dec 27, 2011 at 1:57 PM

Thanks - I'll check out the template. Also, thanks for the details on the NuGet options...looks like OOTB functionality we can use; I'll dig into that further.

BTW, I'm not presenting this as a CI philosophy; just a practical reality to ensure teams who want tight integration cycles properly consume versions of packages as we forward integrate to Main (orthoganal to your opinion if this is CI or not). We would not merge anything to Main that didn't build :).

Regarding "my MsBuild script" (actually it is not an approach I devised, but it has been working to date), we do have scenarios where we create 2 packages from a single solution; for example, we have some bits that are hard to unit test, so we package libraryX and libraryX.Testability from the same solution, to facilitate consumer unit testing. This probably wouldn't be that hard to accomplish from a solution / build artifact point of view, particularly with an XML config and custom build activity.

Regarding versioning, we use the fairly common practice of a solution level Assembly Version Info file that is added as a link to all projects. Team Build manages our version numbers. This does force some governance to make sure solutions are configured to spec; also a solution is always versioned as a single unit in this scenario. Maybe not ideal, but this practice hasn't yet broken down for us. Do you see any gotchas with this approach?

So we aren't in a bad place, just looking to tighten up the automation and integrate accross tiers and boundaries earlier and in a more automated manner