需要团队城市(TeamCity)+ WiX + MSBuild 工作流建议

5
我一直在进行持续集成项目的下一步工作,即让TeamCity构建我的应用程序,自动更改所有程序集的版本号,然后创建安装程序。
首先,稍微介绍一下背景:
过去几个月,我已经成功运行了TeamCity,并且它可以很好地构建我的配置并运行我的NUnit和NCover测试。
我花了一些时间研究安装程序——我一直很讨厌InstallShield,并且从未考虑过将其用于我的当前应用程序。我喜欢NSIS,但偶然发现了WiX。我没有任何关于MS Installer架构的详细了解,我知道这对于复杂的项目来说是危险的,因此在某些时候,我需要学习更多相关知识。然而,在浏览SO问题、搜索和阅读博客几天之后,我有了一个成功构建、安装和运行应用程序以及完全卸载所有内容的WiX项目。太棒了!
我也希望TeamCity构建配置可以自动更新所有程序集的版本号。我能够通过在我的开发机器上安装MSBuild Community Tasks并创建一个部署配置来模拟这个功能,该配置使用BeforeBuild目标和FileUpdate任务来更改版本号。这可以正常工作,但是在我的开发机器上,我没有build_vcs_number_1环境变量可供替换。

现在我所处的位置是这样的——我需要让TeamCity进行更新,虽然它有build_vcs_number_1环境变量,但我无法弄清楚如何使用WiX MSBuild Community Tasks。

我读过一篇帖子,建议将MSBuild目标检入到SVN文件夹中。我有一个/extlib文件夹用于存放此类内容,因此我的TeamCity VCS检出规则看起来像这样:

+:tags/2010-10-15=>src
+:extlib=>extlib

当我运行构建时,TeamCity抱怨(并且是正确的),找不到 c:\ wix30 \ MSBuildCommunityTasks 。实际文件夹是 C:\ TeamCity \ buildAgent \ work \ 3e073d2b74226378 \ extlib \ wix30 \ MSBuildCommunityTasks 。由于我正在进行服务器端检出,因此该文件夹是自动生成的,因此必须有一些环境变量由TeamCity设置,我可以使用它来获取正确的路径。
我应该注意的一件事是,我进入了构建配置 - >属性和环境变量,并找到了所有现有变量的非直观下拉列表,但没有看到任何听起来像指向工作路径的变量。
我能想到的一个可能的解决方法是只需在构建服务器上安装MSBuild Community Tasks,然后我就可以创建一个可以通过<WixToolPath>访问的系统环境变量。
还有其他建议吗?

我只是想知道你是否仍然这样工作。在这个问题被创建的大约同一时间,我曾经做过类似的事情,但后来出现了Git和NuGet,我已经慢慢地迁移到使用NuGet作为管理依赖项的主要方式。当然,TeamCity现在有一个AssemblyInfo修补程序,在下一个版本中,他们将使其执行MSBuild Community Tasks所能做的一切。 - Tim Long
我目前仍在这种方式下工作,对我来说它仍然是一个足够好的解决方案,但随着我的带宽增加,我一定会考虑进行更改。我想离开MSBuild社区任务,因为我必须修改每个新程序集,这很不方便。 - Dave
2个回答

1

我认为将msbuild社区任务放在SVN中(以减少构建机器的要求)是有一定优点的,但个人而言,我会直接在服务器上安装它们。重要的是:更新您的构建服务器文档,将其列为先决条件进行安装。对于我来说,我在几个项目和部署脚本中基本上每个msbuild中都使用社区任务,因此将它们全部放在SVN中有点多余。我还在构建服务器上安装了WiX。

我做了类似的事情,但与其在构建之前设置目标,我有一个大致如下的msbuild项目文件:

<Target Name="Build">
    <CallTarget Targets="UpdateVersionNumbers"/>
    <MSBuild Projects="Project.sln" Targets="Build"/>
</Target>

我的UpdateVersionNumbers目标获取SVN修订版本,然后使用正则表达式和FileUpdate任务将版本号的第四部分更改为SVN修订版本。

然后我运行解决方案文件的普通构建,并在其中包括构建.wixproj。非常简单。


