如何使用Team Build部署ASP.NET Web应用程序?

时间:2009-03-09 22:28:31

标签: asp.net tfs team-build

我已经设法安装了Team Foundation Server 2008,并且我创建了一个单独的构建服务器(因为我的构建当前失败了,所以它可以正常工作)。

我创建了一个简单的“Hello World”Web应用程序(都是标准的Default.aspx页面)并将其放在TFS的源代码控制系统中。

以前,在TFS之前,我只是预编译我的Web应用程序并将结果xcopy写入预先创建的IIS虚拟目录。

谷歌搜索了一段时间,我还没有找到一个分步指南,正确地将应用程序从TFS Source通过TeamBuild部署到指定的测试Web服务器。我知道MS Build属于这个等式,因此任何指导都会有所帮助。

我看过有关部署的点点滴滴,提到了_PublishedWebSites这样的文件夹,但还没有一步一步找到。

3 个答案:

答案 0 :(得分:4)

我在TFSBuild.proj文件中的AfterDropBuild目标中使用了exec任务已经成功。

<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>

请注意,需要正确设置权限,以便TFS服务用户访问您要复制到的服务器上的文件夹。

答案 1 :(得分:4)

首先,您应该使用WebDeployment项目,因为这将进行更多的编译和检查您的代码和标记。有关详细信息,请参阅here

我有4个环境设置DV [开发],PY [原型],PP [预生产],PD [生产] TFS中所有匹配的分支。其中每个都在sln配置管理器中有一个条目,您可以在其中设置需要构建的项目和构建标志。

一旦设置正确,您就可以开始设置部署脚本了。我更喜欢使用MSbuild进行部署,因为它会为您提供更细粒度的部署方法。 MSbuild开始时有点奇怪,但是一旦掌握了它,就会非常强大。

我的部署脚本添加到TeamBuild配置中,如下所示。基本上你可以看到我在复制到实时服务器之前做了一些后期构建清理。我还使用了2个MSbuild框架(在顶部导入)。

<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>

显然,您需要修改系统设置。此外,它会在开始复制新构建之前清除目标文件夹。这是为了确保他们的系统是干净的,但显然你需要添加你需要保存到ExcludedFiles列表中的任何内容。

我还为主应用程序项目中的每个环境都有一个文件夹。这包含web.config替换(WebDeployment项目的另一个功能)和任何其他environement特定文件。

要让它正常工作将是一个漫长的过程,但希望这会让你开始! (显然,如果你选择这个apporach!)

答案 2 :(得分:2)

这可以通过构建脚本直接完成,Vertigo软件人员通常是很多TFS问题的最佳信息来源......不幸的是他们的博客文章通常不会在谷歌上排名那么高。这是由本网站的创建者之一Jeff Atwood撰写的:

Copying Web Files After a Team Build