【问题标题】:Extract branch name in MSBuild prebuild step在 MSBuild 预构建步骤中提取分支名称
【发布时间】:2017-03-09 06:57:48
【问题描述】:

我的最终目标是在 MSBuild 预构建事件中提取分支名称(它是 $SolutionDirectory 的一部分),然后将其注入我的 app.config appSettings。

我一直在做大量的挖掘工作,但还没有真正找到解决这个问题的方法。

我希望能够在预构建期间做这样的事情:

<XmlPoke XmlInputPath="App.config" 
  Query="/configuration/appSettings/add[@key='BuildBranch']/@value" 
  Value="$(Branch)" />

以前有人做过这样的事吗?

【问题讨论】:

    标签: c# tfs msbuild build-automation


    【解决方案1】:

    也许 MsBuild 扩展包适合您?有任务 MSBuild.ExtensionPack.Xml.XmlFile 和 Action UpdateAttribute (http://www.msbuildextensionpack.com/help/3.5.11.0/html/4009fe8c-73c1-154f-ee8c-e9fda7f5fd96.htm) 来更改现有属性值。您必须定义文件、xpath 和值来执行此操作。但我不确定此异常是否适用于新版本的 .net 框架。

    【讨论】:

    • 嗯,我得看看这个。如果这对我有用,这将使我达到 50% 的目标。当我在分支之间切换时,我仍然需要一种动态提取分支名称的方法。
    • 我自己实际上无法尝试,但也许您可以在预构建事件中运行批处理文件并将该文件的输出作为 msbuild 属性传递并在任务中使用它,我之前向您展示过。在该 bat 文件中,您可以运行 git 命令: git rev-parse --abbrev-ref HEAD (此命令将为您提供当前分支)并将其作为输出回显,然后也许有某种方法可以处理该输出并稍后使用它。
    • 不需要批处理文件,你可以直接使用Exec运行git(最好指定--git-dir和--work-tree而不是依赖当前目录)并获取输出
    • 不使用 git。使用 TFS。
    【解决方案2】:

    我的建议是不要依赖你在 $SolutionDirectory 上的路径,因为不能保证值会在那里,你可以在任何目录中检出你的代码并打破规则。

    我认为所有这些都是为了构建自动化,对吧?除了您用于自动化的工具之外,还有一些关于 MSBuild Properties 的重要事项需要记住:

    • 可以在您的 MSBuild 脚本中定义属性
    • 可以从命令行覆盖属性(这可以通过脚本进行限制)。
    • 任何遵循 MSBuild 属性命名约定的环境变量都将被解释为属性。

    考虑到这一点,您需要这样做:

    1. 在您的脚本中使用默认值定义一个“分支”属性(即开发、主控)。允许从命令行/环境变量覆盖它。

      <PropertyGroup>
          <Branch Condition="'$(Branch)'==''">develop</Branch>
      </PropertyGroup>
      
    2. 从您的构建系统(持续集成服务器)发送适当的值,它可以作为环境变量或命令行属性。无论您使用哪种工具,它们都支持这一点。 (TFS、TeamCity、CruiseControl.Net 等)其中一些将根据源代码控制设置进行预定义,在其他情况下,您需要手动进行。您可以查看现有的构建日志以查看是否已经为分支设置了属性,或者检查您是否正确设置了属性。

    3. 根据需要使用预构建事件中的值。

    出于开发目的,在 Visual Studio 中右键单击您的项目 > 属性 > 调试,在“命令行参数”字段中添加:/p:Build=yourbranchname 当您从 VS 运行构建时将使用此处定义的值。

    【讨论】:

      【解决方案3】:

      只想感谢大家的帮助。虽然答案并没有完全让我得到我想要的,但它把我推向了满足我需求的正确方向。这是我最终采用的解决方案:

      <Target Name="AfterBuild">
        <XmlPoke Condition=" '$(TeamBuildOutDir)' == '' " XmlInputPath="$(ProjectDir)bin\$(ConfigurationName)\$(TargetName).dll.config" Query="/configuration/appSettings/add[@key='BuildInfo']/@value" Value="$(SolutionDir)" />
        <XmlPoke Condition=" '$(TeamBuildOutDir)' != '' " XmlInputPath="$(TeamBuildOutDir)\$(SolutionName)\$(ProjectName)\$(TargetName).dll.config" Query="/configuration/appSettings/add[@key='BuildInfo']/@value" Value="$(SolutionDir)" />
      </Target>
      

      事实证明,我们实际上是在构建机器上做一些时髦的东西,这些东西的目录结构与本地目录大不相同。我们正在使用 $(TeamBuildOutDir) 构建属性来转储我们所有的二进制文件。在获得这些知识后,我能够为我们的需求创建上述解决方案。这最终创建了一个相当一致的字符串,我可以将其附加到我的 BuildInfo 属性并稍后处理。

      希望这对其他人有帮助!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2017-02-01
        • 1970-01-01
        • 2011-04-25
        • 2014-02-12
        • 1970-01-01
        • 1970-01-01
        • 2015-07-25
        • 1970-01-01
        相关资源
        最近更新 更多