4

I'm working on a Blazor app that uses scoped CSS, but when I try to build it with Azure Pipelines, the scoped CSS file doesn't get generated. I build on an on-premise machine that I can RDP into, and I see the wwwroot/{assemblyname}.styles.css file completely missing after the dotnet publish

When I run the exact command that Azure Pipelines shows manually on the same exact machine, it's present and works just fine.

The azure-pipelines.yml task:

- task: UseDotNet@2
  inputs:
    packageType: 'sdk'
    version: '5.x'
...
- task: DotNetCoreCLI@2
  condition: succeeded()
  displayName: Publish my.project.blazor
  inputs:
    command: 'publish'
    publishWebProjects: false
    projects: 'src\my.project.blazor\my.project.blazor.csproj'
    arguments: '/p:Version=$(MainVersion).$(Patch) -o $(PublishFolder) -c Release -v d'
    zipAfterPublish: false
    modifyOutputPath: false

Pipeline build start:

Starting: Publish my.project.blazor
==============================================================================
Task         : .NET Core
Description  : Build, test, package, or publish a dotnet application, or run a custom dotnet command
Version      : 2.187.0
Author       : Microsoft Corporation
Help         : https://learn.microsoft.com/azure/devops/pipelines/tasks/build/dotnet-core-cli
==============================================================================
C:\Windows\system32\chcp.com 65001
Active code page: 65001
Info: .NET Core SDK/runtime 2.2 and 3.0 are now End of Life(EOL) and have been removed from all hosted agents. If you're using these SDK/runtimes on hosted agents, kindly upgrade to newer versions which are not EOL, or else use UseDotNet task to install the required version.
C:\agent\_work\_tool\dotnet\dotnet.exe publish C:\agent\_work\31\s\src\my.project.blazor\my.project.blazor.csproj /p:Version=1.0.17 -o C:\agent\_work\31\Publish -c Release -v d
Microsoft (R) Build Engine version 16.10.1+2fd48ab73 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 6/18/2021 1:53:30 PM.
     0>Process = "C:\agent\_work\_tool\dotnet\dotnet.exe"
       MSBuild executable path = "C:\agent\_work\_tool\dotnet\sdk\5.0.301\MSBuild.dll"
       Command line arguments = "C:\agent\_work\_tool\dotnet\sdk\5.0.301\MSBuild.dll -maxcpucount -verbosity:m -restore -target:Publish -property:PublishDir=C:\agent\_work\31\Publish -property:Configuration=Release -verbosity:d C:\agent\_work\31\s\src\my.project.blazor\my.project.blazor.csproj /p:Version=1.0.17 -distributedlogger:Microsoft.DotNet.Tools.MSBuild.MSBuildLogger,C:\agent\_work\_tool\dotnet\sdk\5.0.301\dotnet.dll*Microsoft.DotNet.Tools.MSBuild.MSBuildForwardingLogger,C:\agent\_work\_tool\dotnet\sdk\5.0.301\dotnet.dll"
       Current directory = "C:\agent\_work\31\s"

As noted before, if I execute exactly that command manually on the server, eg.:

C:\agent\_work\_tool\dotnet\dotnet.exe publish C:\agent\_work\31\s\src\my.project.blazor\my.project.blazor.csproj /p:Version=1.0.17 -o C:\agent\_work\31\Publish -c Release -v d

it works fine and the generated, scoped .css file appears.

This is the start of the output of the command when entered manually (note the identical MSBuild version):

Microsoft (R) Build Engine version 16.10.1+2fd48ab73 for .NET
Copyright (C) Microsoft Corporation. All rights reserved.