回答一些你其他的问题:

  • 在指定路径时,始终使用相对于解决方案(检出目录)根的路径。例如,在此情况下,您只需使用wix30\MSBuildCommunityTasks。TeamCity将使用工作目录作为根来执行msbuild,而且无论您或其他开发人员将其检出到何处,路径都是相对的。
  • 您可以通过构建参数->系统属性将参数传递给msbuild。例如,添加一个名为agentHome的属性,其值为%system.agent.home.dir%,然后您可以在msbuild文件中引用它为$(agentHome)。请注意,如果您像上面的示例一样再次调用msbuild,则必须执行以下操作:

    <MSBuild Projects="Project.sln" Properties="agentHome=$(agentHome)" Targets="Build"/>
    

    以实际将该变量传递到Project.sln中。我认为但不确定运行在.sln文件上的msbuild也将向所有单独的项目传递所有属性,因此您可以在构建前事件中访问它。


关于安装程序的一些注意事项(我最近也经历了和你一样的事情):我选择了WiX 3.0,虽然它有相当陡峭的学习曲线,但它运行良好。我们开始了一个新的开发流程,并开始使用VS2010和.NET 4。然而,WiX 3.0与VS2010不兼容,因此我们需要WiX 3.5(尽管现在它的状态似乎比几个月前要好得多,但它们仍然滞后。这就是开源的本质,有时候会出现这种情况)。我在安装WiX 3.0和3.5时遇到了一些问题, 但最终还是解决了。

然而,由于WiX的不兼容性、不稳定的测试版(几个月前的)以及整体进展缓慢,这让我非常失望(无意冒犯WiX的开发人员,但我只是想要一个安装程序,而不想太过深入地涉及其中。请注意,他们也感到非常沮丧)。再加上我需要的下一个产品需要一个更复杂的安装程序,WiX似乎就太费力了。我只是使用AdvancedInstaller构建了我的安装程序,只花了几天时间,到目前为止一直运行良好(虽然我们现在还处于早期开发阶段,但开始进行持续部署和测试)。AI的价格合理(我们现在仍在试用版本),但我将在未来几天内购买。

我确信我学习AI所花费的时间比学习WiX并尝试使其满足我所有需求所花费的时间要少得多。了解Windows Installer的工作原理是不可避免的,但您不必过于深入。


感谢您提供的好建议 - 我还在仔细阅读,但看起来非常不错。明天我可能会有更多问题。 :) - Dave
我对将WiX放入SVN的一个评论是,开发人员将少安装一件东西。目前,我的WiX项目是我的应用程序解决方案的一部分。我可以有两种选择,我猜--我可以这样做,并让TeamCity构建应用程序,然后构建安装程序(我想...)。如果我将WiX项目保留在解决方案中,则其他开发人员需要在其系统上安装WiX,以便VS2008可以加载该项目而不会出现烦人的错误。但他们至少不必安装MSBuild Community Tasks。 - Dave
@Dave:你有 <Import Project="$(MSBuildExtensionsPath)\MSBuildCommunityTasks\MSBuild.Community.Tasks.Targets"/> 吗? - gregmac
@gregmac 我正在使用 <Import Project="$(WORK_FOLDER)\extlib\wix30\MSBuilCommunityTasks\MSBuild.Community.Tasks.Targets" />。如果我安装了 MSBCT 和 WiX,它就可以工作,但是没有它们就不行。我还没有回去看看是否需要两个或只需要其中一个。 - Dave
我又回到了这个问题,现在我不得不重建服务器并开始支持VS2010 + WiX 3.5。我很好奇你的方法是使用一个单独的构建项目来启动文件版本更改的。那么,你最终是编写自己的目标,遍历文件结构,找到所有的AssemblyInfo.cs文件,然后进行修改吗?这听起来像是一个不错的方法,可以避免手动修改每个.csproj文件...虽然我写了一个Python脚本来完成这个工作,但我也愿意尝试其他解决方案。谢谢! - Dave
显示剩余2条评论

0

我讨厌这种情况...打了一个长问题,只发现几分钟后错过了什么。

我想知道这是否就是它:

alt text

我现在的问题是 - 我是否可以在我的.wixproj中实际使用%system.agent.work.dir%?我现在会尝试一下。

重新审视这个问题,如果我没记错的话,答案是否定的——你设置名称,然后在 .csproj 中引用该名称。 - Dave

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接