Enable MvcBuildViews using TeamCity if changing view

Scenario

We have TeamCity 8.1.3 creating every pull request. Build failure reported on GitHub. Fine. However, viewing errors are not matched. This is bad. I could include MvcBuildViews in all directions, but I would prefer our solution to be quite large and this will approximately triple the compilation time.

What I would like to do is enable MvcBuildView only if the view has been changed in a commit in PR. For example, if someone changes the .cs file, then it compiles as usual. If the .cshtml file is modified, include MvcBuildViews and compile.

What i tried

My first attempt was using VCS triggers . In TeamCity, I created two almost identical projects. The only difference was VCS triggers. One assembly was designed to create code changes, and the other a change.

Code change trigger rules: -:\**.cshtml and +:**.cs

View change trigger rules: +:**.cshtml

This did not work as I hoped. In this case, the .cs file and the .cshtml file in the same branch will start both assemblies.

My second attempt was to use the PowerShell build step. I was wondering if it is possible to use PowerShell to read the agent assembly property of the teamcity.build.changedFiles.file agent, determine if the cshtml file has been changed, and if MvcBuildViews has been set to true.

This failed because I could not figure out how to read the properties of the agent. I found this corresponding SO question , but it did not work.

My PS build step looks like this. I mostly cling to a straw here.

 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']" 

What's next?

Has anyone done this before? Does anyone know how I can get one of my previous attempts to work or learn how to do this?

+7
powershell asp.net-mvc asp.net-mvc-4 teamcity
source share
2 answers

Using giacomelli's answer as a starting point, I created this TeamCity PowerShell build step that does exactly what I want. It reads in the list of modified files, determines if the view has been changed, and if this sets MvcBuildViews true in all csproj files. Remember:

  • I'm not an expert at TeamCity or PowerShell, you probably want to reduce this a bit.
  • It is unlikely that you will want to install MvcBuildViews in all csproj files.

Less important when using this, I noticed that TeamCity believes that the build is over time. Not sure if you can do something about it.

 $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']" } 

Update 10/22/2014

I wrote a slightly more advanced version of this script here .

+1
source share

There is no environment variable in teamcity.build.changedFiles.file as you can see in this document: Predefined build options .

In this case, you can use% system.teamcity.build.changedFiles.file%. TeamCity will give your PowerShell script the full path to the file with information about the modified files included in the assembly.

The file contains files separated by a new line: each line corresponds to one file and has the following format:

 <relative file path>:<change type>:<revision> 
+2
source share

All Articles