我已经用 MSBuild 完成了这件事。我的案例涉及的步骤是:
- TFS 使用自定义 MSBuild 项目而不是解决方案文件执行构建。任何 CI 构建系统都可以工作,在这种情况下 TFS 没什么特别的。
- 在自定义构建项目中,除了构建所有项目之外,我还复制了一堆 web.config“模板”文件到 $(OutDir) 文件夹下的一个特殊文件夹中。这些最终会出现在 TFS 的构建中。在我的例子中,内置的配置文件转换还远远不够复杂,但如果这对你有用,那么它就更简单了。
- web.config 文件实际上包含对其他配置文件的引用,每个配置文件对应一个。这使用了自定义配置提供程序。不过,如果您只有一个 web.config 文件,这种技术也可以使用。
- 我从命令行启用了自动部署(发布),作为驱动构建的同一自定义 MSBuild 项目中的新 MSBuild 目标。
- 然后很容易将主构建中的发布步骤自动化到 VM 或 QA 机器,并可以从命令行手动部署到其他服务器(最终是临时服务器)。
web.config 模板有这样的东西:
In the connection string: "Data Source=${SQLINSTANCE};Initial Catalog=${SQLDATABASENAME}..."
重要的是,可替换标记的分隔符是 ${ } 而不是 $( ),因为 MSBuild 不会与大括号混淆。
在 Publish 步骤中,使用 MSBuild 属性函数替换配置文件中的位,以下内容来自 MSDN 对 MSBuild 内联任务的描述:
<UsingTask
TaskName="ReplaceToken"
TaskFactory="CodeTaskFactory"
AssemblyFile="$(MSBuildToolsPath)\Microsoft.Build.Tasks.v4.0.dll">
<ParameterGroup>
<File ParameterType="System.String" Required="true" />
<Token ParameterType="System.String" Required="true" />
<Replacement ParameterType="System.String" Required="true" />
</ParameterGroup>
<Task>
<Code Type="Fragment" Language="cs">
<![CDATA[
string content = File.ReadAllText(File);
content = content.Replace(Token, Replacement);
File.WriteAllText(File, content);
]]>
</Code>
</Task>
</UsingTask>
然后在你的项目中,你可以使用这个任务,
<ReplaceToken
File="PathTo\Web.config"
Token="${SQLINSTANCE}"
Replacement=".\SQLEXPRESS"
/>
这实际上只是一个粗略的指南,ReplaceToken 的所有参数也在 MSBuild 项目元数据中配置,允许选择哪些数据库、服务器、安全性等,每个选项都可以单独指定。
因此,对于每个构建/部署,它将执行构建、复制配置模板、对其进行字符串替换,然后自动化打包/发布,这是最后一步。
你最好的选择是从这个博客开始:http: //vishaljoshi.blogspot.com/2009/02/web-packaging-creating-web-packages.html解释了一点,这个答案包含了一堆其他相关 StackOverflow 帖子的MsBuild 和 MsDeploy 与多个环境,然后使用http://www.bing.com/search?q=msbuild+msdeploy+command+line&go=&form=QBLH&qs=n&sk=在线搜索深入挖掘。我真的很讨厌把你丢给搜索引擎来搜索这部分内容,但我发现有很多不同的场景,很难挑出一个。前十名回复中约有一半对某些有价值的角度有见解。回复更多信息以帮助缩小我此时的回复范围。对于我的实现,我使用 Exec 任务直接从 MSBuild 调用 MSDeploy.exe。需要考虑的一些事项:
- 如何处理各种发布站点上的安全问题。我不得不设置一堆构建服务帐户,并且总是需要在 msbuild 命令行上传递密码。如果您可以像您建议的那样使用 Windows 身份验证,那会更容易一些。
- 对于服务,我必须使用 PSExec 在远程服务器上运行 installutil
- 我使用 PSExec 在远程服务器上调用 appcmd 自动化了一些额外的配置项。
- 在服务器上打开远程共享并在构建期间使用“net use”命令映射和取消映射很容易,您可能有其他偏好。
- 性能是艰难的。对于较大的站点,它可以逐个文件运行很长时间。RoboCopy 并不快。我发现使用 MSDeploy 远程打包(指向本地 drop 作为源,并远程共享包源)对 Rackspace 来说非常快。您可能需要先使用一个 MSDeploy 调用将包打包到一个 zip 文件,然后再使用第二个调用远程推送该包。
希望这能让你开始。如果我真的错过或掩饰了什么,请在您的问题中发表评论或提供更多细节。
回复评论:
“发布”目标是这样的,
<Target Name="Publish">
<!-- token replacement in config files, as above -->
<!-- ...lots of custom setup, selection of various properties used below -->
<PropertyGroup>
<_MsDeployExe>$(PROGRAMFILES)\IIS\Microsoft Web Deploy\msdeploy</_MsDeployExe>
<_MsDeploySourceArg>-source:contentpath="$(_BuildDropFolder)"</_MsDeploySourceArg>
<_MsDeployDestArg>-dest:contentpath=\\$(_RemoteComputerName)\DropFolder</_MsDeployDestArg>
</PropertyGroup>
<Message
Text=""$(_MsDeployExe)" -verb:sync $(_MsDeploySourceArg) $(_MsDeployDestArg)"
/>
<Exec
Condition="'$(DryRun)' != 'true'"
Command=""$(_MsDeployExe)" -verb:sync $(_MsDeploySourceArg) $(_MsDeployDestArg)"
ContinueOnError="false"
WorkingDirectory="$(MSBuildThisFileDirectory)"
/>
</Target>