Copy files to another folder during check in (TFS Preview) - tfs

I have the following scenario: The company edits aspx/xml/xslt files and copy manually to the servers in order to publish them. So, no build is done. For the sake of control we've decided to adopt TFS Preview since it tracks the version, who edited and so on. Needless to say, it works like a charm. :)
The problem is that since we are unable to build the apps we can't set a build definition to automate the copy of files to another place which, as I've stated before, is done manually.
My question is: Is it possible to copy the files to another place (a folder in a server or local) during the check in? If so, how? (remember, we don't build. so we can't customize the build process...)

You have two options.
1) Create a custom check in policy. I'm not familiar with this process enough to give you any pointers, but I believe it can be done.
2) Create a custom build template, and use that for your builds. You should be able to wipe the build template down to nothing, and then only add the copy operation to it. This is probably the route I would take. Get started here.

You mention you are using TFSPreview, which is hosted on the cloud so it won't be able to access any machines in your network unless you're prepared to open up your firewalls :).
You can copy source controlled files around the TFS Instance ([say into a Source Controlled Drop F1) and then check this out after the build completes.
Start by familiarising yourself with customising the TFS Build Process.
When you're up to speed, you need to look at adding a "Copy" Activity in the Workflow to move the files to the drop folder.

Related

Dropping a build in a fixed location

I have a build process that I've defined with a custom build process template, and I'm looking for some advice on how I can solve a problem I've run up against.
The build process (TFS 2012) is used to build the code that drives our load tests, and I have a separate process that needs to reference a specific path within the drop folder so that it is always using the latest version of the load test code. Automated load testing, pretty standard stuff.
However, I'm wondering if there is a way to get the TFS build to overwrite files it finds in the drop folder. Right now I have it set up to drop to a very specific folder, and not put anything that would change in the folder name (no build number, date, etc.). The thought is, this way the automated utilities that rely on those files have a fixed point to look at.
However, when I currently run the build it gives me error TF42064: The build number '<build>' already exists for build definition '<build>'.
Currently I have the build definition set up to only retain the latest build, because this process is specifically for those automated tools. We have other build processes that are fired for debugging/troubleshooting/logging purposes. Is there a way to get the build definition to overwrite the drop folder each time, or will I have to dig into the .XAML template file to have it delete the folder it finds before the build fires?
The way I approached this requirement was to start with the default template and let the build copy to the normal drop location which allows me to keep historical builds in the same way as all other builds.
Once the build has been completed I then copied to a single drop location from the standard drop location by extending the standard build template, the activity was added just before Check-In gated changes.
The steps involved were as follows:
Within SharedResourceScope:
Delete Unified Drop Location
Create Unified Drop Location
Copy Directory (source: BuildDetail.DropLocation)
By default TFS Build creates a new folder, using the unique build name/number, and drops the files there.
If you want to change this behaviour to overwrite files in a known location (instead of creating a new folder each build) you need to modify the build workflow/XAML (as #Oswald mentioned in the comments).
You can read about customizing TFS Builds from the ALM Ranger Build Guidance on CodePlex: http://vsarbuildguide.codeplex.com/

TFS MSBuild Copy Files from Network Location Into Build Directory

We are using TFS to build our solutions. We have some help files that we don't include in our projects as we don't want to grant our document writer access to the source. These files are placed in a folder on our network.
When the build kicks off we want the process to grab the files from the network location and place them into a help folder that is part of source.
I have found an activity in the xaml for the build process called CopyDirectory. I think this may work but I'm not sure what values to place into the Destination and Source properties. After each successful build the build is copied out to a network location. We want to copy the files from one network location into the new build directory.
I may be approaching this the wrong way, but any help would be much appreciated.
Thanks.
First, you might want to consider your documentation author placing his documents in TFS. You can give him access to a separate folder or project without granting access to your source code. The advantages of this are:
Everything is in source control. Files dropped in a network folder are easily misplaced or corrupted, and you have no history of changes to them. The ideal for any project is that everything related to the project is captured in source control so you can lift out a complete historical version whenever one is needed.
You can map the documentation to a different local folder on your build server such that simply executing the "get" of the source code automatically copies the documentation exactly where it's needed.
The disadvantage is that you may need an extra CAL for him to be able to do this.
Another (more laborious) approach is to let him save to the network location, and have a developer check the new files into TFS periodically. If the docs aren't updated often this may be an acceptable compromise.
However, if you wish to copy the docs from the net during your build, you can use one of the MSBuild Copy commands (as you are already aware), or you can use Exec. The copy commands are more complicated to use because they often populated with filename lists that are generated from outputs of other build targets, and are usually used with solution-relative pathnames. But if you're happy with DOS commands (xcopy/robocopy), then you may find it much easier just to use Exec to run an xcopy/robocopy command. You can then "develop" and test the xcopy command outside the MSBuild environment and then just paste it into the MSBuild script with confidence that it will work - much easier than trialling copy settings as part of your full build process.
Exec is documented here. The example shows pretty well how to do what you want, but in your case you can probably just replace the Command attribute with the entire xcopy/robocopy command (or even the name of a batch file) you want to use, so you won't need to set up the ItemGroup etc.

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

The easiest way to test TFS2010 build template

I'm currently working on creating a build template for TFS2010 builds. However, I notice that I'm currently 'spamming' the source control with every change I make to the template (and lots more for all the fixes for those changes).
I wonder what the easiest way is to test the build templates I'm creating?
Is there a way to change the template file and custom activity dlls that doesn't involve checking them in?
I currently have a build controller and agent running on my developer machine, which I'm using to test the template (test = start a build and hope for less errors than last time).
Why is 'spamming' a problem? Anyway, I have a separate Team Project for doing this kind of work, that way I can check in to my hearts content without affecting the developers who need to have a stable build. once I've done my testing I check the template in to the team project(s) used by the developers.
I want to test my builds against the teams latest code-base without having to branch it over to a trial project.
Instead, I do the following:
Create a separate build definition called 'Infrastructure'
clone a production definition
Set the trigger on the Infrastructure build definition to manual.
Set the Infrastructure definitions permissions to allow only [Project]\Build group members to have full control of it.
keeps the notification of broken builds away from the bulk of the team).
Create a separate build process template, called 'Infrastructure.xaml'.
Point the Infrastructure build definition at the Infrastructure process template.
Now when I want to iterate on a new build feature for the team:
Check out the build process template I want to update, and lock it.
Copy the build process template I want to update overtop of the Infrastructure.xaml.
Add my build feature to the Infrastructure.xaml file, and check that in.
Use the Infrastructure build definition to test my changes.
Iterate over 3-4 until I get it right.
Complete the feature and have my changes verified by another Infrastructure team member.
Copy Infrastructure.xaml over the build process template I locked in (1) and check it in.
This still results in 'spam' in the TFS source control, but it keeps the build definition iteration out of the eyes of the team. My build process templates are located out of the main source tree (under the Build Process Templates folder, or in the branches themselves under a 'Core/Build' folder where no-one else on the team is typically paying any attention) so that the team is largely unaffected by it.
#d3r3kk: Why not just branch the template and merge changes back when ready instead of creating copies? That way you can preserve source history in a cleaner way as well.
Ideally, there should be a way to have a build process template that is in progress by having it on your local file system and pointing the build definition to it temporarily. Not sure if something like this exists in later versions of VS/TFS. I haven't seen it available via the UI anyway.

Team Build: Publish locally using MSDeploy

I'm just getting started with the team build functionality and I'm finding the sheer amount of things required to do something pretty simple a bit overwhelming. My setup at the moment is a solution with a web app, an assembly app and a test app. The web app has a PublishProfile set up which publishes via the filesystem.
I have a TFS build definition set up which currently builds the entire solution nightly and drops it onto a network share as a backup of old builds. All I want to do now is have the PublishProfile I've already setup publish the web app for me. I'm sure this is really simple but I've been playing with MSBuild commands for a full day now with no luck. Help!
Unfortunately sharing of the Publish Profile is not supported or implemented in MSBuild. The logic to publish from the profile is contained in VS itself. Fortunately the profile doesn't contain much information so there are ways to achieve what you are looking for. Our targets do not specifically support the exact same steps as followed by the publish dialog, but to achieve the same result from team build you have two choices, I will outline both here.
When you setup your Team Build definition in order to deploy you need to pass in some values for the MSBuild Arguments for the build process. See image below where I have highlighted this.
Option 1:
Pass in the following arguments:
/p:DeployOnBuild=true;DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder;PackageTempRootDir="\\sayedha-w500\BuildDrops\Publish";AutoParameterizationWebConfigConnectionStrings=false
Let me explain these parameters a bit, show you the result then explain the next option.
DeployOnBuild=true:This tells the project to execute the target(s) defined in the DeployTarget property.
DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder: This specifies the DeployTarget target.
PackageTempRootDir="\\sayedha-w500\BuildDrops\Publish": This specifies the location where the package files will be written. This is the location where the files are written before they are packaged.
AutoParameterizationWebConfigConnectionStrings=false: This tells the Web Publishing Pipeline (WPP) to not parameterize the connection strings in the web.config file. If you do not specify this then your connection string values will be replaced with placeholders like $(ReplacableToken_dummyConStr-Web.config Connection String_0)
After you do this you can kick off a build then inside of the PackageTempRootDir location you will find a PackageTmp folder and this contains the content that you are looking for.
Option 2:
So for the previous option you probably noticed that it creates a folder named PackageTmp and if you do not want that then you can use the following options instead.
/p:DeployOnBuild=true;DeployTarget=PipelinePreDeployCopyAllFilesToOneFolder;_PackageTempDir="\\sayedha-w500\BuildDrops\Publish";AutoParameterizationWebConfigConnectionStrings=false
The difference here is that instead of PackageTempRootDir you would pass in _PackageTempDir. The reason why I don't suggest that to begin with is because MSBuild properties that start with _ signify that the property in essentially "internal" in the sense that in a future version it may mean something else or not exist at all. So use at your own risk.
Option 3
With all that said, you could just use the build to package your web. If you want to do this then use the following arguments.
/p:DeployOnBuild=true;DeployTarget=Package
When you do this in the drop folder for your build you will find the _PublishedWebsites folder as you normally would, then inside of that there will be a folder {ProjectName}_Package where {ProjectName} is the name of the project. This folder will contain the package, the .cmd file, the parameters file and a couple others. You can use these files to deploy your web.
I hope that wasn't information over load.
The ability to publish web sites, configure IIS and push schema changes for the DEV->QA->RELEASE cycle has required either custom configuration to imitate publish or custom code where IIS settings are involved.
As of Visual Studio 2013.2 Microsoft has added a third party product that manages deployment of web sites, configuration changes and database deployment with windows workflow and would be the recommended solution for automating deployment from TFS build.
More information can be found here:
http://www.visualstudio.com/en-us/explore/release-management-vs.aspx
You can use the Publish/Deploy in Visual Studio 2010.
See http://www.ewaldhofman.nl/post/2010/04/12/Auto-deployment-of-my-web-application-with-Team-Build-2010-to-add-Interactive-Testing.aspx for more information

Resources