Skip to content

MSBuild doesn't respect MvcBuildViews-setting in .csproj -file when run through CodeQL-cli or through codeql github action #11890

@pekkasin

Description

@pekkasin

Issue Description

MSBuild doesn't seem to respect the MvcBuildViews-setting defined in a .NET-project's .csproj-file when it is run as a github action or through codeql cli. After trial and error, MSBuild seems to behave as if MvcBuildViews is hardcoded to be true. Mvc view precompilation works just as expected when MSBuild is run locally on its own.

In short, I can't disable mvc view precompilation by setting <MvcBuildViews>false</MvcBuildViews> in project configuration.

Possibly noteworthy: I've used two different versions of CodeQL (2.12.0 latest and 2.6.0) and this only happens with 2.12.0.

Steps to Reproduce

  1. Create a new ASP.NET Web Application called "TestProject" with MVC project template in Visual Studio 2022.
  2. Observe that MVC view precompilation is set to false by default in the project's .csproj -file like so:
    <MvcBuildViews>false</MvcBuildViews>
  3. Observe that further down the same .csproj-file a build target MvcBuildViews is defined like so:
    <Target Name="MvcBuildViews" AfterTargets="AfterBuild" Condition="'$(MvcBuildViews)'=='true'"> <AspNetCompiler VirtualPath="temp" PhysicalPath="$(WebProjectOutputDir)" /> </Target>
  4. Introduce a syntax error to any of the .cshtml-files in the project to trigger compiler warnings when using msbuild with Mvc view precompilation (right now that should be set to false according to the configuration above). For example, add a semicolon to ViewBag.Title in Views/Home/Index.cshtml like this:
@{
    ViewBag.Title = "Home Page" + ;  <!-- The semicolon triggers a syntax error in Visual Studio -->
}
  1. nuget restore the dependencies if Visual Studio didn't do it for you.
  2. Try to build the solution locally with msbuild.exe TestProject.sln. The compilation should complete without errors.
  3. Define a GitHub Action for the solution (latest version of setup-msbuild or something older, doesn't matter) and try the same compilation process via setup-msbuild GitHub Action. Example CodeQL configuration including steps for MSBuild:
name: "CodeQL"

on:
  push:
    branches: [ "main" ]
  pull_request:
    branches: [ "main" ]
  schedule:
    - cron: '25 19 * * 0'

jobs:
  analyze:
    name: Analyze
    runs-on: windows-latest
    permissions:
      actions: read
      contents: read
      security-events: write

    strategy:
      fail-fast: false
      matrix:
        language: [ 'csharp' ]

    steps:
    - name: Checkout repository
      uses: actions/checkout@v3

    - name: Initialize CodeQL
      uses: github/codeql-action/init@v2
      with:
        languages: ${{ matrix.language }}
        queries: security-extended   

    - name: Add msbuild to PATH
      uses: microsoft/setup-msbuild@v1
    
    - name: Install Nuget to restore packages
      uses: nuget/setup-nuget@v1
    
    - name: Restore Nuget packages
      run: nuget restore TestProject.sln   
      
    - name: Build app for release
      run: msbuild.exe TestProject.sln 

    - name: Perform CodeQL Analysis
      uses: github/codeql-action/analyze@v2

or alternatively try to build a codeql database locally with codeql cli.

  1. The compilation step fails because of the syntax error in the .cshtml -file, which implies that precompilation is happening despite a setting to the contrary in the .csproj-file.

Expected Behavior

When run through GitHub Actions or codeql cli, MSBuild shouldn't return errors related to syntax errors in .cshtml -files when I've disabled Mvc view precompilation by setting <MvcBuildViews>false</MvcBuildViews>.

Actual Behavior

MSBuild (through GitHub Actions or codeql cli) fails with an error regarding the arbitrary syntax error introduced in step 4, which implies that Mvc View precompilation is happening despite it being disabled. This is different than what happens when I run MSBuild locally (MSBuild completes without errors).

This discrepancy between the results locally and in GitHub Actions (or codeql cli) is confusing since they both use the same version of MSBuild. The build target defined above has the condition set that MvcBuildViews should be true for the precompilation to happen.

I tried out all the different "permutations" of the two settings (MvcBuildViews-element and the build target condition) both locally (msbuild on its own) and in GitHub Actions and I got the following results (if the setting and condition match, the precompilation should happen, if I've understood correctly):

           | <MvcBuildViews> | Build target condition | Did precompilation happen?
------------------------------------------------------------------------------------
Local      |    False        |         False          |          Yes 
GH Actions |                 |                        |          No
-------------------------------------------------------------------------------------
Local      |    True         |         False          |          No
GH Actions |                 |                        |          No 
------------------------------------------------------------------------------------
# This is the default setting that the project template comes with
Local      |    False        |         True           |          No
GH Actions |                 |                        |          Yes
-----------------------------------------------------------------------------------
Local      |    True         |         True           |          Yes
GH Actions |                 |                        |          Yes
-----------------------------------------------------------------------------------

So the local run of MSBuild worked just as expected with the precompilation only happening when the MvcBuildView-setting matched the build target condition. On GH Actions the results varied quite a bit. It basically looks like MSBuild on GH Actions behaves as if the <MvcBuildViews>-setting is hard coded to be true (ignoring whatever is actually set in the .csproj-file). I also tried to set the MvcBuildViews-parameter by calling GH Action MsBuild with /p:MvcBuildViews=false but that did nothing (locally that also worked just as expected.

Since this same behavior occurs when using codeql cli (and has only started happening somewhere between versions 2.6.0 and 2.12.0), I'm assuming that this is a problem with codeql itself and not with msbuild.

Metadata

Metadata

Assignees

No one assigned

    Labels

    C#questionFurther information is requested

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions