-
Notifications
You must be signed in to change notification settings - Fork 441
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
[ExtensionsMetadataGenerator] Improve configuration for cleaning build output #5894
Comments
@fabiocav -- I'll sync with you on what we can do here. |
I'll share my workaround from #1525 for people who run into this issue: It seems that the
The only downside is larger deployments... |
Moving this as a stretch item for sprint 76. We'll need to at least define the work to be done. |
Hi, I am helping maintain RazorLight and am also the co-maintainer of FluentMigrator. To date, I have had zero interest in Azure Functions, but users keep clamoring for it (congratulations on the popularity!). My understanding is its the only practical option for serverless computing with .NET, and, as such, meets a need for .NET customers, but we're still working through what those exact needs are as it relates to modular, pluggable, hot-swappable computing. That said, here is my broad take on things based on bugs that have been submitted to me:
I don't know if a sprint really solves these problems I observe. I personally will continue to not use Azure Functions. However, it would be nice if we could work together and have a script I can request my customers submit to me/you to troubleshoot these problems. I feel so bad for my users that they're on Azure Functions and I can't help them because of the black box nature. Separately, I'm not into the weeds on what this I hope this is taken as come constructive criticism. I've debated for months whether to push any feedback to Azure Functions, but I've probably now received over 100 requests for help with Azure Functions and am tired of it. I need better ways to support open source software customers. |
@jzabroski There's a whole other question about whether the host should be providing any assemblies at all, and whether it would be cleaner to have an out-of-proc implementation, but then you run into problems supporting the strongly-typed C# binding, which is really nice to have. BTW, thanks for RazorLight! I use it in one of my (non-Azure Functions) projects. |
@StephenCleary I see. Here is my confusion, then: How can you This is not a small point. Improving configuration for cleaning build output (title of this issue) DOES NOT solve the problem. It only provides a bandaid, one that gets ripped off every time Azure Functions does a minor .NET version upgrade and sucks in unwanted dependencies. I ran into similar problems when trying to figure out the following problem: How should FluentMigrator support .NET Core 3.x? Originally, I tried implementing the pragmatic wisdom of Nick Guerrera (the designer of the targeting pack system) and his advice didn't work so well and I landed on fluentmigrator/fluentmigrator#1178 instead, which is to regression test every LTS release of .NET via xunit, and support every LTS release of .NET via .NET CLI Tool and other nuget packages. The crux of the problem is that everything depends on what's in your .deps.json file, so you really can't get away with opting in to .NET Core's default setting of Another way to think of this problem is the one I pushed to Nick Guerrera and Dan Plaisted: Prove to me your design works, by implementing a DotNet CLI tool called TaskRunner that recursively runs open-ended Tasks given a TaskKey. If you can do that, you have an open, pluggable system. But we already know you can't do that with Azure Functions because you can't control the exact version of the runtime. Ceteris paribus, it won't work. It can't. We all know how to break this system and under what rules it can never work, yet, amazingly, Microsoft customers want it to work and expect it to work, and come to open source software library writers and ask us why our code won't work for something that is illogical. P.S. Most of the credit for RazorLight goes to Ivan Balan, a brilliant engineer. I just couldn't stand to see the project die, given the alternatives all lacked IntelliSense and type safety from Visual Studio. |
Just for clarification, I don't work for MS. I'm just an AF user (and a bit of a fanboy). Watching this issue since I've been affected by it.
As an function app writer, I stay up-to-date, with a GitHub Action that updates all my dependencies nightly. This seems to be working well enough, and will do so until breaking changes occur (like this issue, which was added a few Functions.Sdk patch-versions ago). I minimize my library usage to minimize the number of breaking changes. I would expect most Functions apps are very simple and only depend on a handful of libraries. As a library author, I'm not sure what the best approach would be. Currently my libraries all just take dependencies of "whatever version was current at the time I wrote them", which is less than ideal. I've been thinking of auto-updating all of them, too with autogenerated semver updates, but that can cause a lot of downstream churn. I have no idea what the best answer is there. |
While I can accept the idea that the larger your dependency graph, the more likely you'll have dependency-related issues, it seems more fruitful to try to compile the list of problems and why they occur, one-by-one. I once challenged a Microsoft engineer, who claimed to have hit many of these problems himself, to list just some of them, and he politely refused. Here, I am listing one of the problems: You cannot use .NET Core's dependency loading subsystem, which takes a .deps.json file and runtime.settings.json file, and expect it to work with the default RollForward Minor version functionality. It's supposed to work in a semver 2.0.0 model, but for practical reasons, it's very hard to align all ".NET In-Box" APIs in such a way that 3.0 to 3.1 doesn't contain any breaking changes. There are additional problems using ".NET Out-of-box" APIs in such ways, too, but they're hard for different reasons. So, back to my original point. Configuring Build Output solves nothing. (Yes, I got it wrong in my original reply by assuming that Azure Functions had some kind of "runtime compilation" feature similar to ASP.NET Classic's incremental compilation of web pages. I just am not an active user of Azure Functions, and I thought, based on a user description of one of the symptoms happening without any deployment changes by them, that the code was compiled. In reality, it sounds like Azure Functions can upgrade the "latest runtime" whenever it wants (I believe it calls this feature "Trigger Syncing") but the underlying code remains the same statically built libraries. This actually seems much worse, to be honest, because you basically don't let MSBuild do its job which is to build a .deps.json file for you and a runtime.settings.json to create the correct virtual environment.) |
@StephenCleary I am a big fan of using Paket. It's especially useful for multi-project solutions, but because it also keeps track of all dependencies, it much better in ensuring buillds are always using the same package versions and that all projects in your solution use the same version. PS: Loved your book 👍 |
…ns to 3.0.3 Prevents error when subscribing to Publications 'Could not load file or assembly 'Microsoft.IdentityModel.Tokens, Version=6.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified' See Azure/azure-functions-host#5894 Also adding logging for caught exceptions.
The current implementation enables full cleanup or no cleanup using _FunctionsSkipCleanOutput. I think it would be viable to use the ../obj/project.assets.json file to exclude any DLLs that are listed under the dependencies key from being removed. What do you think? |
For me the problem was that Microsoft forgot (sic!) to publish updated runtime dependencies list (see Azure/azure-functions-vs-build-sdk#422) when aspnetcore3.1 was released. As Azure Functions run on aspnet core and our DLL is part of that executable, some dependencies would need to be aligned. However the challenge here is to keep host assemblies and build sdk assembly list aligned, so they do not duplicate. If you need full control of assemblies - go with docker. Using Azure Functions is nice but it has some downsides that we just need to accept for now that what we develop is not our application but we build a dynamic part of Azure Functions App. My temporary solution to the problem was to add a target that runs after the cleanup and restores the dlls I need:
|
…ns to 3.0.3 Prevents error when subscribing to Publications 'Could not load file or assembly 'Microsoft.IdentityModel.Tokens, Version=6.5.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35'. The system cannot find the file specified' See Azure/azure-functions-host#5894 Also adding logging for caught exceptions.
Correct. The same more or less goes for Azure App Service. |
Just upgraded to 5.0 and it appears the RemoveRuntimeDependencies task was the culprit for System.Private.CoreLib: Could not load file or assembly 'Microsoft.Extensions.Logging.Abstractions, Version=5.0.0.0 in our functions app.
Disabling the task fixed it. |
@brettsam @fabiocav Could you please take a look? Also saw this error in this tweet. |
I have this error "Could not load file or assembly 'Microsoft.Extensions.Logging.Abstractions, Version=5.0.0.0" if I update Microsoft.Extensions.Configuration.UserSecrets from 3.1.6 to 5.0.0 - My probably dumb questions, where do I make the change for this Skip Clean Output? |
@dsghi, drop this in to your csproj file and it should prevent the assemblies being cleaned.
the <_FunctionsSkipCleanOutput> line can be placed in an existing property group though too. |
Thank you for the quick response @AndyMDoyle, interestingly that did not solve the problem for me. We're just going to roll back the package updates and wait until things get sorted out. We don't absolutely need to be on the latest versions at the moment. |
Today we have an "all or nothing" approach to cleaning your build output and disabling this involves a (currently) undocumented MSBuild setting:
_FunctionsSkipCleanOutput
. We're seeing a handful of customers run into this -- they move forward to a newer version of an assembly that we're cleaning away.This often fails with
Could not load file or assembly...
exceptions during runtime.I think we need to:
Some related issues that have come up (I'm resolving all of those to this one):
The text was updated successfully, but these errors were encountered: