views:

2430

answers:

3

I have managed to install Team Foundation Server 2008 and I created a separate build server (which works because my builds are currently failing).

I have created a simple "Hello World" Web application (all is the standard Default.aspx page) and have it in TFS's source control system.

Previously, prior to TFS, I'd simply precompile my web application and xcopy the results on to a pre-created IIS Virtual directory.

Scouring Google for a while, I have yet to find a step by step guide on correctly deploying an application from TFS Source via TeamBuild to a designated test web server. I know MS Build falls into this equation, so any guidance would be helpful.

I have seen bits and pieces about deployments, with folders such as _PublishedWebSites mentioned, but have yet to find anything step by step.

+1  A: 

This can be done via the build scripts directly, the Vertigo Software guys usually are the best source of info for a lot of TFS questions like this...unfortunately their blog posts don't usually rank that high on google. This one's by Jeff Atwood, one of the creators of this site:

Copying Web Files After a Team Build

Nick Craver
+2  A: 

I've had success using a exec task in the AfterDropBuild target in the TFSBuild.proj file.

<Target Name="AfterDropBuild>
    <Exec Command="xcopy /Y /E &quot;$(DropLocation)\\$(BuildNumber)\%(ConfigurationToBuild.FlavorToBuild)\_PublishedWebsites\MyWebsite1\*.*&quot; &quot;\\server\MyWebsite1\&quot;" />
    <Exec Command="xcopy /Y /E &quot;$(DropLocation)\\$(BuildNumber)\%(ConfigurationToBuild.FlavorToBuild)\_PublishedWebsites\MyWebsite2\*.*&quot; &quot;\\server\MyWebsite2\&quot;" />
</Target>

Note that the permissions need to be setup correctly for the TFS service user to access the folder on the server your are copying to.

ryan.rousseau
I found some other resources that outlined what you described here, I was able to successfully migrate a web application from my old source control system, create a build and deploy it as shown with the copy command
RandomNoob
+3  A: 

Firstly you should be using WebDeployment projects as this will do a lot more compilation and checking of your code and markup. See here for more info.

I have 4 environments setup DV [Development], PY [Prototype], PP [Pre-Production], PD [Production] all matching branches in TFS. Each of these has also has an entry in the sln configuration manager where you can setup what projects are required to be build and the build flags.

Once that is setup correctly you can then start setting up deployment scripts. I prefer use MSbuild to deploy as it will give you a lot more fine-grained approach to deployment. MSbuild is a bit strange to start with however once you get the hang of it it's quite powerful.

My deployment script which is added to the TeamBuild config is below. Basically as you can see I do a bit of post-build cleanup before I copy to the live servers. I also use 2 MSbuild frameworks (imported at the top).

<Import Project="$(MSBuildExtensionsPath)\Microsoft\SDC Tasks - Release 2.1.3155.0\Microsoft.Sdc.Common.tasks"/>
<Import Project="$(MSBuildExtensionsPath)\FreeToDev\MSBuild Tasks Suite 3.5\FreeToDev.MSBuild.tasks"/>

<PropertyGroup>
 <InetpubFolder>\\PathToInetPub</InetpubFolder>
 <AppFolder>AppFolder</AppFolder>
 <AppFolderPath>$(InetpubFolder)$(AppFolder)</AppFolderPath>
 <WebDeployName>WebDeployProjectName</WebDeployName>
 <Debug>0</Debug>
 <AppConfiguration>DV</AppConfiguration>
</PropertyGroup>

<Target Name="AfterDropBuild">
 <Message Text="Begin Release to $(AppConfiguration) Webserver" />
 <Message Text="DropLocation = $(DropLocation)" />
 <CallTarget Targets="PostBuildCleanUp"  />
 <CallTarget Targets="DeployApp"  />
</Target>

