16

We want to use NuGet to share assemblies amongst developers in our organisation. We are currently looking at setting up three NuGet feeds, like this:

  • Release-feed: Stable release-quality versions of the assemblies.
  • QA-feed: Assemblies built in the master-branch (our integration branch).
  • Development-feed: Assemblies built in any of the feature branches (sharing progress).

Local builds on the developers' machines should not be sent to any of these feeds. Only the builds done by the build-server is to do these. Our build server performs three different types of builds, depending on the branch, Development, QA and Release branches. Each of these with corresponding build-configurations that triggers on source changes. On build each of them will push the built assembly-nuget-packages to their corresponding feed. The Development-builds will add "-dev" to the version. The QA builds will add "-qa" to the version, while the Release builds will have a "pure" version number.


Now, questions:

  1. What would be the best solution for the dev to control what packages to use? I guess the dev manually have to edit the dependency source param to explicitly define what feeds to get the assemblies from: Sometimes you want the release assembly, sometimes the QA assembly and sometimes you even want the bleeding edge Development version.

  2. We are also considering pushing local build packages to a local private feed on each devs' own machine, to help speedup the builds. Would that be problematic in terms of which feed(s) to get from?

  3. If those definitions are made by the dev in the dependencies-file (which is also necessarily version controlled) then that setting would be brought into the Development feed when the source is committed to the repo (same focus for the build as the developer, just sharing with others). This may or may not be the right thing for the Development feed?

  4. When the source is then merged into a qa-branch the feeds defined in the dependencies would still be as the dev made them, possibly getting assemblies from Development feeds. For the QA builds I think this would probably not be what we want. QA builds should probably constraint the feeds to Release assemblies only, as you want to see if the changes works as expected with Release components. You don't want to test it with other "untested" QA assemblies. Does this make sense to others too?

  5. In the release branch the release builds should use only release feed assemblies, I guess? I have a feeling that there might be consensus on this, so maybe not not really a question at all :).


So, to sum up the process suggested... During builds we are to:

  • Follow the sources set by the dev in the dependency-specifications for local and Development builds.
  • When doing QA and Release builds the feed should be limited to the Release feed.

As a side note, the QA feeds won't actually be used by any other builds. But, they will be used by the QA department, as they will use these for testing.

Spiralis
  • 3,232
  • 2
  • 39
  • 53
  • How many developers are involved? How many dev teams? The pattern you need is very different if we're talking 5 developers compared to 50 developers. – Matthew Skelton Feb 01 '14 at 23:10
  • We are about 7 now, but plan to double that size over the next year. – Spiralis Feb 02 '14 at 12:07
  • Okay, thanks, Spiralis - this helps for this question, and the one at http://stackoverflow.com/questions/21467094/nuget-issues-with-packages-config-project-references-and-the-solutionwide-packa – Matthew Skelton Feb 02 '14 at 12:51

1 Answers1

14

In my view, the process you suggest is too complicated, both for your team size now and for the team size a year ahead.

I understand the reasons why you think you need three separate feeds (Dev, QA, Release), but I predict this will become painful for you in a year's time. I expect that you want to increase the confidence in the stability/quality of the packages as they progress from Dev to QA to Release - a completely reasonable requirement. However, separate branches and especially separate builds for Dev, QA, and Release is considered by many to be an anti-pattern. Specifically, in the seminal book Continuous Delivery by Humble and Farley, it's strongly recommended to have only a single code base from which builds are taken, and any of those builds should be capable of being promoted to Production if tests pass: "Build your code only once" is the key.

Instead of the pattern you outline, I would recommend that you:

  1. Use a CI tool which allows you to model a deployment pipeline: Jenkins, TeamCity, TW GO, etc. This sets a good precedent for flowing artifacts directly from the initial CI build all the way to Production without a re-build
  2. Use semantic versioning (called SemVer in the .NET world) to protect package consumers from breaking changes, and to communicate the nature of package changes to other teams.
  3. Use version range constraints in packages.config so that builds are not broken by new Major versions of packages (with breaking changes)
  4. Make dev teams responsible for specific packages from code commit to Production - if one of the packages they maintain has problems, they need to provide a fix rapidly so that other teams are not blocked. Teams also need discipline to ensure that they communicate the nature of package changes via SemVer (is it a breaking change? a new feature? a bug fix?)
  5. If you feel it's necessary, use the Prerelease feature of NuGet to 'hide' new package versions from downstream builds and testing. This might allow dev teams to make changes more effectively, but will probably not be necessary if you use deployment pipelines which allow new package versions to be made and delivered rapidly.

In short, only build your source code once, and set up automation such that any fixes to existing packages can be rolled out rapidly using the deployment pipeline.

Matthew Skelton
  • 2,220
  • 21
  • 21
  • Thanks. I am not convinced, yet at least. Builds from dev-branches are for i.e. built with debug-flag and not suitable for release. Also the resulting version-number in the assemblies are created during build and would require rebuild to update. I really would not want the builds to be versioned as if they were a release on the dev builds. There is a danger that one of these could be deployed, just as a test, at a customer site and then forgotten. To anyone this assembly looks like a final build afterwards. It is possible to repackage in NuGet, but the assembly-version stays. – Spiralis Feb 11 '14 at 23:57
  • Have a read of Chapter 5 of Continuous Delivery (it happens to be the free sample chapter): http://www.informit.com/articles/article.aspx?p=1621865 In particular, the pattern "Only Build Your Binaries Once" p.113 The benefits of having *any* build a potential release candidate are substantial: it enables all sorts of good patterns. – Matthew Skelton Feb 12 '14 at 10:42