Wix in TFSBuild: SourceCodeControlRoot - tfs

I am following the recommendations to integrate Wix with TFS (http://wixtoolset.org/documentation/manual/v3/msbuild/daily_builds.html) (without having to install it on the Build server)
In my WixProj file, I have the line:
$(SourceCodeControlRoot)\wix\3.9\
This has been checked in with all of the prerequisite files - and I can successfully build on my Dev box.
But when I run my build, TFS complains that it can't find my Wix.targets file.
The error states:
*C:\Builds\8\AppName\DailyBuild\Sources\Setup\Case Tracking Setup\Wix Case Tracking.wixproj (73): The imported project "C:\wix\3.9\Wix.targets" was not found. Confirm that the path in the declaration is correct, and that the file exists on disk.
So I'm obviously using the wrong Reference but I couldn't find any other examples and the only place with SourceCodeControlRoot appears is related to Wix.
Any ideas?
Thanks

The article intends that you define or replace $(SourceCodeControlRoot) such that $(SourceCodeControlRoot) is the folder TFS exports to during the build. In your case, I'm guessing "C:\Builds\8\AppName\DailyBuild\". Of course, you probably don't want to hardcode it. You could pass a property setting to msbuild: /property:SourceCodeControlRoot="$(TF_BUILD_BUILDDIRECTORY)"
It doesn't really matter where you have your binaries (wix\3.9) folder. The end goal is to have $(WixToolPath) point to it. You could define it relative the project file if that's more convenient in your project structure:
<WixToolPath>$(MSBuildProjectDirectory)/../wix/3.9/</WixToolPath>

Related

Adding references search folder for MSBuild from Visual Studio Build definition UI

I am working on configuring a XAML build definition for a .net solution (of another company) stored in TFS2015.
The solution uses Dll references from a software X, installed on the developers computers, but not present in the Build server. (FTS and Build servers are shared among many clients).
I have option to add the required Dlls in a folder along with the source code, but I do not have option to modify the .csproj files.
In the Build definition, I tried to add the following in the MSBuild arguments field :
/p:AdditionalLibPaths=$/[long tfs path here]/CommonDlls
/p:AdditionalLibPaths=$(SourceDir)/CommonDlls
but it is not working.
Ideally, I would like to specify a relative folder from the root of the source code.
(a static path might work but only for one build server and agent, which is not the objective of shared build).
Any ideas on how I can define this parameter ?
There is also option to add a prebuild script path. I can store a script file along with source code. Any pointers for how to write such script file ?
You do not really need a script.
There are two things to make this work.
The first step is making sure that the DLLs are downloaded to the Agent working folder, the simplest way is have the $/[long tfs path here]/CommonDlls mapped in the Build Workspace; this is specified in the Source Settings tab of the Build Definition. Be careful to use the $(SourceDir) token in the mapping (see here).
The second point is to use a proper reference to the downloaded folder: use the TF_BUILD_SOURCESDIRECTORY variable (see here for full list).
So, if you added a mapping like
$/[long tfs path here]/CommonDlls -> $(SourceDir)\CommonDlls
use $(TF_BUILD_SOURCESDIRECTORY)\CommonDlls.
It took me almost 20 trials to get the right one, it all started with how long it took that warning to consider all other directories, I could've ignored it but here's the warning first
C:\Program Files (x86)\MSBuild\14.0\bin\Microsoft.Common.CurrentVersion.targets(1820,5): Warning MSB3245: Could not resolve this reference. Could not locate the assembly "nameOfDllFile". Check to make sure the assembly exists on disk. If this reference is required by your code, you may get compilation errors.
and this is the argument that got it working
/p:ReferencePath="$(build.sourcesdirectory)\Binaries"
where Binaries is the equivalent to CommonDlls from the question, and it is all because of the vague documentation and differences between versions of MSBuild, mine is 14.0 (VS2015).

TFS Build controller and extensions

I am setting up a TFS 2012 Build server. I am using some extensions (NUnit Test Adapter). Per the instructions, I have added the dlls to a common folder in TFS, and configured the "Version Control Path to Custom Assemblies" on the build controller to reference the correct folder in TFS.
Everything works, BUT: According to the docs, I can create subfolders under my "Path to custom assemblies" folder, and the controller should pick them up.
That doesn't seem to be working for me. If I put the NUnit support in the root, it works, in subfolders, it does not.
I would like to use the subfolders feature so that I can keep each set of extensions/custom build targets, etc separate.
Does this just not work, or am I missing something?
Edit
As requested, here is a reference to the documentation where I found the information:
http://msdn.microsoft.com/en-us/library/vstudio/ee330987(v=vs.120).aspx#custom_process
Here's the passage:
To enable your build processes to leverage these kinds of code, check the binaries in to the folder (or any of its descendant folders) that you specify in the Version control path to custom assemblies box.
It turns out that the documentation is just wrong -- all of the dlls must go into 1 folder.
http://social.msdn.microsoft.com/Forums/en-US/0059bc66-d3c9-42e6-8d8a-dd22f3416e07/version-control-path-to-custom-assemblies-doesnt-use-subfolders?forum=tfsbuild
I do understand that helps to ensure that you don't get duplicate dependencies with different versions -- makes sense. It just makes it a little tougher to know what depends upon what if you add a few extensions. Seems to work fine using a single folder, though.

Customizing Drop Folder Structure with TFS Team Build

I'm using TFS 2012 to automate a build of a solution which contains multiple windows services and two web applicaitons.
I've used the guide I found here to customize the build process template so that the windows services are put in a folder structure that I like. Specifically:
\dropserver\droproot\MyApp\BuildNumber\
\Service1
\Service2
\Service3
\Service4
This works great, but unfortunately it doesn't work for web applicaitons. If I used the same strategy for those, I just get the contents of /bin for each web app, rather than the full site contents.
MSBuild typically uses the web application targets to handle this, but for some reason, this doesn't work when you customize the build as I have. I no longer get the _PublishedWebSites folder in the build output. (I'm guessing that's because I cleared our the OutDir property of the MSBuild task.)
Has anybody done something like this and gotten it to work with web applications as well?
I think I can help with this, it looks like in the build targets that the published websites folder isn't created if the OutDir is the same as the OutputPath.
So this isn't perfect, but if you add the following into the csproj file in the first property group, you'll get everything deployed into "\bin\deploy\" including the _PublishedWebsites folder
<DeployOnBuild>True</DeployOnBuild>
<OutDir>bin\deploy\</OutDir>
With a bit of customization, this solution ended up working for me:
http://www.edsquared.com/2011/01/31/Customizable+Output+Directories+For+TFS+2010+Build.aspx
Basically, did what that link recommended, but also leveraged a new solution configuration (which I called TeamBuild) rather than conditional property definitions.
I believe the key to making this all work was the passing of the outputDirectory as the TeamBuildOutDir argument to MSBuild. Embedding this variable reference in the OutDir or OutputPath variable was allowed Team Build to build to the correct staging location and then automatically copy files from that location to the drop folder.
I'm going to take this a little futher and get rid of the whole _PublishedWebSites thing, but that will be done entirely in the build workflow.
EDIT: TFS 2013 supports this natively with a simply build configuration option:
Take a look at this thread as this post as well.
Team Build: Publish locally using MSDeploy
Since you need all the files for your web projects, you need to trigger the publishing process, and by tweaking the destination of that process, you can have all of your files copied where you need them.
I think option (2) from his answer will work for you.
I hope that helps.
As I can see in your reference link, it will just compile and package the binaries. It does not deploy the website by the steps mentioned in that.
If you want to get the .html, .css, .js etc. under the _PublishedWebSites folder, you need to do a Web Deployment. This manually we can do by clicking the publish option from right click menu of your VS project and by selecting Publish Method as File System.
But, since you need to automate this in your build and drop it in custom drop folder, you may need to manipulate your MSBuild script by calling a AspNetCompiler task. You can get more information on this at the MSDN link. By specifying the TargetPath while you call this target you can get your Web files deployed at the appropriate custom drop folder.
Happy Scripting.
Have you check this blog, this solved my problem where I wanted customized TeamBuild Ouput Directory.
Customizable O/P with TFS 2013
Customizaable O/P with TFS 2012 and .NET Framework 4.5

Retrieving path to solution(s)?

We are currently setting up Team Build 2010 for our company, and I am trying to use workflow activities to retrieve the exact local path to the current solution being built. I haven't found a way to get this value, does anybody know how (without writing a custom activity)?
Either one of server or local path would suffice (i.e $/TeamProject/Branch/OurProject or C:\TeamBuild\src\path\to\branch\OurProject) since we can use the conversion activities on the server item.
The reason we need this path is for updating version info files, and that needs to be done for only the current solution being built, and the files have the same names (AssemblyInfo.cs, for example).
In this similar question, the solution is to define a parameter, but since this information is particular to the solution being built and not some external path, we were hoping that this info would retrievable.
You can retrieve this particular info without adding anything. If you navigate within your Build Process Template to the position where MSBuild breaks out, you will see that the solution that shall be build is set as a string named localProject. This will contain the local path where TFS has downloaded your SLN, something like C:\TeamBuild\src\path\to\branch\OurProject\OurProject.sln.Open the XAML and navigate to:
Run On Agent
Try Compile, Test, and Associate Changesets and Work Items
Compile, Test, and Associate Changesets and Work Items
Try Compile and Test
Compile and Test
For Each Configuration in BuildSettings.PlatformConfigurations
Compile and Test for Configuration
If BuildSettings.HasProjectsToBuild
For Each Project in BuildSettings.ProjectsToBuild
Try to Compile the Project
Compile the Project
Run MSBuild for Project
if you select Run MSBuild for Project & hit F4 you see it.
In order to retrieve what you are after you can define another string-variable solutionPath in your Build Process Template & insert under the Run MSBuild for Project a new Assign activity withTo : solutionPath andValue : Path.GetDirectoryName(localProject)
Have you looked at the TFS Community Build Extensions, they give you a assembly versioning out of the box?
You can use the variable called SourcesDirectory to get the current Source Directory on the Build Server. You can also use an ConvertWorkspaceItem activity to convert between server and local paths.
There's also a blog post that cover's all of this here.

How do I change the build directory that MSBuild uses under Team Foundation Build?

I'm getting the following error when trying to build my app using Team Foundation Build:
C:\WINDOWS\Microsoft.NET\Framework\v3.5\Microsoft.Common.targets(1682,9): error MSB3554: Cannot write to the output file "obj\Release\Company.Redacted.BlahBlah.Localization.Subsystems.
Startup_Shutdown_Processing.StartupShutdownProcessingMessages.de.resources". The specified path, file name, or both are too long. The fully qualified file name must be less than 260 characters, and the directory name must be less than 248 characters.
My project builds fine on my development machine as the source is only two folders deep, but TF Build seems to use a really deep directory that is causing it to break. How do I change the folders that are used?
Edit: I checked the .proj file for my build that is stored in source control and found the following:
<!-- BUILD DIRECTORY
This property is included only for backwards compatibility. The build directory used for a build
definition is now stored in the database, as the BuildDirectory property of the definition's
DefaultBuildAgent. For compatibility with V1 clients, keep this property in sync with the value
in the database.
-->
<BuildDirectoryPath>UNKNOWN</BuildDirectoryPath>
If this is stored in the database how do I change it?
Edit: Found the following blog post which may be pointing me torward the solution. Now I just need to figure out how to change the setting in the Build Agent. http://blogs.msdn.com/jpricket/archive/2007/04/30/build-type-builddirectorypath-build-agent-working-directory.aspx
Currently my working directory is "$(Temp)\$(BuildDefinitionPath)" but now I don't know what wildcards are available to specify a different folder.
You need to edit the build working directory of your Build Agent so that the begging path is a little smaller. To edit the build agent, right click on the "Builds" node and select "Manage Build Agents..."
I personally use something like c:\bw\$(BuildDefinitionId). $(BuildDefinitionId) translates into the id of the build definition (hence the name :-) ), which means you get a build path starting with something like c:\bw\36 rather than c:\Documents and Settings\tfsbuild\Local Settings\Temp\BuildDefinitionName
Good luck,
Martin.
you have to checkout the build script file, from the source control explorer, and get your elbows dirty replacing the path.

Resources