<Target Name="DeployApp">

 <GetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)">
  <Output TaskParameter="DropLocation" PropertyName="DropLocation"></Output>
 </GetBuildProperties>

 <PropertyGroup>
  <CodeDropLocation>$(DropLocation)\$(AppConfiguration) Release</CodeDropLocation>
 </PropertyGroup>

 <ItemGroup>
  <AppFilesToDelete Include="$(AppFolderPath)\**\*.*" Exclude="$(AppFolderPath)\Library\*.*;$(AppFolderPath)\App_Offline.htm;$(AppFolderPath)\jobs\**\*.*" />
 </ItemGroup>

 <ItemGroup>
  <FilesToDeploy Include="$(CodeDropLocation)\$(AppFolder)\**\*.*" Exclude="" />
 </ItemGroup>

 <Copy SourceFiles="$(CodeDropLocation)\$(AppFolder)\App_Offline[RemoveToActivate].htm" DestinationFiles="$(AppFolderPath)\App_Offline.htm" OverwriteReadOnlyFiles="true"/>

 <Message Text="Deleting files in $(AppFolderPath)" />
 <Microsoft.Sdc.Tasks.File.DeleteFiles Files="@(AppFilesToDelete)" Force="true" Condition="$(Debug)==0" />

 <Message Text="Copy $(CodeDropLocation)\$(AppFolder) to $(AppFolderPath)" />
 <Copy Condition="$(Debug)==0" SourceFiles="@(FilesToDeploy)" DestinationFiles="@(FilesToDeploy->'$(AppFolderPath)\%(RecursiveDir)%(Filename)%(Extension)')" SkipUnchangedFiles="true"/>

 <Message Text="Deploy to $(AppConfiguration) Completed" />
 <Microsoft.Sdc.Tasks.File.DeleteFiles Files="$(AppFolderPath)\App_Offline.htm" Force="true" />

 <OnError ExecuteTargets="ErrorHandler" />
</Target>

<Target Name="ErrorHandler">
 <Message Text="Error encountered!!" />
</Target>

<Target Name="PostBuildCleanUp">

 <GetBuildProperties TeamFoundationServerUrl="$(TeamFoundationServerUrl)" BuildUri="$(BuildUri)">
  <Output TaskParameter="DropLocation" PropertyName="DropLocation"></Output>
 </GetBuildProperties>

 <PropertyGroup>
  <CodeDropLocation>$(DropLocation)\$(AppConfiguration) Release</CodeDropLocation>
 </PropertyGroup>

 <ItemGroup>
  <PostBuildCleanUpFilesToDelete Include="$(CodeDropLocation)\*.*;$(CodeDropLocation)\bin\*.xml;$(CodeDropLocation)\bin\*.pdb"/>
 </ItemGroup>

 <RemoveDir Directories="$(CodeDropLocation)\_PublishedWebsites\Web" />
 <Microsoft.Sdc.Tasks.File.DeleteFiles Files="@(PostBuildCleanUpFilesToDelete)" Force="true">
  <Output TaskParameter="DeletedFiles" ItemName="FilesThatWereDeleted" />
 </Microsoft.Sdc.Tasks.File.DeleteFiles>
 <Message Text="The files that were removed were @(FilesThatWereDeleted)" />

 <FTDFolder TaskAction="Move" Path="$(CodeDropLocation)\_PublishedWebsites\$(WebDeployName)" TargetPath="$(CodeDropLocation)\$(AppFolder)"/>

 <RemoveDir Directories="$(CodeDropLocation)\_PublishedWebsites" />

 <RemoveDir Directories="$(CodeDropLocation)\$(AppFolder)\WebDeploy" />

 <OnError ExecuteTargets="ErrorHandler" />
</Target>

Obviously you will need to modify to your system setup. Also it clears down the target folder before it starts to copy the new build accross. This is to make sure they system is clean but obviously you will need to add anything that you need to keep to the ExcludedFiles list.

I also have a folder for each environment in the main application project. This holds the web.config replacements (another feature of WebDeployment projects) and any other environement specifc files.

It will be a long process to get it working correctly but hopefully this will get you started!! (Obviously if you choose this apporach!)

caveman_dick