利用 MSBuild 实现 Web Application 项目的每日构建(上)

原创 2007年10月06日 12:07:00

每日构建,对于这个术语,大家已是耳熟能详。不管项目有多大或有多小,我们都在潜意识的进行持续性构建,无非就是自动化和方便性的程度高低而已。

最近几年我主要开发基于 .NET 平台的应用软件,其中又以 B/S 架构为多。既然是在.NET平台上开发,我倾向于尽量使用此平台上的工具来做每日构建。经过几番查找和实验,发现以 MSBuild 为主、以基于 MSBuild 的开源软件为辅的方法,即可完成 Web Application 项目的自动化每日构建。

我要实现的每日构建,其流程如下:

  1. 从源代码库获取最新源代码;
  2. 根据需要(Debug/Release)编译项目;
  3. 备份编译的项目程序集及其所需文件;
  4. 项目发布;
  5. 每日构建结果通知;

所用软件:

MSBuild,其用法请参考微软相关文档,MSBuild Community Tasks,则可以参考其文档。

至于我为什么要用 MSBuild Community Tasks,原因在于 MSBuild 提供的 Task 不足以达到我的要求,比如版本号维护、文件(夹)压缩、在 IIS 中创建/删除虚拟目录、EMail等等。

一旦准备好环境,就可以开始每日构建的具体步骤了。

考虑到每日构建的最后一步——结果通知——依赖编译及发布的结果,以及自动化的要求,故分为以下三个文件来完成调用:

  1. 步骤2、3、4放在 Project 文件 TestProject.proj 中;
  2. 步骤1和步骤5放在 Project 文件 DailyBuild.proj 中,其间调用 TestProject.proj,在步骤5中根据编译发布结果发送不同的 EMail;
  3. 批处理文件 DailyBuild.bat,调用 Project 文件 DailyProject.proj,记录日志,用以 Windows 任务调用;

以下是各个步骤的源代码。

步骤1:从源代码库获取源代码

<!-- 忽略错误,我们需要自己控制结果。-->
<Target Name="SyncSource">
    
<Exec
        
Command="[Your command line]"
        IgnoreExitCode
="true"
        
>
        
<Output TaskParameter="ExitCode" PropertyName="ExitCode" />
    
</Exec>

    
<Error Text="Failed to Sync source code." Condition=" $(ExitCode) != 0 " />
</Target>

 步骤2:根据需要(Debug/Release)编译项目,及步骤3:备份编译的项目程序集及其所需文件

<Target Name="CoreBuild">
    
<RemoveDir Directories="$(TempDir)" Condition="Exists('$(TempDir)')" />

    
<MakeDir Directories="$(TempDir)%(Configuration.Identity)" />

    
<MSBuild Projects="$(ProjectReferences)" Targets="Build"
        Properties
="Configuration=%(Configuration.Identity);OutDir=$(TempDir)%(Configuration.Identity)"
    
/>

    
<Copy
        
SourceFiles="$(TempDir)%(Configuration.Identity)_PublishedWebsitesWebWeb.config.%(Configuration.Identity)"
        DestinationFiles
="$(TempDir)%(Configuration.Identity)_PublishedWebsitesWebWeb.config"
        SkipUnchangedFiles
="false"
    
/>

    
<Delete Files="$(TempDir)%(Configuration.Identity)_PublishedWebsitesWebWeb.config.Debug" />
    
<Delete Files="$(TempDir)%(Configuration.Identity)_PublishedWebsitesWebWeb.config.Release" />

    
<CreateItem Include="$(TempDir)%(Configuration.Identity)_PublishedWebsitesWeb***.*">
        
<Output
            
TaskParameter="Include"
            ItemName
="%(Configuration.Identity)SourceFiles"/>
    
</CreateItem>

    
<Zip
        
Files="@(%(Configuration.Identity)SourceFiles)"
        WorkingDirectory
="$(TempDir)%(Configuration.Identity)_PublishedWebsitesWeb"
        ZipFileName
="$(TempDir)%(Configuration.Identity)Web$(BuildNumber).zip" />

    
<RemoveDir
        
Directories="$(DailyBuildDir)%(Configuration.Identity)"
        Condition
="Exists('$(DailyBuildDir)%(Configuration.Identity)')"
    
/>

    
<MakeDir Directories="$(DailyBuildDir)%(Configuration.Identity)" />

    
<Copy
        
