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

Issue when using latest Microsoft.NET.Sdk.Functions (1.0.19) #3345

Open
johlrich opened this Issue Aug 30, 2018 · 20 comments

Comments

Projects
None yet
3 participants
@johlrich
Contributor

johlrich commented Aug 30, 2018

Description

Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator is a new package referenced by Microsoft.NET.Sdk.Functions and looks like it is responsible for generating an extensions.json file needed by the runtime.

When restoring packages with the latest paket and azure functions build, there are warnings MSB4011 at build time. When the build finishes the extensions.json generated is in the wrong location and empty.

Looking in the props/target files you do see a reference to both.

Full warning MSB4011 text:
C:\Users\JonathanOhlrich\.nuget\packages\microsoft.net.sdk.functions\1.0.19\build\netstandard1.0\Microsoft.NET.Sdk.Functions.props(38,3): warning MSB4011: "C:\Users\JonathanOhlrich\.nuget\packages\microsoft.azure.webjobs.script.extensionsmetadatagenerator\1.0.0\build\Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator.props" cannot be imported again. It was already imported at "C:\dev\authorization-service\src\Functions\obj\Functions.fsproj.nuget.g.props (17,5)". This is most likely a build authoring error. This subsequent import will be ignored. [C:\dev\authorization-service\src\Functions\Functions.fsproj]
C:\Users\JonathanOhlrich\.nuget\packages\microsoft.net.sdk.functions\1.0.19\build\netstandard1.0\Microsoft.NET.Sdk.Functions.targets(45,3): warning MSB4011: "C:\Users\JonathanOhlrich\.nuget\packages\microsoft.azure.webjobs.script.extensionsmetadatagenerator\1.0.0\build\Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator.targets" cannot be imported again. It was already imported at "C:\dev\authorization-service\src\Functions\obj\Functions.fsproj.nuget.g.targets (9,5)". This is most likely a build authoring error. This subsequent import will be ignored. [C:\dev\authorization-service\src\Functions\Functions.fsproj]

Repro steps

Paket version 5.176.9

Reference Microsoft.NET.Sdk.Functions 1.0.19 and then build

Expected behavior

Since Microsoft.NET.Sdk.Functions references Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator I suppose only Microsoft.NET.Sdk.Functions's props/targets should be used? I'm not positive how exactly both are being referenced

Actual behavior

Both exist causing warnings and incorrect behavior

Known workarounds

If you restore and manually remove the Imports lines referencing the Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator's target and props in the obj folder, then build --no-restore will succeed without warning and generate the extensions.json in the function app's bin folder

I tried to explicitly exclude the targets via Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator import_targets: false at both the paket.reference and paket.dependencies, but it would still appear.

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member
Member

forki commented Aug 30, 2018

@johlrich

This comment has been minimized.

Show comment
Hide comment
@johlrich

johlrich Aug 30, 2018

Contributor

Here's a repro zip, I left my attempt at working around it with import_targets: false
paket-3345.zip

With the warning you'll get an empty extensions.json file in bin\Debug\netstandard2.0 and with the workaround applied (removing ExtensionsMetadataGenerator imports from obj\paket-3345.fsproj.nuget.g.props and .target then build --no-restore) you'll see the two extensions referenced in the extensions.json file located in bin\Debug\netstandard2.0\bin

I'd be happy to open something upstream and follow up but I'm not sure what I would report to them yet as the same scenario works via nuget + vs. Here is the commit for the Function's sdk that added the reference / Import's, which seems to explain what's happening, but I'm not sure what necessarily should be happening yet: Azure/azure-functions-vs-build-sdk@ade32fd#diff-03102f2d5679fbdea7c914beee32b2b5

filled out extensions.json file example
{
  "extensions":[
    { "name": "DurableTask", "typeName":"Microsoft.Azure.WebJobs.Extensions.DurableTask.DurableTaskWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.DurableTask, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null"},
    { "name": "AzureStorage", "typeName":"Microsoft.Azure.WebJobs.Extensions.Storage.AzureStorageWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null"}
  ]
}
Contributor

