Team City NuGet Server not publishing all package versions - teamcity

We are using Team City 9.1.5. Our main application is very old and complex, and over the years we have had to write several utilities to support customers. The utilities need to reference application components, and multiple versions of the utilities are maintained to correspond to different application versions.
To avoid creating a new release of the application every time a utility needs to be updated, we are using the Team City NuGet feed to host versions of our application's dlls. These are then referenced by the utilities in Visual Studio, etc.
The original solution was to create a separate build configuration for NuGet packages for every released version of the application. These are manually triggered to reduce the number of packages for a specific version of the app (i.e. I don't need a package for every build, just stable).
Over time, the number of supported versions of the application has grown, and so has the number of NuGet package build configurations. I am trying to consolidate these separate build configurations into a single build configuration with multiple build steps - one step per version. But when run, Team City will only publish the latest version of a package from a single configuration. Examination of the configuration's artifacts show that all all of the different versions are built and retained, but only the latest is published.
When I break the exact same build steps out into multiple configurations, one build step/configuration per version, the artifacts all show up again.
Is there a way to get Team City to publish all of the artifacts from a single configuration, even if there are multiple versions of the same package?

Per JetBrains, "Unfortunately it's a known bug in TeamCity: https://youtrack.jetbrains.com/issue/TW-40363, please vote for it."
My solution for now is to go ahead with the separate build configurations, although that will add maintenance overhead and "noise" to the TeamCity projects page.
We are also discussing an alternative solution of using one build configuration and pushing to a separate nuget package feed other than Team City's.
Neither of these options is desirable as both will require additional resources to implement.

Related

Nuget version and release management like maven release plugin

I am more experienced with Java than dotnet. But, recently I have started working on a dotnet Project and I have to write CI process for this Project.
I use maven for Java. And Where is a maven release plugin. Basically, You use snapshot version during development time. and when you ready for a release candidate or release. You use maven release plugin and it update all pom files and commit the new version for you.
Is there a similar tool for nugget to automatically update version number and put tags like RC, RELEASE etc. What approach should I use.
Not: We are usign TFS 2015 for CI process. I can take advantages of TFS capabilities.
There is a tool called Release Management in TFS, an essential element of DevOps that helps your team continuously deliver software to your customers at a faster pace and with lower risk.
Since you are also using a continuous integration (CI) system and you
could use TFS release management as a fully-fledged continuous
delivery system. You could set up Release Management to automatically
deploy new builds to multiple environments.
As for version nuget package you could take a look at below blog which shows you how to hold CI packages(part1) and share packages using Release Management(part tool) with the help of NuGet Publisher task.
Versioning NuGet packages in a continuous delivery world: part 1
Versioning NuGet packages in a continuous delivery world: part 2
Not sure maven how to handle the tags and equivalent in TFS, there is a tag in tfs build, you could add the tag manually or through API, which builds actually be tagged for easy searching.
As for snapshot, there is a corresponding thing in TFS called labels, you could directly build labels.

Debug and release nuget packages local repository

We are experimenting with nuget for our visual studio projects. However, we only (or at least mainly) use nuget for our own external references, and we store them in a local repository (network share). What I would like to know is how to handle the whole debug/release situation.
Concrete (simplified) situation:
We have a main project that has references to two shared components that we developed ourselves. These shared components are also used in other products of our company
When we build the main project (azure pipelines), we build the debug and release versions of the project. However, we can only specify a single nuget package for each external reference.
What we want to accomplish to to use the debug version of the shared components during the debug build, and the release version during the release build. However, these are (as far as I know) actually different packages.
What is the way of tackeling this issue? Is there, for instance, a way to include both the release and debug versions in a single nuget package? Is it possible to have to different nuget configurations for different build configuration settings?
I've found Best practices with Nuget: Debug or Release?, however this topic doesn't really address my issue. This thread is more a discussion about whether to publish debug or release versions to a remote server. We want to publish both and use both in a private repository. We have no intention of sharing our libraries with the rest of the world.
A NuGet package will normally hold just a single set of assemblies for a particular target framework. It is not really designed to ship a debug and release version since you are publishing the NuGet package to be consumed by other users. Normally you do not publish a debug and a separate release version of your application to end users.
You may be able to workaround this by using a custom MSBuild .targets file in the NuGet package that has its own references and configuration information. You can use this .targets file as an extension to your project. It will be imported so you can define the references as you need based on the configurations defined in your project. It is not ideal but it should work.

Publishing NuGet Packages - TeamCity

I have just setup TeamCity to automate our builds, our current solution has both a dev and main branch. What I am trying to achieve is to have the development branch build and publish to a development NuGet feed on our ProGet installation, and then have the main branch publish to our Main NuGet feed on ProGet server.
We are using octopus deploy to deploy the packages, within TeamCity we have the octopus deploy plugin installed and if I tick the box to run OctoPack it builds the packages and they appear as artifacts when the build completes. If I try to use the NuGet Pack build step in TeamCity I get the following error for one of our projects:
[08:33:49] : [pack] Attempting to build package from 'xxx.csproj'.
[08:33:50]W: [pack] Unable to find 'xxx.exe'. Make sure the project has been built.
The project has been built and it works with OctoPack so why isn't it working with the NuGet Pack? Wwe have five projects being built and the first four run fine, one is a console app, one is an mvc website, and two are class libraries. The one that doesn't work is a windows service.
The end goal here is to publish these packages to a private feed on ProGet. I don't mind using OctoPack but in my head wanted to remove that dependency from TeamCity but I can live with it. However when I try to use the NuGet Publish runner type how do I select to publish any NuGet artifacts that have been created?
I have been googling like mad and I cannot find any helpful links that describe what you are supposed to enter, I would really appreciate any helpful comments/answers.
We are using version 8.15 of TeamCity.
Hopefully the following will help with at least part of your question; mainly the bit relating to how to publish packaged artifacts.
NuSpec Approach
When using the NuGet Pack build step, you can specify the Output Directory, which will determine the output location of the packages. You can specify this as a relative path to the checkout directory, probably best to define it as a build parameter, such as %system.PackageDeployOutput% as you'll be using it in the next step...:
Next, specify a NuGet Publish build step, fill in the Package Source / API key etc, and specify the Packages to upload as
%system.PackageDeployOutput%\*.nupkg
This will pick up the packages output in the previous step. I've used this quite effectively, and the parameterisation approach encourages conventions across all your builds.
OctoPack Support
If you're using the MsBuild build step with OctoPack, you can use a similar approach by declaring a system parameter called
system.OctoPackPublishPackageToFileShare = %teamcity.build.checkoutDir%\%system.PackageDeployOutput% (note the same parameter as above)
You can declare these as root project parameters, so you get the best of both worlds. My preferred approach to packaging is currently to use nuspec files for deployable endpoints. I've found OctoPack to be a bit of an overhead when it comes to more complex deployments (it's fine for basic MsBuild projects).

