Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DOTNET 6 Error - Cannot find compilation library location for package 'System.Security.Cryptography.Pkcs' #460

Closed
jacodv opened this issue Nov 15, 2021 · 95 comments

Comments

@jacodv
Copy link

jacodv commented Nov 15, 2021

Describe the bug
Existing tests fail after upgrade.

To Reproduce
Upgrade Test Project from Dotnet 5 to Dotnet 6:

Expected behavior
The template should transform

Information (please complete the following information):

Additional context
TEST

    public void Convert_GivenValidInput_ShouldConvert()
    {
      // arrange
      Setup();
      var data = new { Name = "TheName" };
      var template = "Name is @Model.Name";

      // action
      var result = _engine.Convert(data, template, true);

      // assert
      result .Should().Be("Name is TheName");
  }

IMPLEMETATION:

        var result = engine.CompileRenderStringAsync(GetTemplateCachedId(templateData), templateData, data,  (ExpandoObject)null).Result;

ERROR:


IIAB.Core.Common.Exceptions.RazorParsingException : One or more errors occurred. (Cannot find compilation library location for package 'System.Security.Cryptography.Pkcs')
   at IIAB.Razor.RazorTemplateEngine.Convert(Object data, String templateData, Boolean ifErrorTrySerializeAndDeserialize) in C:\Git\IIAB-netcore\src\IIAB.Razor\RazorTemplateEngine.cs:line 102
   at IIAB.Razor.Tests.RazorTemplateEngineTests.Convert_GivenValidInput_ShouldConvert() in C:\Git\IIAB-netcore\src\IIAB.Razor.Tests\RazorTemplateEngineTests.cs:line 32

@jzabroski
Copy link
Collaborator

@jacodv I don't think RazorLight.Tests has any test with Convert_GivenValidInput_ShouldConvert. Can you reproduce this in the current repositories tests?

@jacodv
Copy link
Author

jacodv commented Nov 16, 2021

I have cloned the repo, but Visual Studio 2022 keep on hanging trying to load the projects. I will create a clean solution and try load them again. If I succeed then I will push to GitHub and revert ASAP.

@jacodv
Copy link
Author

jacodv commented Nov 16, 2021

