Reputation: 7407
We use Nuget for our internal development to allow us to share code across teams. We run into issues however when one person is working on code that will be deployed across multiple nuget packages at the same time. For instance
A depends on B which depends on C.
A, B and C have their artifacts pushed to Nuget and that's how we manage the dependencies between A, B and C. The trouble we find is that if a developer wants to make changes in C and quickly see those changes reflected in A, they have to go through the following process.
This seems extremely painful and is causing some of our developers to question the choice of Nuget for our internally developed code. Everyone still like it for consuming external packages.
Is there any better workflow for using Nuget internally?
Upvotes: 74
Views: 18189
Reputation: 14746
Nuget was designed for sharing third party libaries. We plan to use Nuget internally for all common code that can be shared between projects. Things like a common data layer, string and other regular expression functions, email components and other artifacts like that.
The only way I see Nuget being of any help is when the components, code or artifacts you are sharing across teams/projects are stable and have their own release cycle that is different from your project's release cycle. For your needs Nuget is an overkill. You might have better productivity linking all such projects within the same solution. Your solution structure should include the three projects A,B and C as dependent projects referenced internally wherever required.
Upvotes: 0
Reputation: 18098
If A, B and C are under the same solution, you can create NuGet packages for them in a single build.
Just make sure that the using package has the new version number (assuming your build doesn't randomly change it) of the package it depends on.
If A, B and C are intentionally under different solutions e.g. A is under an infrastructure solution and B is under a product solution, then the only suggestion I have for you is to define your CI builds run on check in and not periodically.
Edit:
Another option is to create a push pre-release packages (e.g. version 1.0.0-alpha) to your NuGet server during local builds, this way developers can experiment with the package prior to creating a release version.
Upvotes: 2
Reputation: 2220
You have two choices here:
I have used both, and #1 is a reasonable choice to start with, but NuGet Galley is optimised and designed for nuget.org, not on-premise/enterprise use, so things like deleting packages is a pain (hand-rolled SQL required).
I'd say that you should pay the (low) license fee for Artifactory Pro - it's an excellent product, and the JFrog team are really keen and switched on.
You should not be using nuget.org for internal/enterprise packages; nuget.org is designed for 3rd party/open source libraries, not internal build dependencies.
EDIT: in terms of workflow, why are you putting shared code into multiple packages? If the code needs to be shared, it needs to go in its own separate package.
EDIT 2: To speed up the code change workflow for the developer, you can use nuget.exe
(the command-line client) and use command-line accessible builds, so you can target a "developer" build run. Then in your "developer" build (as opposed to the CI build) you specify -Source as a local path (e.g. nuget install B -Source C:\Code\B
) when you want to pull the newly-updated B
as a dependency and build against that; likewise for C
or other local, newly-updated packages. Then when A
, B
, and C
all build fine, you can git push
all of them (in reverse dependency order), and let CI do its thing.
However, you also should question whether your package separation is really appropriate if you have to do this build 'dance' often, as this suggests that all the code should be in a single package, or possibly split along different lines in separate packages. A key feature of a well-defined package is that it should not cause ripple effects on other packages, certainly not if you are using Semantic Versioning effectively.
Edit 3 Some clarifications requested by marcelo-oliveira: "command-line accessible builds" are builds which can take place entirely from the command-line, without using Visual Studio, usually via batch files. A "developer build" is a build which a developer runs from her workstation, as opposed to the CI build which runs on the CI server (both builds should essentially be the same).
Upvotes: 7
Reputation: 1981
In our company we have solved the cascading updates problem with the following setup. First we have the following setup for our NuGet repositories and build server.
Each developer can have (but doesn't need to have) one or more directories on their own machine that serves as a local NuGet package repository. By using a user specific NuGet configuration the developer can control in which order NuGet searches through the package repositories to find packages.
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<packageRestore>
<add key="enabled" value="True" />
</packageRestore>
<packageSources>
<add key="Dev" value="D:\dev\testpackages" />
<add key="Company" value="<UNC_ADDRESS_COMPANY_REPOSITORY>" />
<add key="NuGet official package source" value="https://nuget.org/api/v2/" />
</packageSources>
<disabledPackageSources />
<activePackageSource>
<add key="All" value="(Aggregate source)" />
</activePackageSource>
</configuration>
All solutions have automatic package restore turned on, so that we don't have to commit the packages to our version control system.
<MAJOR>.<MINOR>.<BUILD>.<REVISION>
then developers can only change the major, minor and build numbers, the revision number is set to 0 except in builds done by the build server where it is the build number of the build. This is important because it means that for a given version consisting of a major, minor and build number the build server will always produce the higher version number. This again means that NuGet will prefer to take the package version coming from the company package repository (which only gets packages through the build server).In order to make a change to one of the base libraries there are two possible processes being used. The first process is:
If more changes are required to (A) then repeat steps 1,2 and 3 and then delete the package of (A) from the working directory of (B). Next time the build runs NuGet will go looking for the specific version of (A), find it in the local machine repository and pull it back in. Note that the NuGet cache may thwart this process some of the time, although it looks like NuGet may not cache packages that come from the same machine(?).
Once the changes are complete, then we:
Another way of doing the development work is by taking the following steps
c:\mysource\projectB\packages\ProjectA.1.2.3.4
)The commit process is still the same, project (A) needs to be committed first, and in project (B) the NuGet reference to (A) needs to be upgraded.
The first approach is slightly neater because this process also warns if there are faults in the NuGet package of (A) (e.g. forgotten to add a new assembly) while in the second process the developer won't know until after the package for (A) has been published.
Upvotes: 43