johlrich commented Aug 30, 2018

Here's a repro zip, I left my attempt at working around it with import_targets: false
paket-3345.zip

With the warning you'll get an empty extensions.json file in bin\Debug\netstandard2.0 and with the workaround applied (removing ExtensionsMetadataGenerator imports from obj\paket-3345.fsproj.nuget.g.props and .target then build --no-restore) you'll see the two extensions referenced in the extensions.json file located in bin\Debug\netstandard2.0\bin

I'd be happy to open something upstream and follow up but I'm not sure what I would report to them yet as the same scenario works via nuget + vs. Here is the commit for the Function's sdk that added the reference / Import's, which seems to explain what's happening, but I'm not sure what necessarily should be happening yet: Azure/azure-functions-vs-build-sdk@ade32fd#diff-03102f2d5679fbdea7c914beee32b2b5

filled out extensions.json file example
{
  "extensions":[
    { "name": "DurableTask", "typeName":"Microsoft.Azure.WebJobs.Extensions.DurableTask.DurableTaskWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.DurableTask, Version=1.6.0.0, Culture=neutral, PublicKeyToken=null"},
    { "name": "AzureStorage", "typeName":"Microsoft.Azure.WebJobs.Extensions.Storage.AzureStorageWebJobsStartup, Microsoft.Azure.WebJobs.Extensions.Storage, Version=3.0.0.0, Culture=neutral, PublicKeyToken=null"}
  ]
}
@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member

@soninaren @fabiocav I think this is a bug in azure functions sdk

Member

forki commented Aug 30, 2018

@soninaren @fabiocav I think this is a bug in azure functions sdk

forki added a commit to forki/azure-functions-vs-build-sdk that referenced this issue Aug 30, 2018

Update Microsoft.NET.Sdk.Functions.targets
This import should be done via nuget/paket - see fsprojects/Paket#3345
@forki

This comment has been minimized.

Show comment
Hide comment
@forki
Member

forki commented Aug 30, 2018

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member

@johlrich any ideas what that extensions file is about?

Member

forki commented Aug 30, 2018

@johlrich any ideas what that extensions file is about?

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member

@johlrich the really weird thing here is that we actually don't touch the .fsproj.nuget.g.props and .fsproj.nuget.g.targets - these are generated by nuget itself. That's why that proposed workaround doesn't work.

Member

forki commented Aug 30, 2018

@johlrich the really weird thing here is that we actually don't touch the .fsproj.nuget.g.props and .fsproj.nuget.g.targets - these are generated by nuget itself. That's why that proposed workaround doesn't work.

@johlrich

This comment has been minimized.

Show comment
Hide comment
@johlrich

johlrich Aug 30, 2018

Contributor

@forki I haven't poked around enough to see exactly how it's used, but it's def used by the runtime to decide which extensions to load. When I loaded the app with the empty extensions file almost all of my bindings reported errors at func start, which led me to try it via VS and see the difference in output.

If I was a betting man I'm guessing it helps cold starts by pushing the reflection to decide what to load to these build tasks instead of at startup.

Contributor

johlrich commented Aug 30, 2018

@forki I haven't poked around enough to see exactly how it's used, but it's def used by the runtime to decide which extensions to load. When I loaded the app with the empty extensions file almost all of my bindings reported errors at func start, which led me to try it via VS and see the difference in output.

If I was a betting man I'm guessing it helps cold starts by pushing the reflection to decide what to load to these build tasks instead of at startup.

@johlrich

This comment has been minimized.

Show comment
Hide comment
@johlrich

johlrich Aug 30, 2018

Contributor

BTW I don't know how you get your runtimes, but the npm package seems to lag behind, the tooling feed seems to get runtime zips added pretty quickly though. In case you need the latest as you explore the new version, check out the tooling feed repo: Azure/azure-functions-tooling-feed@b86d343

Contributor

johlrich commented Aug 30, 2018

BTW I don't know how you get your runtimes, but the npm package seems to lag behind, the tooling feed seems to get runtime zips added pretty quickly though. In case you need the latest as you explore the new version, check out the tooling feed repo: Azure/azure-functions-tooling-feed@b86d343

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member

