How do I get my build agent to build a solution with external project references? - tfs

Currently I am plagued with two TFS build issues:
Issue one: I have a solution with a project that now references the dll product of another project in another solution. The build agent does not seem to include these dlls and the build fails.
Issue two: I have a solution that references the a project in another solution. The build agent does not seem to include the externally referenced project and the build fails.
I have looked at the "copy directory" build activity but have no idea where to shim that in or what to put as source and output values.

The best practice is to use project references for referencing other projects within the same solution. For references which are external to your solution you should use file references, and then check in the compiled DLL which is being referenced.
Solution1
\Project1 --> Project1.dll
\Project2 --> Project2.dll
Solution2
\ProjectA (references Project1.dll)
\ProjectB (references Project2.dll)
\References
\Project1.dll -- this DLL gets checked in here and ProjectA references from here
\Project2.dll -- this DLL gets checked in here and ProjectB references from here
ProjectA.csproj
<Reference Include="Project1.dll, Version=blah blah blah">
<HintPath>..\References\Project1.dll</HintPath>
</Reference>
ProjectB.csproj
<Reference Include="Project2.dll, Version=blah blah blah">
<HintPath>..\References\Project2.dll</HintPath>
</Reference>
With this approach you have to build Solution1, get the DLLs which get dropped, and then check them into the References folder for Solution2. You can get real fancy and setup some logic in the build for Solution1 which automatically checks out the Solution2\References folder, replaces the Project1 and Project2 DLLs with the latest from the build, and then checks them in... and if you're using Continuous Integration this kicks off the build for Solution2.

If you are using TFS 2012 / TFS2010 build templates, make sure that the property "Solution Specific Build Output" set to false. This will ensure that the build agent builds all assemblies in the same bin directory.

Related

TFS NuGet Installer build step not working

I'm trying to configure an automated build of a project that has a NuGet package reference, but I'm not having any luck. (FYI I'm still pretty wet behind the ears with all of this, so please provide simple steps and/or configurations.)
Note: this isn't a duplicate of other similar questions, as I'm using a central package repository. Other similar questions make no mention of this important detail, so they should be assumed to not be relevant.
The build runs fine without the reference. I added Newtonsoft.Json and bound to it by including this simple construct:
Dim eHandling As Newtonsoft.Json.ConstructorHandling
eHandling = Newtonsoft.Json.ConstructorHandling.Default
I checked it in and the build started, but NuGet hadn't first copied the assembly to my application's bin folder. It did, however, copy it to here:
Restoring NuGet package Newtonsoft.Json.9.0.1.
Adding package 'Newtonsoft.Json.9.0.1' to folder 'C:\Agent\_work\1\s\packages'
Naturally the build failed, as it couldn't find the dependency.
It's worth noting that I'm using a central package repository on my dev machine:
<config>
<add key="repositoryPath" value="D:\Dev\Packages" />
</config>
I'd like to emulate this behavior on the server as well, e.g. C:\Packages\*\*.nupkg.
I tried using the standard %AppData%\NuGet\NuGet.config file, but the build ignores it. I tried the advice in this answer (using repositoryPath instead of packageSources as shown there), but that causes the server to hang until I restart the VSO Agent service. Thinking it might be a permissions issue, I reconfigured the agent to run under the user account associated with the %AppData% location of NuGet.config. Still no luck. No build.
How can I get NuGet to download and populate the central package repository on the server and then copy the appropriate dependencies to the application bin folder prior to running the build step?
EDIT 1
Update: Apparently something's working, as I now have a C:\Packages\Newtonsoft.Json.9.0.1 folder on the server. However, the assembly still isn't being copied to the application bin folder prior to build. Same result. Failed build.
EDIT 2
OK, I'm getting closer. I created a D: drive on the server and set the local repositoryPath value to D:\Dev\Packages, the same as it is on my dev machine. The build is still failing, but a quick look at the project XML reveals this:
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\..\Packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
<Private>True</Private>
</Reference>
How to deal with that relative path? That should fix it, yes?
EDIT 3
OK, that worked. I edited the project and changed HintPath to
D:\Dev\Packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll
I now have a successful build.
But this is going to get real tedious real fast. Surely I'm not going to have to do this for every single NuGet reference in every single project, past present and future... am I?
OK, got it.
As long as the repositoryPath folder on the server is the same number of levels deep as on our dev machine—in relation to the folder in which the Build Agent puts the project file—we can put it anywhere we want and retain the relative HintPath value in the project file.
For example, in my case I ended up setting the server location to C:\Agent\Build\Packages, to match the hierarchical location of the local Git repos on my dev machine:
D:\Dev\Packages
D:\Dev\Git\app.repo\App\App.vbproj
Works great.
EDIT
Just to clarify, the action of copying the assembly from the package folder to the application bin folder isn't a NuGet action. It's an MsBuild action (i.e. the CopyLocal setting in the project's assembly reference properties).
The reason it was failing was that MsBuild couldn't find the assembly to copy, according to its relative reference as specified in the project file.
So technically my question title is incorrect. The NuGet Installer step has been working fine all along.

How to include config transform files in web application filesystem publish output

I've been pulling my hair out on this for a while now. I'm trying to implement a continuous integration and deployment pipeline using TeamCity and Octopus Deploy. I am 99% there, except for one problem. I am using the standard msbuild runner of teamcity, configured to use the version 12 of msbuild.
I need to include the web.config transforms in the published output so they can be packaged into a nuget package for octopus deploy. I do not want the transforms to be applied by msbuild.
I am not using Octopack to create packages. I'm using the built-in teamcity nuget packager. So I'm publishing the website to a filesystem folder and then creating the package from the files in this folder. However, no matter what I do I cannot get msbuild to include the web.config transform files in the publish (I am using Octopus Deploy to perform the transforms, so I don't want msbuild to perform them).
I have verified that all the transform files (Web.Release.config, etc..) are marked as "Content". I have NOT marked them to copy always, because doing this copies them to the bin folder, not the root folder where they belong.
I have removed the /p:Configuration= property from the msbuild command line as I've read that is required for transforms to be applied. my parameters to msbuild look like this:
/p:DeployOnBuild=true /p:PublishProfile=Deployment
There is nothing in the publish profile that seems to relate to transforms. The publish profile contains the filesystem location to publish to.
Any suggestions here?
Note: I've given up and found a different solution, but I'm leaving this open in case anyone has any input.
You could create a custom .nuspec file and reference the files that you want to include from there.
My suggestion would be to have the .nuspec file in the same directory as the web.config / web.release.config files, and make the paths relative from there.
So if you publish to a directory called /output you could use rules like this
<files>
<file src="*.config" target="\" />
<file src="publish\*.*" target="\" />
</files>
So nuget pack nuspecPath would become the way to pack the project
NuSpec Reference
Hope this helps

How can I use project macros in TFS 2015 vNext Build definination?

I want to use macros of current csproj such as ${TargetPath} $(TargetName),in vNext Build defination as part of vs build task property of MSBuild argument,to do some copy etc.
But I found it not work,in build log, the macros did not be change into the absolute path.
Is there any way to use these macros just like in csproj post-build event?I did not find description about this on msdn ,and I could not use it in each csproj,because we have more than one thousand project files, edit the prj file one by one is not good:(
Thanks alot for your help.
Update
I want each project only output its own assembly without any referenced assembly when build.But I can't change project file to modify the reference property "copy local" to false.
You just need to add it as MSBuild arguments:
If you mean you want to achieve the function in post-build event same as this question Visual Studio Post Build Event - Copy to Relative Directory Location. There is no such thing like post-build in vnext build.
You can add several steps to copy the assemblies (One step for one project) and specify the copy root in the step.Refer to this question Copy one file in target directory on deploy from visual studio team services
However, as you have mentioned there are thousand project files. You can create a powershell script and add it in the build definition to copy the files.

TFS 2010 Build Definitions only output DLLs and PDBs?

So, I'm new to TFS build definitions - and the RA team at my company asked how to deploy a project that I built. In this case, a Windows Service project.
When I compile from Visual Studio, the "bin" directory has all the files I need... including copying a ".bat" file that is set to "copy local".
Anyway, the last step of the default "Build Definition" is "Run MSBuild for Project"... but that seems to just stick every DLL in the entire solution into an output directory.
Am I missing something? ... how do I get the build to:
Only build a single project - not the entire solution.
Put all the files that would be in the "bin" directory into the output directory.
When you're editing the Build Definition you can specify just a single project if you wish. By default TFS Build should put everything in the Build Drop that you typically find in your bin directory.
If you find the build is missing files that you expect to be there consult the MSBuild log that you can find linked from the TFS Build log. You can also run the TFS Build with Verbosity=Diagnostic when you queue up a build, which will cause the MSBuild log to contain much more detail.
Dylan Smith's answer was correct, and got me 90% there... the was a strange bug that some quick Googling found here: http://social.msdn.microsoft.com/Forums/uk/tfsbuild/thread/990fdd96-69bc-4e99-be0e-acc0874e022f
So, the solution is:
Do what Dylan said (pick the csproj file).
Remove the "Any CPU" part of the build... just target "Release" or "Debug" or whatever.

Error While Creating Build

I have TFS 2010 and for one of the team project I have created the build definition (used default build template) and added the solution of one of the project. But when try to create build getting the following error:
C:\Windows\Microsoft.NET\Framework64\v4.0.30319\Microsoft.Common.targets
(902): The command "if Debug == Debug copy
"C:\Builds\14\\\Sources\ServerObjects..\SharedInterfaces\bin\debug*.dll"
"C:\Builds\14\\\Sources\ServerObjects..\ServerObjects\bin\debug"" exited with
code 1.
I think you maybe has wrong folder structure on the source control, see my answer on similar question here
teambuilding and deploying a dll (e.g. wpftoolkit.extended.dll)
TeamBuild overrides the output folder so the bin\debug (or bin\release) folder won't exist. It collates the output into Binaries.
For your custom build step use the obj folder instead of bin as that'll be the same under both TeamBuild and the local machine build.

Resources