Visual Studio, Plugins, and Nuget

Normally "continuous package integration" involves source control, a build server, and participating teams fetching updated packages as often as they like. But I'm looking for a more extreme version of this story - without CM - that happens entirely on a developer's machine, all in one swoop. A more detailed description of what I want goes like this...
Using Visual Studio 2010 or 2012, assume a "foo.csproj" application that implements a plugin system. Each plugin represents a nuget package and has a corresponding Visual Studio project. Each of these projects is part of the same VS solution that contains the base application.
I want the following development story:
Change source code for a plugin.
Build solution, or perform a debug-launch, which causes msbuild to...
rebuild the changed plugin(s)
nuget then packages and uploads each plugin to a local repository (which can be just a subfolder of the VS solution)
rebuild the base application.
refresh the base application's nuget-plugin dependencies, which were just updated in prior steps. Notes:
This assumes MSBuild magically knows not to perform this last step until all plugins are built, packaged, and uploaded.
The "foo" application could itself use nuget.core to refresh the packages, but in this case I'm assuming that the VS build process did this step.
I would like to know if this story is common enough that there are "common" (msbuild?) scripts for this.
My own guess of how this should be handled is as follows:
All plugin projects are placed in a common "Plugins" folder somewhere in the VS solution folder structure.
The base application "project dependencies" are configured with references to all the plugin projects.
Note: I don't like the idea of managing these project dependencies manually.
The base application "foo.csproj" has a build step that scans the "foo.csproj" XML for dependencies it has in the "plugins" folder, and initiates the nuget packaging and deployment for each.
The base application then initiates the nuget "update all". Hopefully this is possible even though msbuild already mid-stride in execution.
In short, the base application is able to instantly consume plugins that have been altered. This is done without check-ins, a build-server, or manual and arbitrary requests to update plugin packages.
If pre-existing scripts do not already exist for this story, then I'll make my own. But I'd still like to know:
Can step 2, immediately above, be converted to something generic? That is, how can I convince msbuild not to build the "base application" until all projects in a particular folder have already been built? Remember, I'd like not to manage the project dependencies manually.
Is there anything flawed with this overall approach?
I would be particularly interested to know if there is an already existing nuget-visual-studio integration that assists with this story that I may have overlooked.
That's quite a long question to answer, so not sure I'm covering everything in this one; I'll do my best. First, your scenario is not uncommon. The first 2 steps of your planned approach seem OK to me (you're free to choose the location of the plug-in projects).
One thing's for sure: you'll have to manually define the build order, because your solution has no idea of knowing whether the projects consuming (NuGet) plug-ins have a dependency to the projects containing the source code for those plug-ins. Instead of using the built-in Build Order dialog in Visual Studio, take a look at this post on the MSDN blog for a correct way of doing this (or you might end up with something that works locally but not on the build server).
The key MSBuild elements in the referred post are the following:
<ProjectReference Include="... foo.csproj">
<ReferenceOutputAssembly>false</ReferenceOutputAssembly>
</ProjectReference>
Now, as for the packaging, deployment and consumption of those plug-ins:
Each plug-in project should trigger package creation and publication in a post-build step. This post on my blog contains ZIP-download with quite lot of MSBuild stuff you can use to get started. E.g. I version, package and publish the NuGet package for a class library in Release builds. I'm using the NuGet command line tool to pack (command reference) and push (command reference) the package.
The consuming application project(s) should run NuGet.exe update <packages.config> (command reference) in a pre-build step.
Also pay attention you're NOT running builds in parallel.

Is it possible to share huge data between projects when the data is installed by Nuget?

I found that nuget seems to always install packages under the folder of the visual studio project.
It is not feasible for me because the package that I'm going to distribute contains huge amount of data. I don't want to make a copy of that whenever I add that package to a new visual studio project.
I want that data to be shared between projects. Since it is shared, if one project removed that package, the data should stay there until I explicitly tell the system to remove it.
Is there any way that can deal with this kind of problem?
I heard that Maven installs packages in a global location and it doesn't have such a problem. How about using Maven to install .NET libraries, is that possible? What would be the potential problems?
To upload and store your .NET artefacts you'll need a Maven repository manager like Nexus, Artifactory or Archiva. Good news is that these are capable of storing files of any type.
If you don't fancy converting your build process over to Maven, I'd recommend the following answer on using Apache ivy with MSBuild. All Maven clients appear to cache their downloads for use across projects (They're basically intelligent downloaders)
The upcoming 2.0 version of Nexus promises integration with NuGet. I'm expecting better .NET support from Maven in the future.

Resources