SourceFiles="$(TempDir)%(Configuration.Identity)Web$(BuildNumber).zip"
        DestinationFolder
="$(DailyBuildDir)%(Configuration.Identity)"
        SkipUnchangedFiles
="false"
    
/>
        
    
<RemoveDir
        
Directories="$(LatestBuildDir)%(Configuration.Identity)"
        Condition
="Exists('$(LatestBuildDir)%(Configuration.Identity)')"
    
/>

    
<MakeDir Directories="$(LatestBuildDir)%(Configuration.Identity)" />

    
<Copy
        
SourceFiles="$(TempDir)%(Configuration.Identity)Web$(BuildNumber).zip"
        DestinationFolder
="$(LatestBuildDir)%(Configuration.Identity)"
        SkipUnchangedFiles
="false"
    
/>
</Target>

步骤4:项目发布

<Target Name="AfterBuild">
    
<Copy
        
SourceFiles="@(PublicFiles)"
        DestinationFiles
="@(PublicFiles->'$(WWWRoot)%(RecursiveDir)%(Filename)%(Extension)')"
        SkipUnchangedFiles
="false"
    
/>

    
<ServiceController ServiceName="w3svc" Action="Restart" />

    
<WebDirectoryDelete
        
VirtualDirectoryName="$(VirtualDirectoryName)"
        Condition
="Exists('$(VirtualDirectoryPhysicalPath)')"
        ContinueOnError
="true"
    
/>

    
<RemoveDir
        
Directories="$(VirtualDirectoryPhysicalPath)"
        Condition
="Exists('$(VirtualDirectoryPhysicalPath)')"
    
/>

    
<MakeDir Directories="$(VirtualDirectoryPhysicalPath)" />

    
<Copy
        
SourceFiles="@(DebugSourceFiles)"
        DestinationFiles
="@(DebugSourceFiles->'$(VirtualDirectoryPhysicalPath)%(RecursiveDir)%(Filename)%(Extension)')"
        SkipUnchangedFiles
="false"
    
/>

    
<WebDirectoryCreate
        
VirtualDirectoryName="$(VirtualDirectoryName)"
        VirtualDirectoryPhysicalPath
="$(VirtualDirectoryPhysicalPath)"
        AuthAnonymous
="False"
        AuthBasic
="false"
        AuthNtlm
="true"
        EnableDefaultDoc
="true"
        DefaultDoc
="Index.aspx"
    
/>

    
<WebDirectoryDelete
        
VirtualDirectoryName="$(NeedsToBeDeletedVirtualDirectoryName)"
        Condition
="Exists('$(NeedsToBeDeletedVirtualDirectoryPhysicalPath)')"
        ContinueOnError
="true"
    
/>

    
<RemoveDir
        
Directories="$(NeedsToBeDeletedVirtualDirectoryPhysicalPath)"
        Condition
="Exists('$(NeedsToBeDeletedVirtualDirectoryPhysicalPath)')"
    
/>
</Target>

步骤5:每日构建结果通知

<Target Name="SendEMailOnSuccess">
    
<Mail
        
SmtpServer="smtphost"
        To
="@(ToEMailAddress)"
        Cc
="@(CcEMailAddress)"
        From
="$(FromEMailAddress)"
        Subject
="TestProject Daily Build from $(SourceBranch) source"
        IsBodyHtml
="true"
        Body
="[You email body for building success]"
        Attachments
="@(LogFile)"
    
/>
</Target>

<Target Name="SendEMailOnFail">
    
<Mail
        
SmtpServer="smtphost"
        To
="@(ToEMailAddress)"
        Cc
="@(CcEMailAddress)"
        From
="$(FromEMailAddress)"
        Subject
="TestProject Daily Build from $(SourceBranch) source"
        IsBodyHtml
="true"
        Body
="[You email body for building fail]"
        Attachments
="@(LogFile)"
    
/>
</Target>

最后就是自动化了,每日调度实现自动化。编写含有以下内容的批处理文件,然后将其放入 Windows 任务计划中即可。

rem @echo off

echo User Domain: %userdnsdomain%
echo User Name: %username%

set CurrentDate=%date=_%
set CurrentDate=%CurrentDate:/=_%
set CurrentDate=%CurrentDate:-=_%