@johlrich in your vanilla nuget test - you didn't add the package as direct dependency, right? You only referenced it via nuget's transitive dev mechanism. So I assume you can repro with vanilla nuget if you directly reference that new package in the fsproj. Can you please test that?

Member

forki commented Aug 30, 2018

@johlrich in your vanilla nuget test - you didn't add the package as direct dependency, right? You only referenced it via nuget's transitive dev mechanism. So I assume you can repro with vanilla nuget if you directly reference that new package in the fsproj. Can you please test that?

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member
Member

forki commented Aug 30, 2018

@johlrich

This comment has been minimized.

Show comment
Hide comment
@johlrich

johlrich Aug 30, 2018

Contributor

@forki Your hunch must be right; I was able to confirm via the nuget repro. Everything is fine with only Microsoft.NET.Sdk.Functions directly referenced. When I add the direct reference to Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator and run dotnet restore / build, you start seeing the same issue there too.

Contributor

johlrich commented Aug 30, 2018

@forki Your hunch must be right; I was able to confirm via the nuget repro. Everything is fine with only Microsoft.NET.Sdk.Functions directly referenced. When I add the direct reference to Microsoft.Azure.WebJobs.Script.ExtensionsMetadataGenerator and run dotnet restore / build, you start seeing the same issue there too.

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member

thanks for confirmation. working on temporary fix in paket which mitigates this

Member

forki commented Aug 30, 2018

thanks for confirmation. working on temporary fix in paket which mitigates this

@matthid

This comment has been minimized.

Show comment
Hide comment
@matthid

matthid Aug 30, 2018

Member

b) I know how to do temporary workaround

oO sounds quite dangerous to me

Member

matthid commented Aug 30, 2018

b) I know how to do temporary workaround

oO sounds quite dangerous to me

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member

@matthid well I need it to continue to work - business depends on it ....

Member

forki commented Aug 30, 2018

@matthid well I need it to continue to work - business depends on it ....

forki added a commit that referenced this issue Aug 30, 2018

@matthid

This comment has been minimized.

Show comment
Hide comment
@matthid

matthid Aug 30, 2018

Member

Why is that happening now and is so critical?

Member

matthid commented Aug 30, 2018

Why is that happening now and is so critical?

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member

because they are deploying breaking changes in the runtime and we need to update our code to behave to that. see Azure/app-service-announcements#129

Member

forki commented Aug 30, 2018

because they are deploying breaking changes in the runtime and we need to update our code to behave to that. see Azure/app-service-announcements#129

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member

@johlrich put "version 5.177.1" on top of your deps file, delete all /obj, run paket update and it should work

Member

forki commented Aug 30, 2018

@johlrich put "version 5.177.1" on top of your deps file, delete all /obj, run paket update and it should work

@johlrich

This comment has been minimized.

Show comment
Hide comment
@johlrich

johlrich Aug 30, 2018

Contributor

Confirmed working here, thanks!

Contributor

johlrich commented Aug 30, 2018

Confirmed working here, thanks!

@johlrich johlrich closed this Aug 30, 2018

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member

I'd like to keep this open until it's fixed in azure functions and when we removed the workaround again

Member

forki commented Aug 30, 2018

I'd like to keep this open until it's fixed in azure functions and when we removed the workaround again

@forki forki reopened this Aug 30, 2018

@forki

This comment has been minimized.

Show comment
Hide comment
@forki

forki Aug 30, 2018

Member

So if I read the example code at #3345 (comment) correctly then extensions.json is basically azure functions own version of binding redirects but for dotnet core. Am I correct? I mean after Microsoft people insisting that binding redirects are no longer needed for 3 years - how can this be?

Member

forki commented Aug 30, 2018

So if I read the example code at #3345 (comment) correctly then extensions.json is basically azure functions own version of binding redirects but for dotnet core. Am I correct? I mean after Microsoft people insisting that binding redirects are no longer needed for 3 years - how can this be?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment