tfs 2015 build not performing nuget package restore - tfs

I have a bit of a strange situation. 2 applications in the same tfs repository, both using near identical build definitions, both using nuget packages, one performs a package restore, one does not.
Both build definitions contain the 'Restore NuGet Packages' option checked:
both have same .sln and .vbproj file structures.
build log of the 'good' one gives:
and the 'bad' one doesnt:
Build controller/agent is the same, I cant see any difference in the build definition or the solution configuration.
My question is where do I start looking for why these are doing something different?

Turns out the packages.config files for each of the projects were not checked in to TFS, without these there was nothing to restore. Stupid error!

Related

Resolving dependencies in TFS 2015

I have two separate solutions in TFS 2015. We'll call them Solution1 and Solution2. The build for Solution1 creates an assembly which is required by Solution2. I'm not sure of the best way to handle this dependency in TFS.
Possible scenarios could include.
Each time Solution1 builds successfully it copies the new assembly to Solution2 which in turn triggers a build of Solution2 (is this possible in TFS? And if so, how?)
Each build of Solutiuon2 pulls the latest version of the assembly from Solution1
How have other people handled dependencies between TFS projects?
You should package the output of Solution 1 as a Nuget package and publish it to a Nuget repository. You can use a Network Share, MyGet, VSTS, or TFS 2017 as a Package Repo.
Your second solution can then take a dependantsy on that Nuget Package and you choose when to update.
If you want to update the packages automatically you can call something prior to Solution 2 build, like the pre-build step mentioned in comments.
As it was explained in the other answer you can manage it with NuGet deployment. That is the really clear and fancy way.
Another way might be, if you use the same output folder for both solutions, and
you always build Solution1 first.
The third way can be that you always deploy your Solution1 to a specific location which can be referenced by Solution2. It is logically similar to the NuGet version, however you do not rely on that (but this dependency in "normal" cases is IMHO acceptable).
Your actual choose can depend on the environment and on your constraints.

using tfs build pull a prebuilt common components into another build

