Blazor Server scoped CSS missing after dotnet publish
See original GitHub issueIs there an existing issue for this?
- I have searched the existing issues
Describe the bug
Iβm not sure this is the correct repository to post this issue in, but I have not been able to find any other place that seems more fit.
Our issue is: When we run dotnet publish
for our Blazor Server App in Azure Pipelines, we are missing some key styles in the output publish
folder. If we use just a default Blazor Server project template from .NET 6, the missing files in the publish\wwwroot
folder include the following:
{AssemblyName}.styles.css
css\site.css
css\bootstrap\bootstrap.min.css
css\open-iconic\font\css\open-iconic-bootstrap.min.css
If we run dotnet publish
with the same parameters on our local machines and in GitHub Actions, it is working as expected and we get the correct stylesheet files in the publish
folder.
It seems that in Azure Pipelines, the DefineStaticWebAssets
task is skipped:
1:7>Target "_ComputeScopedCssStaticWebAssets" in file "/opt/hostedtoolcache/dotnet/sdk/6.0.201/Sdks/Microsoft.NET.Sdk.Razor/targets/Microsoft.NET.Sdk.Razor.ScopedCss.targets" from project "/home/vsts/work/1/s/src/BlazorTestApp.csproj" (target "_CollectAllScopedCssAssets" depends on it):
Task "DefineStaticWebAssets" skipped, due to false condition; (@(_ScopedCss) != '') was evaluated as ( != '').
1:7>Done building target "_ComputeScopedCssStaticWebAssets" in project "BlazorTestApp.csproj".
In GitHub, the same task has the following output:
1:7>Target "_ComputeScopedCssStaticWebAssets" in file "/home/runner/.dotnet/sdk/6.0.201/Sdks/Microsoft.NET.Sdk.Razor/targets/Microsoft.NET.Sdk.Razor.ScopedCss.targets" from project "/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/BlazorTestApp.csproj" (target "_CollectAllScopedCssAssets" depends on it):
Task "DefineStaticWebAssets"
RelativePath 'Shared/MainLayout.razor.rz.scp.css' normalized to 'Shared/MainLayout.razor.rz.scp.css' found for candidate '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/MainLayout.razor.rz.scp.css' and will be used for matching.
Identity for candidate '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/MainLayout.razor.rz.scp.css' is '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/MainLayout.razor.rz.scp.css' because it starts with content root '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/'.
RelativePath 'Shared/NavMenu.razor.rz.scp.css' normalized to 'Shared/NavMenu.razor.rz.scp.css' found for candidate '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/NavMenu.razor.rz.scp.css' and will be used for matching.
Identity for candidate '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/NavMenu.razor.rz.scp.css' is '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/Shared/NavMenu.razor.rz.scp.css' because it starts with content root '/home/runner/work/BlazorServerScopedCSSIssue/BlazorServerScopedCSSIssue/src/obj/Release/net6.0/scopedcss/'.
Done executing task "DefineStaticWebAssets".
1:7>Done building target "_ComputeScopedCssStaticWebAssets" in project "BlazorTestApp.csproj".
Expected Behavior
I expect to have the following files in the publish\wwwroot
folder after running dotnet publish
:
{AssemblyName}.styles.css
css\site.css
css\bootstrap\bootstrap.min.css
css\open-iconic\font\css\open-iconic-bootstrap.min.css
Steps To Reproduce
- Create a default Blazor Server app using .NET 6.
- Create a minimalistic Azure Pipelines build pipeline (e.g. similar to the one found in the sample repo - https://github.com/dynsim/BlazorServerScopedCSSIssue/blob/main/azure-pipelines.yml)
- Run the application that was published and see that the styles are missing.
Exceptions (if any)
Publishing locally and in GitHub Actions.
.NET Version
6.0.201
Anything else?
Additional info
A sample repository can be found here: https://github.com/dynsim/BlazorServerScopedCSSIssue
What we have tried:
- Adding a build step prior to the publish step, as suggested here: https://stackoverflow.com/a/68036804/16397671.
- Calling
builder.WebHost.UseStaticWebAssets()
in ourProgram.cs
file, as static web apps only are enabled by default inDevelopment
mode, as pointed out here: https://github.com/dotnet/aspnetcore/issues/28174#issuecomment-734239932. - Setting the
ASPNETCORE_ENVIRONMENT
toDevelopment
, as static web apps only are enabled by default inDevelopment
mode, as pointed out here: https://github.com/dotnet/aspnetcore/issues/28174#issuecomment-734239932.
File outputs
Azure Pipelines
|-- publish
| βββ appsettings.Development.json
| βββ appsettings.json
| βββ BlazorTestApp
| βββ BlazorTestApp.deps.json
| βββ BlazorTestApp.dll
| βββ BlazorTestApp.pdb
| βββ BlazorTestApp.runtimeconfig.json
| βββ web.config
| βββ wwwroot\favicon.ico
| βββ wwwroot\css\bootstrap\bootstrap.min.css.map
| βββ wwwroot\css\open-iconic\FONT-LICENSE
| βββ wwwroot\css\open-iconic\ICON-LICENSE
| βββ wwwroot\css\open-iconic\README.md
| βββ wwwroot\css\open-iconic\font\fonts\open-iconic.eot
| βββ wwwroot\css\open-iconic\font\fonts\open-iconic.otf
| βββ wwwroot\css\open-iconic\font\fonts\open-iconic.svg
| βββ wwwroot\css\open-iconic\font\fonts\open-iconic.ttf
| βββ wwwroot\css\open-iconic\font\fonts\open-iconic.woff
GitHub Actions
|-- publish
| βββ appsettings.Development.json
| βββ appsettings.json
| βββ BlazorTestApp
| βββ BlazorTestApp.deps.json
| βββ BlazorTestApp.dll
| βββ BlazorTestApp.pdb
| βββ BlazorTestApp.runtimeconfig.json
| βββ web.config
| βββ wwwroot\BlazorTestApp.styles.css
| βββ wwwroot\favicon.ico
| βββ wwwroot\css\site.css
| βββ wwwroot\css\bootstrap\bootstrap.min.css
| βββ wwwroot\css\bootstrap\bootstrap.min.css.map
| βββ wwwroot\css\open-iconic\FONT-LICENSE
| βββ wwwroot\css\open-iconic\ICON-LICENSE
| βββ wwwroot\css\open-iconic\README.md
| βββ wwwroot\css\open-iconic\font\css\open-iconic-bootstrap.min.css
| βββ wwwroot\css\open-iconic\font\fonts\open-iconic.eot
| βββ wwwroot\css\open-iconic\font\fonts\open-iconic.otf
| βββ wwwroot\css\open-iconic\font\fonts\open-iconic.svg
| βββ wwwroot\css\open-iconic\font\fonts\open-iconic.ttf
| βββ wwwroot\css\open-iconic\font\fonts\open-iconic.woff
.NET info
Azure Pipelines
.NET SDK (reflecting any global.json):
Version: 6.0.201
Commit: ef40e6aa06
Runtime Environment:
OS Name: ubuntu
OS Version: 20.04
OS Platform: Linux
RID: ubuntu.20.04-x64
Base Path: /opt/hostedtoolcache/dotnet/sdk/6.0.201/
Host (useful for support):
Version: 6.0.3
Commit: c24d9a9c91
.NET SDKs installed:
6.0.201 [/opt/hostedtoolcache/dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.3 [/opt/hostedtoolcache/dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.3 [/opt/hostedtoolcache/dotnet/shared/Microsoft.NETCore.App]
GitHub Actions
.NET SDK (reflecting any global.json):
Version: 6.0.201
Commit: ef40e6aa06
Runtime Environment:
OS Name: ubuntu
OS Version: 20.04
OS Platform: Linux
RID: ubuntu.20.04-x64
Base Path: /home/runner/.dotnet/sdk/6.0.201/
Host (useful for support):
Version: 6.0.3
Commit: c24d9a9c91
.NET SDKs installed:
6.0.201 [/home/runner/.dotnet/sdk]
.NET runtimes installed:
Microsoft.AspNetCore.App 6.0.3 [/home/runner/.dotnet/shared/Microsoft.AspNetCore.App]
Microsoft.NETCore.App 6.0.3 [/home/runner/.dotnet/shared/Microsoft.NETCore.App]
Issue Analytics
- State:
- Created a year ago
- Comments:9 (7 by maintainers)
Top GitHub Comments
@dynsim thanks for the additional details.
This seems like an issue in how the CSS files are built. It normally means that the files got generated too late. We created a package in November and did a blog post around the time to help make this scenario easier. You can check the details here
In general, I would recommend against generating build artifacts in a location that makes them susceptible to be included in source control or as part of the build inputs. This is a bit different in .NET Core vs other build systems because the inputs are in many cases implicitly added (you donβt need to list them all and there are βdefault patternsβ that discover them) so whenever possible, it is best to place the outputs in a separate folder, (like the obj folder).
In general, if you want your files/assets to be considered, they should be generated before
AssignTargetPaths
. The blog post I linked above goes into a lot of detail on how this works build wise.We are also looking to productionize this scenario (that is, making easier to integrate third-party client asset toolchains) in 7.0 and are gathering feedback/interest about it, so please take a moment to upvote this issue if this is something you care about.
I think the behavior here is expected and that additional steps are needed to correctly integrate within the build process, if the guidance provided above doesnβt help, please update the repro and let us know, and we can take another look to see if thereβs something amiss.
This issue has been resolved and has not had any activity for 1 day. It will be closed for housekeeping purposes.
See our Issue Management Policies for more information.