如果视图已更改,请使用TeamCity启用MvcBuildViews

Phi*_*ale 7 .net asp.net-mvc powershell teamcity asp.net-mvc-4

脚本

我们有TeamCity 8.1.3构建每个拉取请求.GitHub报告了构建失败.这很棒.但是没有查看视图错误.这是不好的.我可以全面启用MvcBuildViews,但我不愿意,因为我们的解决方案非常庞大,而且编译时间大约是三倍.

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

我试过的

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

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

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

这不像我希望的那样有效.在同一分支上提交.cs文件和.cshtml文件将触发两个构建.

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

这失败了,因为我无法弄清楚读取代理属性.我找到了这个相关的SO问题,但它没有用.

我的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']"
Run Code Online (Sandbox Code Playgroud)

接下来是什么?

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

Phi*_*ale 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']"
}
Run Code Online (Sandbox Code Playgroud)

更新 22/10/2014

我在这里编写了该脚本的稍微高级的版本。