How to use default project output locations in TFS 2013 build definition? - visual-studio-2013

I have a solution which has several VC++ projects. I am trying to make TFS do weekly builds. I have set up TFS Build controller and agent. I created a build definition using DefaultTemplate.xaml file and I can successfully build some of the projects.
The problem is my projects depend on some libraries that are already checked in to debug/release folders. TFS is trying to put project outputs (dlls and exes) to $(SolutionDir)\Binaries directory. Since dependent libraries don't exist on this location, TFS build fails.
What I would like to do is use my own project output locations and somehow copy the output files to somewhere in server.
How can I do that?
Thanks

It's not recommended checking in the libraries to TFS, you can use Nuget to restore the packages.
For the build outputs, you can specify the drop folder in your build definition and copy the outputs to the drop folder.
You can also check in a script that copy the outputs, and specify a post-build script path in your XAML build definition. This script gathers some of the typical binary types from the typical locations and copies them to the folder from which TFBuild copies and drops to your staging location. Check more information about Run a script in your XAML build process at website:
https://msdn.microsoft.com/library/dn376353%28v=vs.120%29.aspx

I would suggest to edit your build definition. Under Process section, set MSBuild arguments to
/p:GenerateProjectSpecificOutputFolder=true
As follows:

Related

TFS XAML Build Console App

I'm using TFS2017 and VS2015.
I have a solution with multiple WebApps and a ConsoleApp.
When I do a TFS build I get the WebApps built and dropped to the location I need. but so far I have been manually copying the ConsoleApp.
Is there a way for TFS to build the ConsoleApp and also drop it in a specific location?
Why you have to use the Xaml build system? See Why You Should Switch to Build VNext
In TFS 2017 you can easily use the new vNext system to build the ConsoleApp and drop it in a specific location.
You can build the entire solution with VS build task or separately build the ConsoleApp projects with the MSBuild task with the MSBuild Arguments set e.g : /p:OutDir="$(build.artifactstagingdirectory)\\"
Then use the Publish Build Artifacts task to drop it in the specific location.
You can use a PowerShell script as post build script in a xaml build and use it to copy files to the build output. Sample script for XAML builds available here

Visual Studio 2015 - Finding out path to currently used workspace (C# / custom build steps)

I would like to add a custom build step to copy the executable from where it was built (in current active configuration, in current workspace, by currently logged in user) into a shared location.
Are there any predefined environment variables in VS (?) that would contain that information?
Or C# API to Visual Studio that would provide the same?
This might help:
https://msdn.microsoft.com/en-us/library/42x5kfw4.aspx
These did not help:
Visual Studio 2015 Extension - How to get workspace of current Solution
How to get the TFS workspace directory
VNext build
Seems you want to copy files from working folder on the agent computer.(The local path on the agent where your source code files are downloaded. For example: c:\agent\_work\1\s)
You can try to use Windows Machine File Copy task.
Source: You can use pre-defined system variables such as $(Build.Repository.LocalPath) (the working folder on the agent computer), which makes it easy to specify the location of the build
artifacts on the computer that hosts the automation agent.
Destination Folder: The folder on the Windows machine(s) to which the files will be copied. Example: C:\FabrikamFibre\Web
If your shared loaction is on the same machine. You can also try to use Copy Files.
XAML build
In XAML build, you can check in your script, and specify a post-build script path in your XAML build definition. This script gathers some of the typical binary types from the typical locations and copies them to the folder from which TFBuild copies and drops to your staging location. Check more information about Run a script in your XAML build process at website: https://msdn.microsoft.com/library/dn376353%28v=vs.120%29.aspx

Multiple web deployment packaging using TFS build

We have several web services that we have been deploying "manually" using msdeploy. We pick up the deployment packages from the TFS2010 build machine in the appropriate _PublishedWebsites\<<ProjectName>>_Package directory.
We now want to wrap the deployment packages up with a deployment tool that makes it easier for the person doing the installation to see the parameters.
What we'd like to do is to build the individual web service deployment packages, have the deployment packages land in the right place for the deployment tool build and then have the deployment tool build both build the tool and copy the previously-built deployment packages to the same Binaries drop folder on the build machine.
For some reason, this seems incredibly difficult to do.
Things we've tried
Setting Location where package will be created on the web services project's Package/Publish Web project settings using a variable (e.g. $(TargetDir)). Visual Studio interprets the entered variable and replaces it with the hard-coded path for the development machine... and that's what goes to the build machine. On the build machine the end result is... nothing; the deployment packages are still sent to _PublishedWebsites\<<ProjectName>>_Package.
Setting /p:PackageLocation on as one of the MSBuild Arguments settings on the TFS build definition "Process" / "Advances" section, in addition to /p:CreatePackageOnPublish=true /p:DeployOnBuild=true. All this did was generate the error:
MSB1008: Only one project can be specified. Switch: p:PackageLocation=$(BinariesRoot)\DeploymentFiles For switch syntax, type "MSBuild /help"
presumably because there is more than one deployment package being generated by the build.
Any advice appreciated! Are we going about this the wrong way? Should we be doing something like altering the build XAML to cater for this (like this page suggests for another issue)?
Couple possibilities for you to consider:
1 - Alter the TFS workflow like you've described to perform some copy task
2 - Create an MSBuild project that runs after your standard Packaging steps to copy the output from _PublishedWebsites to some location of your choice
3 - Override the following MSBuild parameter when building the package to change the package drop location:
<DefaultPackageOutputDir Condition="'$(DefaultPackageOutputDir)'==''">$(OutDir)[YourDesiredLocation]\$(DefaultMSDeployDestinationApplicationName)\Package</DefaultPackageOutputDir>
Note that you can see the set of packaging MSBuild parameters available to you at
c:\program files (x86)\MSBuild\Microsoft\VisualStudio\v10.0\Web\Microsoft.Web.Publishing.targets
I recently implemented suggestion #2 at a client, using the MSBuild overrides suggested in #3 in the custom MSBuild project file and it worked like a charm.

TFS 2010 build cannot handle custom MSBuild script which generate multiple files in multiple directories

I have a custom MSBuild script (e.g. WpfResources.proj), in which I scan through multiple folders for *.resx files anc build .NET satellite resource dlls using the AL task. The output of this WpfResources.proj contain multiple *.resources.dll under different folders (corresponding to different projects which will need these resource dlls).
The example output folder structure is shown as following:
WpfResources
Bin
Project1
zh-CN
Project1.resources.dll
es-ES
Project1.resources.dll
...
Project2
zh-CN
Project2.resources.dll
es-ES
Project2.resources.dll
...
This WpfResources.proj can be built correctly by MSBuild.exe. However if I run it in TFS 2010 build (i.e. create a build definition and refers to the WpfResources.proj to build), it failed to copy all those resource dlls into the drop location. Actually it outputs nothing to the drop location even though on the actual build PC, the output is fine.
How can TFS 2010 build handle custom MSBuild scripts which output multiple files under multiple folders? Is there something missing in my WpfResources.proj which the Team build will consider as outputs of this MSBuild project?
On a build system, TFS handles the binary output directory and the copying of its output to a drop folder a bit special. It generates a central output directory for all output files.
I would imagine that your MSBuild project does output the standard way as if it were on a development system, with output bins under the project folder structure. TFS will not copy them to the drop folder, because by default, it only copies the binaries it produced under the central output folder.
For our systems, we solved the issue (that also goes for building VS Setup projects) but having a manual copy action embedded in the build template that copies the MSBuild output to either the centralized bin output folder, or directly towards the drop folder location.
For adding such a custom action, please see the fine TFS2010 customization blog of Ewald Hofman at: http://www.ewaldhofman.nl/post/2010/04/29/Customize-Team-Build-2010-e28093-Part-4-Create-your-own-activity.aspx.
Hope that helps.

build and deployment automation for msbuild EXE projects

I'm working on some automated build changes and have some questions as to the best approach for building/packaging EXE applications.
Conceptually, there are two scripts. The first builds everything at puts the resulting binaries on a share so they are available for deployment. The second set of scripts are each responsible for copying and configuring some application from that build result.
The first script, which builds the entire solution, copies the build result to known pickup location by overriding the msbuild output path. This causes binaries for all to be dropped in the same folder (except web applications, where each project is in its own website under _PublishedWebsites). This is problematic as when I build an installer for a single EXE project, I only want to include the EXE and dependencies of that EXE. However since all project outputs are in the same folder then it is not clear which are needed by the individual application.
Given that the build has put the binaries for all the executables in one folder, how can I build an MSI that only includes the binaries needed for a particular EXE?
I am using psake/powershell for the build scripts, using msbuild to compile the solution files. I am using WixSharp the build the installer from a command-line app (not CSC).
SUMMARY
Since Wix# actually builds the MSI when you "run" the .exe it creates, and uses the WiX toolkit, you would need to output the executable Wix# + WiX Toolkit creates to your drop folder. Then make sure the WiX toolkit executable files are either on your PATH or in your output folder, and create Powershell script(s) that invoke your Wix# executable(s) in the drop folder. One straightforward approach would be to have one Wix# project for each separate "product installer", and have each these Wix# executables be output to your drop folder, for further processing/generation of the MSI files by your downstream Powershell (or other) scripts.
I am using Wix# integrated into the VS2013 IDE, so my answer should be interpreted in that context. My Wix# installer is simply one project of several in my overall solution.
EXAMPLE FOR A SINGLE Wix# PROJECT IN A VISUAL STUDIO SOLUTION
So, for example, if your Wix# project code file is set up in VS as a project named named MyWebsiteSetup, and the Wix# code file is MyWebsiteSetup.cs, your Wix# executable will be located at \MyWebsiteSetup\bin\debug\MyWebsiteSetup.exe.
Have the build place this MyWebSiteSetup.exe file in the drop folder, along with the other files Wix# places in bin\debug folder. Then have your second set of scripts run the MyWebsiteSetup.exe program, which will generate the MSI. I believe you may need to have the installation component files the Wix# code requires be deployed to the drop folder as well, and in the expected folder structure. Wix# seems to place all the other support files it needs in the bin\debug folder, so just having all the files copied from the Wix# project's bin\debug to the drop folder should get you what you need.
ADAPTING THE EXAMPLE TO MULTIPLE PRODUCTS (MULTIPLE Wix# PROJECTS)
Now, your question was how to do this for multiple websites where all the files are placed in the same drop folder. There are several ways to approach this, but the one I suggest is to have a separate Wix# project in Visual Studio for each separate product, and have the Wix# output files for each of those projects deployed to the drop folder along with the product files. If your separate products were named MyWebSiteSetupA, MyWebSiteSetupB, and MyWebSiteSetupC, they will generate executables MyWebSiteSetupA.exe, MyWebSiteSetupB.exe, and MyWebSiteSetupC.exe. You would simply have your second set of scripts invoke each of those in turn. Each of the Wix# code files (.cs files) for those projects of course will have been coded to know what files it needs to pick up when it runs, and when the resulting exe is run, it will get the files it needs, provided you've made them available where expected, and build the individual MSI's for each product's installer.
There are of course, numerous other approaches for this, with flexible tools like PowerShell, each approach with pros and cons, but I hope this helps get you started with an approach you can then tailor to your needs.

Resources