@jzabroski I have created a repo (https://github.com/jacodv/RazorLightDotNet6)

I get different errors, but they can be fixed by updating the RazorLight.csproj. Here are my tests in order (branches):

  • branch_jdevil-Dotnet5-Success (Started with a .Net5 Test Project)
  • branch_jdevil-Dotnet6-UpdateProjectOnly (Only change the test project to .Net6) - See README in root for error
  • branch_jdevil-Dotnet6-ChangeLanguageVersion-To-9-Sucess (Leave Test Project on .Net6, Change LanguageVersion to 9)
  • branch_jdevil-Donet6-Add-6-To-RazorLight-Project-success (Update RazorLight project with .Net 6 conditions)

@jacodv
Copy link
Author

jacodv commented Nov 16, 2021

@jzabroski : My Error has todo with a dependency (System.Security.Cryptography.Pkcs) of referenced Nuget packages. It would seem that different Nuget packages depend of different versions of this dependency. I realized it by looking at the project.assets.json file in the obj folder.

I still get the error after making the above changes and referencing the new RazorLight project. If I remove the project that has all the nuget packages it works.

Three questions:

  • Is there a way to for the load of a specific version when the RazorEngine compiles?
  • Why does this only occur when the test project (Entry Assembly) is .Net6?
  • Is there a way to debug and determine which Nuget package causes the error? Bear in mind that the razor template and data does not reference any of the nuget packages, it must happen in the load of the reference assembly.

@adimoldovan92
Copy link

I am having the same problem after upgrading from .NET Core 3.1 to .NET 6. I haven't managed yet to find a fix for this,

@jacodv
Copy link
Author

jacodv commented Nov 16, 2021

@jzabroski I managed to replicate the problem. All I had todo was to add a package reference to System.Security.Cryptography.Pkcs in the test project.

See the README in the root

https://github.com/jacodv/RazorLightDotNet6/tree/branch_jdevil-Add-IIAB-To-See-Why-Error-Occurs

Thank you in advance

@jzabroski
Copy link
Collaborator

@jacodv ...Why are you adding a reference to that project?

That said:

It would seem that different Nuget packages depend of different versions of this dependency. I realized it by looking at the project.assets.json file in the obj folder.

The only solution to fix this conflict is to write an assembly resolve helper. This isn't really a RazorLight problem, this is a your-dependencies-are-in-hell-you-need-to-sort-it-out problem.

@jzabroski
Copy link
Collaborator

I get different errors, but they can be fixed by updating the RazorLight.csproj. Here are my tests in order (branches):

  • branch_jdevil-Dotnet5-Success (Started with a .Net5 Test Project)
  • branch_jdevil-Dotnet6-UpdateProjectOnly (Only change the test project to .Net6) - See README in root for error
  • branch_jdevil-Dotnet6-ChangeLanguageVersion-To-9-Sucess (Leave Test Project on .Net6, Change LanguageVersion to 9)
  • branch_jdevil-Donet6-Add-6-To-RazorLight-Project-success (Update RazorLight project with .Net 6 conditions)

Thanks, I'll try to take a look at this soon to understand the problem.

@jacodv
Copy link
Author

jacodv commented Nov 17, 2021

@jacodv ...Why are you adding a reference to that project?

@jzabroski I added the reference to show that it is not DLL hell as suggested. If I only add that project and add RazorLight then I get the error. Let us assume I had this code in my project

Commit to: https://github.com/jacodv/RazorLightDotNet6/tree/branch_jdevil-Add-IIAB-To-See-Why-Error-Occurs

[Test]
		public void Convert_GivenValidInput_ShouldConvert()
		{
			// arrange
			Setup();
			var data = new { Name = "TheName" };
			var template = "Name is @Model.Name";

			// action
			var result = _engine.Convert(data, template, true);

			var signedResult = _sign(Encoding.UTF8.GetBytes(result), X509Certificate2.CreateFromPemFile("personal.pem"));

			// assert
			result.Should().Be("Name is TheName");
		}
		
private static byte[] _sign(byte[] message, X509Certificate2 cert)
		{
			var contentInfo = new ContentInfo(message);
			var signedCms = new SignedCms(contentInfo);
			var cmsSigner = new CmsSigner(cert)
			{
				IncludeOption = X509IncludeOption.EndCertOnly
			};

			signedCms.ComputeSignature(cmsSigner);

			var signed = signedCms.Encode();
			return signed;
		}

@jacodv
Copy link
Author

jacodv commented Nov 22, 2021

@jzabroski / @toddams, did you manage to see what might cause this issue? On my last commit I showed that my initial guess that a 3rd party is causing the problem was incorrect.

@jzabroski
Copy link
Collaborator

jzabroski commented Nov 22, 2021

Sorry man. I have not given this repo a lot of love the last ~2 years (basically, since covid hit). I acknowledge your repro and think it is great you went that far. I'm hesitant to sink a lot of time into issues related to loading third party DLLs, since ultimately RazorLight is doing very simple things.

I would guess there is an issue with the Metadata Resolver, for which there is already an FAQ entry.

Typically when I debug these problems I try to see if:

  1. There is a conflict across versions due to "diamong dependencies" across nuget packages, and there is no way to "roll forward".
  2. The problem is due to third party packaging issues. Sometimes, OOB (Microsoft term for packages that ship on nuget.org instead of with a target framework SDK that sits on disk) packages don't have a clear package under certain conditions, like netstandard packages vs a specific, concrete target framework (e.g., net5.0).
  3. I check to see how things are being packaged on our side. As I've explained to people before, if you want to use this project on newer frameworks, self-contained deployment is the way to go, but you do open yourself up to security risks due to the underlying dependencies being unpatched nuget.org patches (which is likely part of the reason why Microsoft moved to making the framework something that sits on disk vs. can be included off nuget.org).

The third reason is rather subtle, and something people criticize me for how I chose to package the project. They would rather I not do it the way I chose to do it, so that things "just work". I think that's the incorrect perspective as you should know/understand your dependencies.

@jzabroski
Copy link
Collaborator

I think, the fix might be to change the way we packaged netstandard2.0, as it is probably ambiguous which version of Microsoft.AspNetCore.* assemblies we should use when we request a frameworkreference for net6.0 in a context where the interstitial project between the entrypoint assembly and the RazorLight assembly is a netstandard2.0 assembly/csproj.

e.g.

Program.csproj [net6.0]
 \
  References EmailRenderer.csproj
|
EmailRenderer.csproj [netstandard2.0]
 \
  Package Reference RazorLight
  \
   FrameworkReference 6.0
 \
  Microsoft.AspNetCore.* references 2.1 version

In this case, MSBuild will resolve half of the dependencies to netstandard2.0 direct depenencies,& will resolve framework references to net6.0 dependencies provided by Microsoft on Disk for whichever version of the 6.0 SDK you have.

THIS IS JUST A WORKING THEORY I HAVE NOT FULLY TESTED. Just sharing on my lunch break to try to help unblock you.

@jzabroski
Copy link
Collaborator

https://github.com/jacodv/RazorLightDotNet6/blob/branch_jdevil-Add-IIAB-To-See-Why-Error-Occurs/RazorLight.Jdv/Jdv.Razor/Jdv.Razor.csproj you can see here you are using netstandard2.1

I am honestly not 100% sure what the behavior is, but I think my characterization of the problem is on the right track.

@jacodv
Copy link
Author

jacodv commented Nov 23, 2021

@jzabroski , Firstly I appreciate you and the rest of the team's efforts to maintain a crucial function for us. If I can help, I will do so greatly.

Your assessment seems on track, It has todo with conflicts between 2.0 and 2.1. We need 2.1 for some of the collectable assembly functionality and there lie the issue I believe. Because .Net 5 works without any issues.

I will also play with your suggestions later today when I have a gap in my day

@jzabroski
Copy link
Collaborator

jzabroski commented Nov 23, 2021

The primary reason we support netstandard2.0 TFM is really for .NET Framework 4.8 projects. The Microsoft.AspNetCore.* assemblies do not target net4.8 TFM, so that is why we targeted netstandard2.0.

One possible solution is to create a RazorLight.Net48 project and move the netstandard2.0 dependency there. It would share the same code as RazorLight.csproj through auto-globbing rules, but have a different assembly title and package name.

Another solution is to delete the FrameworkReference entirely and see what breaks and what needs to be fixed.

However, the hidden problem lies when an assembly takes advantage of a newer TFM's Runtime IL instruction or attribute that is not present on a older TFM's underlying runtime. For example, support for Span is a classic example. I think that is a lot harder to keep track of and know in advance to plan for, as nuget.org API does not expose any knowledge on binary breaking changes across runtimes. In this sense, the whole netstandard2.0 thing has always been a lie, and is part of why FrameworkReference needs to exist - to make netstandard2.0 a shiftable set of packages based on which runtime framework you actually want to target in your entrypoint assembly.

@jzabroski
Copy link
Collaborator

jzabroski commented Nov 23, 2021

Here are the packages we use and a quick review of which ones keep up to date on versions:

.NETCoreApp 3.1

Package RazorLight Version Status Available OOB? Notes
Microsoft.AspNetCore.Mvc.Razor.Extensions (>= 3.1.5) 6.0.0 ✔️ -
Microsoft.CodeAnalysis.Razor (>= 3.1.5) 6.0.0 ✔️ -
Microsoft.Extensions.Caching.Abstractions (>= 3.1.5) 6.0.0 ✔️ -
Microsoft.Extensions.Caching.Memory (>= 3.1.5) 6.0.0 ✔️ -
Microsoft.Extensions.DependencyInjection (>= 3.1.5) 6.0.0 ✔️ -
Microsoft.Extensions.DependencyModel (>= 3.1.5) 6.0.0 ✔️ -
Microsoft.Extensions.FileProviders.Physical (>= 3.1.5) 6.0.0 ✔️ -
Microsoft.Extensions.Primitives (>= 3.1.5) 6.0.0 ✔️ -
System.Buffers (>= 4.5.0) 4.5.1 ✔️ ❓ Both System.Buffers and System.Memory have been in-box with the .NET SDK since .NET Core 2.1.

I didn't do the other TFMs, but you get the idea of my approach. I am not sure if System.Buffers 4.5.1 is the right version for .NET 6.0. Can you please research that?

@jzabroski
Copy link
Collaborator

There's also this advisory in the .NET 6 Breaking Changes guide: https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/older-framework-versions-dropped

Starting with .NET 6 Preview 5, the core libraries packages can no longer be installed into projects whose target framework is older than:

  • .NET Framework 4.6.1
  • .NET Core 3.1
  • .NET Standard 2.0

@jzabroski
Copy link
Collaborator

jzabroski commented Nov 23, 2021

In particular, see this:

https://docs.microsoft.com/en-us/dotnet/core/compatibility/core-libraries/6.0/older-framework-versions-dropped#affected-apis

Affected APIs

The following packages no longer ship old frameworks:

  • Microsoft.Extensions.DependencyModel
  • Microsoft.Win32.Registry.AccessControl
  • Microsoft.Win32.SystemEvents
  • System.ComponentModel.Annotations
  • System.ComponentModel.Composition
  • System.ComponentModel.Composition.Registration
  • System.Composition.AttributedModel
  • System.Composition.Convention
  • System.Composition.Hosting
  • System.Composition.Runtime
  • System.Composition.TypedParts
  • System.Data.Odbc
  • System.Diagnostics.DiagnosticSource
  • System.Diagnostics.EventLog
  • System.Diagnostics.PerformanceCounter
  • System.DirectoryServices
  • System.DirectoryServices.AccountManagement
  • System.DirectoryServices.Protocols
  • System.Drawing.Common
  • System.IO.Packaging
  • System.IO.Pipelines
  • System.Management
  • System.Net.Http.WinHttpHandler
  • System.Reflection.Context
  • System.Runtime.Caching
  • System.Runtime.CompilerServices.Unsafe
  • System.Security.Cryptography.Cng
  • System.Security.Cryptography.OpenSsl
  • System.Security.Cryptography.Pkcs
  • System.Security.Cryptography.ProtectedData
  • System.ServiceProcess.ServiceController
  • System.Speech
  • System.Text.Encoding.CodePages
  • System.Text.Encodings.Web
  • System.Threading.AccessControl
  • System.Threading.Channels

The following packages will no longer be updated because their implementation is now part of the .NET 6 platform:

  • Microsoft.Win32.Registry
  • System.ComponentModel.Annotations
  • System.IO.FileSystem.AccessControl
  • System.IO.Pipes.AccessControl
  • System.Security.AccessControl
  • System.Security.Cryptography.Cng
  • System.Security.Cryptography.OpenSsl
  • System.Security.Principal.Windows

I bolded three packages that I think are interesting. One we have a direct dependency on. The other we might have indirect (transitive) dependencies on, but dont seem to.

It also looks like System.Memory and System.Buffers got folded into .NET 6 but I dont see that listed in any breaking changes.

@jzabroski
Copy link
Collaborator

It also looks like System.Memory and System.Buffers got folded into .NET 6 but I dont see that listed in any breaking changes.

Correction (in post above): System.Memory and System.Buffers have been in-box since .NET Core 2.1 as part of Span being introduced.

@jacodv
Copy link
Author

jacodv commented Nov 24, 2021

Good morning, South Africa (GMT+2) , I think we are worlds apart. I have a couple of admin tasks for the morning, then I am on this.

Thanks for the details so far

@jacodv
Copy link
Author

jacodv commented Nov 24, 2021

@jzabroski this branch compiles and my simple test passes with most of RazorLight.Tests. This is not the solution, I wanted to get a better understanding of the problem, and thus made everything DotNet 6.

https://github.com/jacodv/RazorLightDotNet6/tree/branch_jdevil-Get-Dotnet6-Working

It does show that there are major compatibility issues going to DotNet 6, especially around ASP.Net Core and hosting.

I need to get back to my own work. But will take it up again tomorrow.

@jacodv
Copy link
Author

jacodv commented Nov 24, 2021

@jzabroski , I can confirm that if I start using the converted engine in our code I get "locking" issues. I think it is in the _cache.Set extension. I get the same in the RazorLight.Tests project when run on the branch: https://github.com/jacodv/RazorLightDotNet6/tree/branch_jdevil-Get-Dotnet6-Working

This is going to be a tough one

@jzabroski
Copy link
Collaborator

OK, but do you see my point that I suspect major problems may be coming from any of these dependencies:

  • Microsoft.Extensions.DependencyModel
  • System.Security.Cryptography.Pkcs
  • System.Text.Encodings.Web (this one is a guess - I dont see where we use it, though)
  • System.IO.FileSystem.AccessContro l(this one is a guess, I dont see where we use it, though)

The first two are the likely culprits. See: dotnet/runtime#35606 where they refactored how dependencies are tracked from "depproj" projects To be honest, I dont know what a depproj is, but I think its removal is likely related to the above notes about .NET 6 not supporting older libraries and that "harvesting" is no longer due in .NET 6. See for example dotnet/runtime#29155 where they noted that they should automate harvesting for .NET 5 , then for .NET 6 they decided to remove it altogether because they realized it was a bad idea. But in 35606 they messed up part of the "fix" for removing harvesting.

@jacodv
Copy link
Author

jacodv commented Nov 24, 2021

Possible yes, If you try and support all the frameworks.

But even before we get to the dependencies, just converting to .Net 6 is an issue. I tried to eliminate all the noise by just focussing on .Net 6 and even that seems to be a challenge.

await _cache.Set(item.NormalizedKey, taskSource.Task, cacheEntryOptions); Is one of the culprits

@jzabroski
Copy link
Collaborator

I'm a little surprised the built-in MemoryCache is causing locking problems. Can you be more specific?

@jacodv
Copy link
Author

jacodv commented Nov 25, 2021

@jzabroski, I have two relatively full days today and tomorrow but will try and get more detail. I will focus on this test, it shows the lock. I am 99% sure it has todo with an async/await that included a .Wait() or similar. My branch:
https://github.com/jacodv/RazorLightDotNet6/tree/branch_jdevil-Get-Dotnet6-Working shows the behaviour.

[Fact]
public async Task Ensure_Option_Disable_Encoding_Renders_Models_Raw() 

Also, further to your point above, you are correct atleast w.r.t System.Security.Cryptography.Pkcs. If I comment await _cache.Set(item.NormalizedKey, taskSource.Task, cacheEntryOptions); to allow the code to continue and not lock-up, I am back to this error: "Cannot find compilation library location for package 'System.Security.Cryptography.Pkcs'".

This is very frustrating, we have functionality that we want to use in .Net 6 and cannot upgrade until we have a working RAZOR component.

The irony is that all we use in our system is await engine.CompileRenderStringAsync(...). We do no have any cshtml files, we only store small strings in a database that require on-demand rendering.

@jzabroski
Copy link
Collaborator

jzabroski commented Nov 29, 2021

I would recommend the following approach to debugging.

  1. See the FAQ where it covers this topic: https://github.com/toddams/RazorLight#im-getting-cannot-find-compilation-library-when-i-deploy-this-library-on-another-server
  2. If the error works fine on .NET Core App 3.1 but doesn't work on .NET 6, and the only material difference is the SDK, then I would take a BinLog of both builds and view them line by line in MSBuildStructuredLogViewer utility until you see something that pops out at you.

One thing that pops out at me is this footnote: https://docs.microsoft.com/en-us/aspnet/core/razor-pages/sdk?view=aspnetcore-6.0#runtime-compilation-of-razor-views

Runtime compilation of Razor views

  • By default, the Razor SDK doesn't publish reference assemblies that are required to perform runtime compilation. This results in compilation failures when the application model relies on runtime compilation—for example, the app uses embedded views or changes views after the app is published. Set CopyRefAssembliesToPublishDirectory to true to continue publishing reference assemblies. Both code generation and compilation are supported by a single call to the compiler. A single assembly is produced that contains the app types and the generated views.

  • For a web app, ensure your app is targeting the Microsoft.NET.Sdk.Web SDK.

I'm not sure why the RazorLight FAQ recommends setting a different setting to false:

<MvcRazorExcludeRefAssembliesFromPublish>false</MvcRazorExcludeRefAssembliesFromPublish>

These two settings do seem related, and I don't know if one was deprecated, or if we've been relying on MSBuild flags Microsoft would consider "private" to the implementation of the SDK.

One thing to test would be to see if you could try the runtime compilation advice from Microsoft that is publicly available, and see if the error changes or if its the same error. (I have not tried this).

I can see from 2019 there was some advice in this regard, here: dotnet/core#1725 (comment)

@jacodv
Copy link
Author

jacodv commented Dec 1, 2021

Thanks @jzabroski, I will try and make time this week to start with the deeper investigation. I also want to see if I cannot make another project that is even lighter with less moving parts for our needs.

@jacodv
Copy link
Author

jacodv commented Dec 1, 2021

@jzabroski - I think I have the problem. And it might be on my side. I use Resharper. I accidently ran my tests in VS test runner and now I don't see the ERROR. I have some other issues, but not missing System.Security.Cryptography.Pkcs related.

I am not sure if I want it to be Resharper or NOT.

ReSharper
image

VS Tests
image

@jzabroski
Copy link
Collaborator

I hate to be negative, but ReSharper is miles,better than VS Test Runner. It's funny/ironic how bad Microsoft testing is.

Since we have covered so much ground, can you summarize which problems are resolved and which are not?

@jzabroski
Copy link
Collaborator

jzabroski commented Feb 14, 2022

@leighmetzroth I remember my thought process now.

  1. We are targeting the following TFMs: https://github.com/toddams/RazorLight/blob/master/src/RazorLight/RazorLight.csproj#L3
    a. netstandard2.0;netcoreapp3.1;net5.0;net6.0
  2. Of those TFMs, netstandard2.0 isn't a real target, but a pseudo-target. Because it's a pseudo-target, it can refer to netcoreapp3.1, net5.0, net6.0 or net48.
    a. netstandard2.1 started with .netcoreapp3.0. Therefore, in some sense, while netstandard2.0 can refer to .netcoreapp3.0 and greater, the PackageReference elements target AspNetCore 2.1 packages, which are out-of-date and not security patched. Fundamentally, net48 consumers can't realistically use netstandard2.1 frameworks (read: netcoreapp3.0 or later), because there are new features in the runtime like Span.
    b. Therefore, if you're using netstandard2.0, you are implicitly saying you plan to use it from a net48 project entrypoint - but some people want to use netstandard2.0 to simply mean a common library that can be used in various TFMs across their organization. This is what gets people into trouble and where they end up opening support requests on RazorLight Issues on GitHub (here), because they don't understand why they are getting runtime assembly conflict issues.
    c. Moreover, and this is really subtle, but what netstandard2.0 binds to when you compile depends upon what SDKs you have installed + if you override the SDK version number in your csproj via the rather unknown expression: dotnet new globaljson --sdk-version <yoursdkversion>, or use one of the options listed in How to: Reference an MSBuild Project SDK:
<Project Sdk="My.Custom.Sdk/1.2.3">
   ...
</Project>

or

<Project>
    <Sdk Name="My.Custom.Sdk" Version="1.2.3" />
    ...
</Project>

There. Sorry I didn't get all this out on the weekend. Sometimes I turn my brain down a bit on the weekend.

@leighmetzroth
Copy link

Given this is blocking a ticket I'm working on that includes an upgrade to .net 6, are we able to publish the new pre-release nuget with .net 6 support so I can get some momentum back up on that work? As you may understand, it's a significant piece of work and each change that's made by my teammates or other tickets I'm working on needs to be merged into this branch; which in itself is costing me a lot of time.

Once my blocked ticket is progressing, I will be able to commit some time to making the change you're suggesting.

Also, is there a way that we could potentially talk through this and the requirements before I tackle it? Going by your profile, you're based in Boston when means that we could jump on a Google Meet early my time, which should be early evening your time.

@jacodv
Copy link
Author

jacodv commented Feb 15, 2022

If I can assist, then I am willing to help. I will create a VM with all the required frameworks and help.

I am in South Africa and therefor in the middel, let me know if I can be of assistance.

@jzabroski
Copy link
Collaborator

Given this is blocking a ticket I'm working on that includes an upgrade to .net 6, are we able to publish the new pre-release nuget with .net 6 support so I can get some momentum back up on that work?

of course. https://github.com/toddams/RazorLight/actions/runs/1848527620 heading away from my desk for next 2 hours but i will follow up to see that it made it up to nuget.org I picked rc.5 for now - once you confirm it works fine, i will drop the rc tag

@leighmetzroth
Copy link

Looks like you've been fighting with failures 😔 and the latest failure is because it couldn't find the project.

I've never really dealt with github actions before, but looking at the code here for alirezanet/publish-nuget, I can see that it just references this.projectFile = process.env.INPUT_PROJECT_FILE_PATH whereas the others reference both the environment variable with and without the INPUT_ part. I also spotted this issue where there was a bug where the INPUT_ was being ignored.

Perhaps we need to switch PROJECT_FILE_PATH: src\RazorLight\RazorLight.csproj for INPUT_PROJECT_FILE_PATH: src\RazorLight\RazorLight.csproj temporarily?

@jzabroski
Copy link
Collaborator

It looks like it still failed. What's odd is I thought I fixed this 2 months ago. I do remember commenting on this PR brandedoutcast/publish-nuget#62 but I dont remember how I pushed rc.4 - e.g., I think its possible I uploaded everything successfully but the GItHub action was reporting failure

@jzabroski
Copy link
Collaborator

I think the remaining issue is that the way the code is retrieving the environment var is based on the current process's env variable, which, at the time the step executes, probably is a stale copy of the env variable. I'm not an expert in GitHub actions, so I am going to try that - mostly explaining what I am doing here to leave breadcrumbs in the future.

@jzabroski
Copy link
Collaborator

jzabroski commented Feb 16, 2022

So, there were several issues.

The latest seems to be that pack is failing for some reason... but the GitHub Action isnt checking that commands results for errors (yay!). Ideally these would be smaller actions, but what do I know.

The other issue I observe, that we havent even gotten to yet, is the Action is using --skip-duplicate, so there is no way to know if the workflow silently failed. Awesome.

@leighmetzroth
Copy link

It was looking so good! Looks like it tried to push as rc-4 again

@leighmetzroth
Copy link

Does it need the version updated in the Directory.Build.props?

@jzabroski
Copy link
Collaborator

https://github.com/toddams/RazorLight/actions/runs/1855287487

it succeeded but did it publish rc.5? I can't check right now. Driving

@jzabroski
Copy link
Collaborator

jzabroski commented Feb 16, 2022

OK, I see the problem. I forgot I put the version in the src/Directory.Build.props not the top level build props. Should be fixed. It will be published as rc.6 unfortunately

@jzabroski
Copy link
Collaborator

@leighmetzroth @jacodv We did it! https://www.nuget.org/packages/RazorLight/2.0.0-rc.6

@leighmetzroth
Copy link

It is strange that it's not showing there, but it does show in the Frameworks section below. Maybe there's some process that updates it later???

Anyway, the good news is that the new version works in a test .NET 6 project. The bad news is that it looks like I'm about to be in "DLL Hell" as it was called earlier in this thread as it appears that something is pulling in the old version of System.Security.Cryptography.Pkcs in our solution. I'm fairly sure I know what it is (an internal NuGet that we have that's still referencing .NET 2.2).

image

@jzabroski
Copy link
Collaborator

The Frameworks tab I think is brand new. I am guessing its a UI bug. I actually just sent Jon Douglass a tweet about this: https://twitter.com/johnzabroski/status/1494499821469810697 He is the PM for Nuget.

@jacodv
Copy link
Author

jacodv commented Feb 18, 2022 via email

@jzabroski
Copy link
Collaborator

@jacodv @leighmetzroth Please do follow up on success. If you have success, I will drop the rc.6 tag and make it official. It's possible but not certain I am migrating to .NET 6 next month as well, so your efforts are appreciated.

@leighmetzroth
Copy link

After a heap of digging, I found that we have a transitive dependency on System.Security.Cryptography.Pkcs via MailKit (it has a dependency on MimeKit, which takes the dependency on System.Security.Cryptography.Pkcs).

After upgrading to the latest MailKit, I still had issues and ended up trawling through all of our own internal nugets (of which quite a few were in dire need of upgrading to the latest frameworks too 😬 ). After all of that, it still didn't work; uninstalling MailKit and commenting out the code that sends the emails using it, it did work....

I did some more Google-foo and eventually landed on this, which has an answer for adding <GenerateRuntimeConfigDevFile>true</GenerateRuntimeConfigDevFile> to the csproj files (the same stack of projects that need the PreserveCompilationContext set to true). I tried that, and it worked. So I have a feeling it's got something to do with the refactor they made to these DLLs and with the removal of the runtime config dev file, it has left projects like this unable to discover these dependencies for some reason.

Is it worth adding some instructions to the FAQ for this? If you think it is, just let me know and I'll write up the instructions and PR it in.

@jzabroski
Copy link
Collaborator

jzabroski commented Feb 19, 2022

Yes, but... Please mention the actual issue rather than StackOverflow: dotnet/sdk#16818

Make sure you edit README.Source.md and build. Check in both files with your PR

@jacodv
Copy link
Author

jacodv commented Feb 21, 2022

WOW, I added that element to the project file weeks ago, but it was to to get ReSharper tests to work. Who would have thought....

@jzabroski
Copy link
Collaborator

@jacodv It's funny, isn't it. We were told that getting rid of Assembly Binding Redirects and shadow copy assemblies would make dotnet core infinitely easier than .NET Framework. And here we are, playing with a bunch of new knobs. Feels an awful lot like the old new thing, doesn't it? I do think its slightly improved in some core ways, but everything outside that core shell is now a mess. This has been my biggest takeaway working with .NET Core and later - dynamically loading plugins without a well-defined assembly load context is a bad idea. But the problem is the compiler framework doesn't have any way to hint at what dynamic load targets you might plan, e.g. if you target netstandard2.0.

@leighmetzroth Let me know if you still plan to do the P.R.

@leighmetzroth
Copy link

@jzabroski I am planning on doing it, just a bit busy right now between sick kids at home and having to take time off, and getting this .NET 6 upgrade completed and tested so we can roll it out to our customers.

@jzabroski
Copy link
Collaborator

Sounds good.

@jacodv
Copy link
Author

jacodv commented Mar 16, 2022

@leighmetzroth @jzabroski - We have successfully upgraded to .Net 6. Thanks for all the help.

@jzabroski
Copy link
Collaborator

Yes, thanks. Were there any additional gotchas?

@jacodv
Copy link
Author

jacodv commented Mar 16, 2022

Nope, Added the required project attributes [PreserveCompilationContext, GenerateRuntimeConfigDevFile] and all good.

@mikart143
Copy link

So for people still having the issue the ultimate solution for this is setting PreserveCompilationContext to true and adding ExcludingAssembly like:

            services.AddRazorLight(() =>
            {
                return new RazorLightEngineBuilder()
                    .UseFileSystemProject(Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location))
                    .UseMemoryCachingProvider()
                    .ExcludeAssemblies(typeof(System.Security.Cryptography.Pkcs.AlgorithmIdentifier).Assembly.GetName().Name) // Workaround for loading CompileLibraries
                    .EnableDebugMode(Debugger.IsAttached)
                    .Build();
            });

If you will try to Exclude Assembly with FullName It will not work. Additonally the RazorLightDependancyEngineBuilder is broken and all ExcludedAssemblies are ignored further in DefaultMetadataReferenceManager. @jzabroski

@jzabroski
Copy link
Collaborator

Additonally the RazorLightDependancyEngineBuilder is broken and all ExcludedAssemblies are ignored further in DefaultMetadataReferenceManager. @jzabroski

Can you explain what you mean by opening a new issue?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

5 participants