I'm looking for advice on how to have team build 2013 use a pre-compiled common that is not checked in or part of the workspace.
Everything we build is QNX based and we are refactoring out a common set of components to be shared across all projects. I've looked at Go and NuGet but that seems like a lot effort for something like this.
What is the best way to pull a prebuilt common into a TFS Team Build?
So you would nuget "publish" a package.
https://docs.nuget.org/create/creating-and-publishing-a-package
then your build would nuget restore using a packages.config file (aka, NOT a .sln file)
nuget restore [<solution>|<packages.config file>]
https://docs.nuget.org/consume/command-line-reference
What VS (in a .sln file) is auto-voodooing some of this for you.
But using command line nuget (especially for the restore)....is a way to get a package out of nuget if you're build isn't based on .sln file.
Another way to think about it is...when you run "nuget install" or "nuget update", VS is auto-voodooing you a packages.config file. While you might look at the file and find it interesting, you're not consumed on how it works in the background of VS. But if you want to manually pull nuget packages....you will be very interested in how it is created.
What I would do as a test would be:
Create a dummy .sln,csproj file.
Nuget add a few random packages (using "Manage Nuget Packages for this solution).
Take that packages.config that was auto-voodoo created for you.... and move it to a clean directory.
See if you can run nuget.exe restore on it, and get/pull the packages (aka, you're testing that you can do a pull... without a .sln file being involved).
If that works...than it becomes of matter of creating your own nuget repository..creating your own published-package...and repeating #4 above to get that package out.
Make sense?
So I have these files in a clean directory:
.\packages.config
.\.nuget\NuGet.Config
.\.nuget\NuGet.exe
.\.nuget\NuGet.targets
Then I run in the comamand-window:
.\.nuget\nuget.exe restore .\packages.config -PackagesDirectory .\MyPackages
And all the packages listed in "packages.config" will download to : .\MyPackages
Note, if you have a custom nuget repository, that will need to be configured...but cross that bridge when you get there.

How does TFS know about nuget?

From this article -
"However, there are cases where it’s not actually a person who’s doing the building and who therefore can’t provide consent this way. (And where Visual Studio isn’t even installed.) The prototypical example is a build server. In that case, NuGet will also look for an environment variable called EnableNuGetPackageRestore. To enable package restore for scenarios where the Visual Studio option is not practical, set this variable to true."
How does TFS even know how to call nuget? Do I install the nuget exe?
As you've stated in a comment, "Enable NuGet Package Restore" is no longer the recommended method for accomplishing this. The NuGet docs explain it best. Basically, because that method is integrated into MSBuild, packages that extend the build will be downloaded too late. While I'm not sure what packages do this currently it appears that there are big plans for the future of NuGet (the new ASP.NET vNext custom CLR implementation is one example of where it's headed).
The good news is that the alternative is really easy to set up. If you're in VS, you literally do nothing (unless you've disabled the automatic package restore in the past). If you have a build server you just have to make some small changes to your .proj file. If you're not familiar with MSBuild it may seem challenging but it's really quite simple. The secret is this chunk of code:
<Target Name="RestorePackages">
<Exec Command=""$(ToolsHome)NuGet\NuGet.exe" restore "%(Solution.Identity)"" />
</Target>
Again, the details are in the docs (this one specifically). If you have any questions don't be afraid to reach out: the SO community is here to help!
How does TFS even know how to call nuget? Do I install the nuget exe?
No, you should enable package restore for the solution which can be done from the context menu for the solution file in the solution explorer. This will add a folder named .nuget to your solution and in this folder you will find NuGet.exe.
If you add the solution to source control and build it on a build server the NuGet.exe executable will be used by the NuGet msbuild targets to restore packages from NuGet as part of the build.
So you do not need to install NuGet on the build server - it becomes part of your project and is placed under version control.
If you set your solutions to restore NuGet packages, and then on the build server with the build account, open vs and set Allow NuGet to download missing packages during build in Visual Studio. Your builds should restore packages ok.

Linked file in WCF RIA service does not build in TFS Build server

I've just setup a TFS (2012) server and now I'm trying to build the complete code (written in .NET 4.0 in VS 2010) via the TFS Build server. But in my solutions I have also a WCF RIA project which contains linked files because they are used somewhere else also and there is no possibility to add a reference to a general .NET binary in WCF/Silverlight.
Everything builds without any problem on my development machine but when I check it all in, create a standard build definition and run that build definition I get the following problem. The linked files have usings (UsingNamespace for example) to other projects that are also build by us and build before the WCF/Silverlight but the following error pops up while building through TFS Build server:
The type or namespace 'UsingNamespace' could not be found (are you
missing a using directive or an assembly reference?)'
Is there any solution for this problem that I looked over?
EDIT 1
Just tried to set the Copy to Output Directory propertie of the linked files to Copy Always but this still gives me the same error as I was expecting. The problem is that the linked file is placed somewhere that it can use the usings but the WCF RIA service cannot access/find that using.
EDIT 2
Just tried out my local test TFS where I can do what I want and there I made a build definition with just the solutions needed to make that the project with the linked files builds. This worked without any problem. Then I tried the same on our TFS server with a new build definition that has the same solutions as on my test TFS and here it did not work. The only difference that I know for sure is that my test TFS is TFS 2012 Update 1 and that my production TFS does not have the update 1 yet. I'll try to install it next week.
EDIT 3
I've just updated our production TFS to Update 1 but it is still not working with my temporary build definition which only contains the projects that are needed to build the silverlight application with the linked files. The 2 workspaces are the same on both server and the projects to build are also the same.
You need to specify the workspace information in the Build Definition for the build to use. The workspaces are what the build process copies from source control to the build server. If you don't have everything in the build server's workspace, it can't build properly.
The Source Control Folder in the workspace tab is the location of the files you need from TFS. The Build Agent Folder is a relative path from the build server's pre-defined base location. You'll usually use $(SourceDir)\Folder to specify the "Folder" that your build process needs.
This sounds like an $(Outdir) problem. A build definition in TFS automatically overrides the Bin folder. All Binaries are redirected to the bin folder upon compile. Sounds to me that you are using a mixture of project references and file references. The file references are probably what is causing your build failures.
Example if you compile in the same build the following solutions
Solution1.sln (TFS Build Pass)
project1.csproj
project2.csproj (references project 1)
Solution2.sln (TFS Build Failure)
project3.csproj (references binary output of project 1)
Expectations from TFS out of the box without customizing your workflow is that this simple build will fail. The reason is that in your development box all projects produce output to one destination while in a tfs build your projects will build to $(Outdir).
Some Things to try
Simple (best practice in my view)
Create 1 solution and use project references instead of file references.
Complex
Build using MSBuild project files
Modify your windows workflow to not override the $(Outdir)
Copy the binaries after a build is complete.
Best practice on Automating Builds
Build from command line
Build from cmd a NON vs2010 command line.
C:\Windows\Microsoft.NET\Framework\v4.0.30319\msbuild.exe FullpathtoSolutionFile.sln
Cheers!
Apparently there was just missing the WCF RIA services V1.0 SP2 on the TFS server. If that was installed the problem was solved.

TFS, NuGet, Package Restore Finding projects that needs to be updated?

So the past few days i've been setting up NuGet, making packages of our internal libraries, updating our projects, getting our TFS Build server to Build. all of this is awesome! Now I have a problem though, before NuGet and package restore I could search TFS for the .dll files, as an example I could search for Company.Common.dll in TFS and find all projects that utilized this dll with the following command:
tf dir "$/*Company.common.dll" /recursive
/server:http://tfs-server:8080
Now after we have started using NuGet and using package restore the dll file Company.Common.dll will not be present in TFS in the projects that uses it. that means I can't use the above search command to find the .dll file I want to update
I was contemplating writing a powershell script that would find all packages.config files in TFS and download them to a folder structure indicating where in TFS the different projects are located. Then I would traverse the packages.config file to figure out what projects used the specific NuGet package I wanted to update.
The reason for this is ofcourse that all our projects should have the Common.dll updated when there is an update too it.
What I would like to know is if anyone has already solved this "problem", so I don't have to invent the wheel again, or perhaps have some perspective or constructive comments on this. I guess the core question is this:
How do you handle updating a package across ALL projects, when there are multiple teams that create / update projects in TFS?
One solution would be to use the "repositoryPath" NuGet config settings and make it point to a central UNC share. More details here # http://docs.nuget.org/docs/release-notes/nuget-2.1.
You can use NuGet.exe Update packageName -RepositoryPath xxx -Source xxx command to update the specific package if needed.

Resources