Build started 6/18/2021 2:06:57 PM.
     0>Process = "C:\agent\_work\_tool\dotnet\dotnet.exe"
       MSBuild executable path = "C:\agent\_work\_tool\dotnet\sdk\5.0.301\MSBuild.dll"
       Command line arguments = "C:\agent\_work\_tool\dotnet\sdk\5.0.301\MSBuild.dll -maxcpucount -verbosity:m -restore -target:Publish -property:PublishDir=C:\agent\_work\31\Publish -property:Configuration=Release -verbosity:d C:\agent\_work\31\s\src\my.project.blazor\my.project.blazor.csproj /p:Version=1.0.17 -distributedlogger:Microsoft.DotNet.Tools.MSBuild.MSBuildLogger,C:\agent\_work\_tool\dotnet\sdk\5.0.301\dotnet.dll*Microsoft.DotNet.Tools.MSBuild.MSBuildForwardingLogger,C:\agent\_work\_tool\dotnet\sdk\5.0.301\dotnet.dll"
       Current directory = "C:\agent\_work\31\s"

I've compared the output of these log files, and found a couple of notable things, mainly:

Pipelines:

1:7>Target "_GenerateScopedCssFiles" in file "C:\agent\_work\_tool\dotnet\sdk\5.0.301\Sdks\Microsoft.NET.Sdk.Razor\build\netstandard2.0\Microsoft.NET.Sdk.Razor.ScopedCss.targets" from project "C:\agent\_work\31\s\src\my.project.blazor\my.project.blazor.csproj" (target "_PrepareForScopedCss" depends on it):
       Skipping target "_GenerateScopedCssFiles" because it has no outputs.
       Though the target has declared its outputs, the output specification only references empty properties and/or empty item lists.
   1:7>Done building target "_GenerateScopedCssFiles" in project "my.project.blazor.csproj".
       Target "_PrepareForBundling" skipped. Previously built successfully.
       Target "ResolveStaticWebAssetsInputs" skipped. Previously built successfully.
       Target "_CollectAllScopedCssAssets" skipped. Previously built successfully.
   1:7>Target "BundleScopedCssFiles" in file "C:\agent\_work\_tool\dotnet\sdk\5.0.301\Sdks\Microsoft.NET.Sdk.Razor\build\netstandard2.0\Microsoft.NET.Sdk.Razor.ScopedCss.targets" from project "C:\agent\_work\31\s\src\my.project.blazor\my.project.blazor.csproj" (target "_PrepareForScopedCss" depends on it):
       Task "ConcatenateCssFiles" skipped, due to false condition; ('@(_ScopedCssProjectBundles)' != '' or '@(_ScopedCss)' != '') was evaluated as ('' != '' or '' != '').
       Task "ConcatenateCssFiles" skipped, due to false condition; ('@(_ScopedCss)' != '') was evaluated as ('' != '').

Manual:

   1:7>Target "_GenerateScopedCssFiles" in file "C:\agent\_work\_tool\dotnet\sdk\5.0.301\Sdks\Microsoft.NET.Sdk.Razor\build\netstandard2.0\Microsoft.NET.Sdk.Razor.ScopedCss.targets" from project "C:\agent\_work\31\s\src\my.project.blazor\my.project.blazor.csproj" (target "_PrepareForScopedCss" depends on it):
       Skipping target "_GenerateScopedCssFiles" because all output files are up-to-date with respect to the input files.
       Input files: 
           Components\Configurator.razor.css
           Components\Option.razor.css
           Components\Options.razor.css
           Components\Popup.razor.css
           Components\Step.razor.css
           Pages\Index.razor.css
       Output files: 
           C:\agent\_work\31\s\src\my.project.blazor\obj\Release\net5.0\scopedcss\Components\Configurator.razor.rz.scp.css
           C:\agent\_work\31\s\src\my.project.blazor\obj\Release\net5.0\scopedcss\Components\Option.razor.rz.scp.css
           C:\agent\_work\31\s\src\my.project.blazor\obj\Release\net5.0\scopedcss\Components\Options.razor.rz.scp.css
           C:\agent\_work\31\s\src\my.project.blazor\obj\Release\net5.0\scopedcss\Components\Popup.razor.rz.scp.css
           C:\agent\_work\31\s\src\my.project.blazor\obj\Release\net5.0\scopedcss\Components\Step.razor.rz.scp.css
           C:\agent\_work\31\s\src\my.project.blazor\obj\Release\net5.0\scopedcss\Pages\Index.razor.rz.scp.css
   1:7>Done building target "_GenerateScopedCssFiles" in project "my.project.blazor.csproj".
       Target "_PrepareForBundling" skipped. Previously built successfully.
       Target "ResolveStaticWebAssetsInputs" skipped. Previously built successfully.
       Target "_CollectAllScopedCssAssets" skipped. Previously built successfully.
   1:7>Target "BundleScopedCssFiles" in file "C:\agent\_work\_tool\dotnet\sdk\5.0.301\Sdks\Microsoft.NET.Sdk.Razor\build\netstandard2.0\Microsoft.NET.Sdk.Razor.ScopedCss.targets" from project "C:\agent\_work\31\s\src\my.project.blazor\my.project.blazor.csproj" (target "_PrepareForScopedCss" depends on it):
       Using "ConcatenateCssFiles" task from assembly "C:\agent\_work\_tool\dotnet\sdk\5.0.301\Sdks\Microsoft.NET.Sdk.Razor\build\netstandard2.0\..\..\tasks\net5.0\Microsoft.NET.Sdk.Razor.Tasks.dll".
       Task "ConcatenateCssFiles"
       Done executing task "ConcatenateCssFiles".
       Task "ConcatenateCssFiles"
       Done executing task "ConcatenateCssFiles".

