【问题标题】:Turn on MvcBuildViews using TeamCity if a view is changed如果视图发生更改,则使用 TeamCity 打开 MvcBuildViews
【发布时间】:2014-12-09 12:36:41
【问题描述】:

场景

我们让 TeamCity 8.1.3 构建每个拉取请求。构建失败在 GitHub 中报告。这很棒。但是,视图错误不会被拾取。这是不好的。我可以全面打开 MvcBuildViews,但我宁愿不这样做,因为我们的解决方案非常大,而且编译时间大约增加了三倍。

我想做的是仅在 PR 中的提交中更改了视图时才启用 MvcBuildViews。例如,如果有人更改了 .cs 文件,则可以正常编译。如果更改了 .cshtml 文件,则启用 MvcBuildViews 并编译。

我的尝试

我的第一次尝试使用了VCS triggers。我在 TeamCity 中建立了两个几乎相同的项目。唯一的区别是 VCS 触发器。一个构建旨在构建代码更改和另一个视图更改。

代码更改触发规则:-:\**.cshtml+:**.cs

查看变更触发规则:+:**.cshtml

这并没有像我希望的那样工作。在同一个分支上提交 .cs 文件和 .cshtml 文件会触发这两个构建。

我的第二次尝试是使用 PowerShell 构建步骤。我想知道是否可以使用 PowerShell 读取 teamcity.build.changedFiles.file 代理构建属性,确定 cshtml 文件是否已更改,如果已更改,请将 MvcBuildViews 设置为 true。

这失败了,因为我不知道如何读取代理属性。我找到了这个relevant SO question,但它没有用。

我的 PS 构建步骤如下所示。我在这里主要是抓着稻草。

write-host "##teamcity[message text='Starting PhilTest build step']"

write-host "##teamcity[message text='Build number $env:build_number']" #Outputs build number

write-host "##teamcity[message text='Changed files $env:teamcity_build_changedFiles_file']" #Outputs nothing

foreach ($row in $env:teamcity_build_changedFiles_file)
{
    write-host "##teamcity[message text='Changed files row $row']" #Outputs nothing
}

write-host "##teamcity[message text='Ending PhilTest build step']"

下一步是什么?

以前有人做过吗?有谁知道我如何才能让我以前尝试工作或知道另一种方法吗?

【问题讨论】:

    标签: .net asp.net-mvc asp.net-mvc-4 powershell teamcity


    【解决方案1】:

    teamcity.build.changedFiles.file 没有环境变量,您可以在此文档中看到:Predefined Build Parameters

    在这种情况下,您可以使用 %system.teamcity.build.changedFiles.file%。 TeamCity 会将文件的完整路径传递给您的 PowerShell 脚本,其中包含有关构建中包含的已更改文件的信息。

    文件包含换行符分隔的文件:每一行对应一个文件,格式如下:

    <relative file path>:<change type>:<revision>
    

    【讨论】:

      【解决方案2】:

      使用 giacomelli 的回答作为起点,我创建了这个 TeamCity PowerShell 构建步骤,它完全符合我的要求。它读取已更改文件的列表,确定视图是否已更改,如果已更改,则在所有 csproj 文件中将 MvcBuildViews 设置为 true。请注意:

      • 我不是 TeamCity 或 PowerShell 专家,您可能需要稍微整理一下
      • 您不太可能希望在 所有 csproj 文件上设置 MvcBuildViews

      在使用它时不太重要,我注意到 TeamCity 认为构建是随着时间的推移。不确定是否可以对此采取任何措施。

      $changedFileInfoPath = '%system.teamcity.build.changedFiles.file%'
      $fileData = Get-Content $changedFileInfoPath
      
      $containsViews = $false
      
      foreach($line in $fileData)
      {
          write-host "##teamcity[message text='File contents = $line']"
          if($line -like "*.cshtml*")
          {
            $containsViews = $true
            break
          }
      }
      
      if ($containsViews)
      {
          write-host "##teamcity[message text='View changes found']"
      
          function xmlPoke($file, $xpath, $value) 
          {
              $filePath = $file.FullName
      
              [xml] $fileXml = Get-Content $filePath
              $node = $fileXml.SelectSingleNode($xpath)
              if ($node) 
              {
                  $node.InnerText = $value
      
                  $fileXml.Save($filePath)
              }
          }
      
          $workingDirectory = '%teamcity.build.workingDir%'
      
          $webCsProjFiles = Get-ChildItem -Path $workingDirectory -Recurse -Include "*.csproj"
      
          foreach ($csProjFile in $webCsProjFiles)
          {
              xmlPoke $csProjFile "//*[local-name()='MvcBuildViews']" "true"
              write-host "##teamcity[message text='Set MvcBuildViews true in $csProjFile']"
          }
      }
      else
      {
          write-host "##teamcity[message text='No view changes were found']"
      }
      

      2014 年 10 月 22 日更新

      我已经编写了这个脚本的稍微高级的版本here

      【讨论】:

      • 留下评论指出仅在视图更改时将 MvcBuildViews 标志限制为 true 实际上是一个非常糟糕的主意 - 非常可能会在不更改视图的情况下破坏视图更改它(如果有的话,这比其他任何事情都更有可能发生,例如,如果您更改 ViewModel 而不更新视图本身)
      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2021-06-24
      • 1970-01-01
      • 2017-12-30
      • 2012-12-04
      相关资源
      最近更新 更多