set CurrentTime=%time=0%
set CurrentTime=%CurrentTime::=_%
set CurrentTime=%CurrentTime:.=_%

set LogFileName=%CurrentDate%.%CurrentTime%.log

%SystemRoot%/
Microsoft.NET/Framework/v2.0.50727/MSBuild.exe /nologo /noconlog /l:FileLogger,Microsoft.Build.Engine;logfile=E:/Build/Logs/DailyBuild.%LogFileName%;append=false;verbosity=normal;encoding=utf-8 /p:WWWPath=C:/Inetpub/wwwroot;SourceBranch=Development;SourcePath=D:/Source/TestProject/Web;BuildPath=E:/Build "D:Source/TestProject/Build/DailyBuild.proj"

利用 MSBuild 实现 Web Application 项目的每日构建(下)

 在上篇文章 利用 MSBuild 实现 Web Application 项目的每日构建(上) 中,零零碎碎的发表了一些代码。在这篇文章中,我会附上完整的代码。欢迎各位积极交流。1.TestProje...
  • AutumnalRiver
  • AutumnalRiver
  • 2007年11月03日 18:15
  • 864

使用MSBUILD发布Web Application

VS Publish Web Application的功能很好用,能够直接预编译整个站点。对于Website, 可以在命令行下通过aspnet_compiler来进行预编译。但是对于Web Appli...
  • jianzhiying
  • jianzhiying
  • 2010年02月05日 16:26
  • 1944

C# 搭建DotNetty客户端

以下是DotNetty开源项目 https://github.com/Azure/DotNetty 我得出的结论:(2017年3月29日) 1.DotNetty 只能通过 vs 2017 进行加...
  • u013244192
  • u013244192
  • 2017年03月29日 20:47
  • 10141

利用jenkins实现自动构建、部署,提升团队开发效率

一大早就被群里的同学刷银川下雪的消息,看着我都发冷,突觉一阵凉风裹身,是不是该考虑秋裤了。         偏离主题,正文走起......         使用jenkins目标:利用...
  • hero272285642
  • hero272285642
  • 2018年01月26日 09:24
  • 293

每日构建 Daily build

一个好的办法是每日构建(daily builds)。 每日构建意味着自动地,每天,完整地构建整个代码树、(译者按:“代码树”,原文为source tree,意思是将整个项目源代码的目录,子目录,文件的...
  • u013890660
  • u013890660
  • 2014年03月17日 10:49
  • 997

VSTS2005实现团队项目的每日构建

1、安装TFSBuild工具TFS默认情况下是没有安装TFSBuild工具的,在TFS2005安装光盘的bb目录下,点击setup.exe文件,安装TFSBuild工具。2、查看TFSBuild工具的...
  • lindingbao
  • lindingbao
  • 2008年11月04日 13:07
  • 469

msbuild构建web应用脚本

@echo off SET DestPath=D:\projectFolder SET SrcPath=D:\srcFolder SET ProjectName=ProjectName SET Con...
  • yz1988computer
  • yz1988computer
  • 2015年10月22日 10:12
  • 806

Myeclipse中导入Android项目时,提示的错误:由于项目的构建路径不完整,所以未构建该项目。

在Myeclipse中将一个Android程序代码引入到项目中时,在构建项目过程中提示的错误: 1 由于项目的构建路径不完整,所以未构建该项目。找不到 java.lang.Object 的类文件。修...
  • u010919530
  • u010919530
  • 2013年07月22日 11:01
  • 4154

一年多推行每日构建的经验总结

作者:朱金灿来源:http://blog.csdn.net/clever101         早在主持开发产品新版本之初,我就有一个略显激进的想法:新产品的测试版本发布频率至少在一周之内。开发人员倾...
  • clever101
  • clever101
  • 2014年08月31日 21:52
  • 3163

持续集成与每日构建

  每个经历过完整游戏项目开发的人都永远会清楚的记得从开发到运营阶段所经历过的那些痛苦:枯燥的代码提交、代码更新、编译、提交可执行程序再到测试的过程;永远改不完的BUG;修改了一处BUG结果引入了更多...
  • lfhfut
  • lfhfut
  • 2009年02月07日 10:27
  • 3472
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:利用 MSBuild 实现 Web Application 项目的每日构建(上)
举报原因:
原因补充:

(最多只允许输入30个字)