I don't uderstand why the Azure Pipelines triggered build says Skipping target "_GenerateScopedCssFiles" because it has no outputs., but I think that might be the cause of my issue.

How do I get Pipelines to scope and bundle my .css files?

René Sackers
  • 2,395
  • 4
  • 24
  • 43
  • This is going to sound weird, but I've just checked one of my builds where I remember having a similar issue. Although to be fair I was also using the webcompiler which adds a bit of complexity. The only way I got it to work was to do a .net build command before the publish command. Worth a try – App Pack Jun 18 '21 at 13:14
  • @AppPack that's crazy, it works! I don't understand why, but it does. I just added a build step before the publish, builds to en entirely different output directory, and yet the publish then suddenly works as well. Post your comment as an answer, then I can accept it :) – René Sackers Jun 18 '21 at 13:49

3 Answers3

2

I had a similar issue. Although to be fair I was also using the webcompiler which adds a bit of complexity.

The only way I got it to work was to do a .net build command before the publish command.

Worth a try

Edit: Glad it worked for you too. Like you I have no idea why this worked, after messing about with the build process for far too long for a low value project... once it worked I didnt look into WHY.

App Pack
  • 1,512
  • 10
  • 9
  • 1
    I'll mark this as the answer for now, it solved my issue, but it's stupid and there must be a better solution, so of anyone has a better answer, please post it. – René Sackers Jun 18 '21 at 14:20
1

Not completely the same issue but this might help someone. I had a situation where scoped css wasn't being detected during the pack target. Specifically, when I was packing as part of the build i.e. *.csproj

<Project Sdk="Microsoft.NET.Sdk.Razor">
   <GeneratePackageOnBuild>true</GeneratePackageOnBuild>
   ...

Interestingly, it would work on the second build - (once the css files had already been compiled). For context, I was using BuildWebCompiler to compile less into css during the build.

I spent quite a while looking at Razor.ScopedCss.targets to ensure that the web compiler was running before the scoped css bundling, but it still wasn't working.

The solution I found was to make a build target similar to the following.

<Target Name="WebCompileExample" BeforeTargets="ResolveScopedCssInputs">
    <!-- Create Scoped css files. e.g. compile less files etc. -->

    <ItemGroup>
        <None Remove="**/*.razor.css" />
        <None Include="**/*.razor.css" />
    </ItemGroup>
</Target>

Specifically, the <ItemGroup> section is what fixed it. I don't know why this was only an issue when I added the pack step... but to be honest this is the point where I stopped asking questions.

This is the relevant GitHub issue that got me onto this.

Super Kai - Kazuya Ito
  • 22,221
  • 10
  • 124
  • 129
0

I solved it by adding all wwwroot folder to the source control

Daniel Tshuva
  • 483
  • 4
  • 12