Azure-functions-vs-build-sdk: Unable to generate nuget package when using nuget "Microsoft.NET.Sdk.Functions" in a library project

Created on 8 Sep 2017  路  24Comments  路  Source: Azure/azure-functions-vs-build-sdk

Hi,
When generating the nuget package for a project which references <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.2" />, the packaging fails with error:
C:\Program Files\dotnet\sdk\2.0.0\Sdks\NuGet.Build.Tasks.Pack\buildCrossTargeting\NuGet.Build.Tasks.Pack.targets(141,5): error : The file 'c:\users\<user>\documents\visual studio 2017\Projects\AzFuncExtensions\AzFuncExtensions\bin\Debug\net461\AzFuncExtensions.dll' to be packed was not found on disk., since it includes some MsBuild targets which is moving DLLs in the bin subfolder.

My goal here was to include a nuget package which references all the expected dependencies currently supported by the Functions runtime (the beta versions of WebJobs for example), without having to reference the specific nuget packages directly. This will allow me to create a classic class library aligned with the Functions runtime that I can use in my pre-compiled functions, and distribute it as a nuget package.

That experience triggered sevaral comments:
1) The current description of the nuget package is: Package Description, which isn't really helpful.
2) From the name I was expecting that nuget to be what I was looking for. Maybe something including Build or Task or MsBuild?
3) There is currently no easy way to align our project nugets with the Function Runtime expected versions (except going to the github repo for webjobs and looking at the packages.config and web.config to figure out the redirects).
4) It would be nice to have a compile time warning if my nuget versions are not aligned with the Functions runtime. Currently, I have to execute my code with the CLI to figure this out.
5) I do now understand that this "Microsoft.NET.Sdk.Functions" is meant to be referenced from the pre-compiled assembly only to enable proper debugging scenarios from visual studio with the AzFunc CLI, but I do believe that what I am trying to accomplish will be done by other developers. Currently, I have to explicitly add pre-release nugets in my project (Include="Microsoft.Azure.WebJobs" Version="2.1.0-beta1"), at the next release of the runtime, I guess I will need to go upgrade manually that version to make sure I am aligned
6) It looks strange to have a non-beta nuget to depend on beta nuget... Are there any plans to have the webjobs stuff out of beta?

Project to reproduce the problem:
AzFuncExtensions.csproj:

<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFrameworks>net461</TargetFrameworks>
    <GeneratePackageOnBuild>True</GeneratePackageOnBuild>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="1.0.2" />
  </ItemGroup>
</Project>

The project includes a simple class:

using Microsoft.Azure.WebJobs.Host;

namespace AzFuncExtensions
{
    public static class TraceWriterExtensions
    {
        public static void LogTodo(this TraceWriter writer)
        {
            writer.Error("TODO");
        }
    }
}

Most helpful comment

If you're creating a shared library, the workaround could be to remove reference to Microsoft.NET.Sdk.Functions and instead reference some packages that Microsoft.NET.Sdk.Functions depends on. For example, I resolved this by replacing it with a reference to Microsoft.Azure.WebJobs.Extensions.Http that our library actually depends on.

All 24 comments

I am having the same issue creating a nuget when proj reference Microsoft.NET.Sdk.Functions

This is causing me headaches too, has anyone been able to get to the bottom of this?

I'm having a similar issue, but with a different "warning" while referencing a newer version of the package (1.0.7):

C:\Users\aanttila\.nuget\packages\microsoft.net.sdk.functions\1.0.7\build\netstandard1.0\Microsoft.NET.Sdk.Functions.Build.targets(32,5): warning : [C:\SomeFolder\SomeProject.csproj]

The end result is that I can't create a NuGet package that references the Functions SDK, so we can't package some of our code the way we'd like to.

+1

We really need this to be able to create and consume some shared code in a large functions implementation. Any updates?

+1

Same here. Is there any workaround for generating packages even when it doesn't work with Visual Studio out-of-the-box?

As a work around you could create a nuspec file and include the additional bin folder
image
Then use the nuget command line to pack the file e.g. nuget pack Useful.Azure.Functions.Dependency.Injection.nuspec

+1
same issue.

+1

Does anyone have any solutions?

@ahmelsayed / @soninaren - Is this scenario supported?

Simply, I added .nuspec (in my case it's LogMetrics) file with below content in the my source project

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
    <metadata>
        <id>AzureFunctions</id>
        <version>1.0.0.0</version>
        <title>LogMetrics</title>
        <authors>Muhammad Bilal Yar</authors>
        <owners>Muhammad Bilal Yar</owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>Azure Functions</description>
        <copyright>copyright</copyright>
        <tags>AzureFunctions</tags>
    </metadata>
    <files>
        <!--<file src="$OutputPath$"                                    target="\" />-->
        <file src="\bin\Release\" target="\" />
    </files>
</package>

Then pass LogMetrics.nupac file path to Nuget Pack task on Azure DevOps.
image
It's works for me.

An alternate solution that i am using is

  1. Add Nuget. exe and NuGet.targets in source project
  2. Than add .nuspec file
  3. at last, add Post Build event, below is my post build evernt script
<Import Project="..\.nuget\NuGet.targets" />
  <Target Name="CreateNugetPackage">
    <MakeDir Directories="$(OutDir)OctopusPackages">
      <Output PropertyName="OctopusPackagesPath" TaskParameter="DirectoriesCreated">
      </Output>
    </MakeDir>
    <Message Text="Creating NuGet package..." />
    <Exec Command="..\.nuget\nuget pack $(ProjectPath) -NoPackageAnalysis -p OutputPath=$(OutDir) -OutputDirectory $(OutDir)OctopusPackages">
    </Exec>
  </Target>
<Target Name="AfterBuild" DependsOnTargets="CreateNugetPackage;">
    <Message Text="AfterBuild in = $(ProjectName) complete!" />
  </Target>

Simply, I added .nuspec (in my case it's LogMetrics) file with below content in the my source project

<?xml version="1.0" encoding="utf-8"?>
<package xmlns="http://schemas.microsoft.com/packaging/2012/06/nuspec.xsd">
    <metadata>
        <id>AzureFunctions</id>
        <version>1.0.0.0</version>
        <title>LogMetrics</title>
        <authors>Muhammad Bilal Yar</authors>
        <owners>Muhammad Bilal Yar</owners>
        <requireLicenseAcceptance>false</requireLicenseAcceptance>
        <description>Azure Functions</description>
        <copyright>copyright</copyright>
        <tags>AzureFunctions</tags>
    </metadata>
    <files>
        <!--<file src="$OutputPath$"                                    target="\" />-->
        <file src="\bin\Release\" target="\" />
    </files>
</package>

Then pass LogMetrics.nupac file path to Nuget Pack task on Azure DevOps.
image
It's works for me.

It seems to work only with the Nuget CLI, getting this to work with dotnet CLI is problematic. The following instructions do not seem to work:

https://docs.microsoft.com/en-us/nuget/reference/msbuild-targets#packing-using-a-nuspec

@soninaren to take a look

This is a pretty ancient issue, but it's still a problem. It makes sense to want to publish function classes as a NuGet library, and it's pretty weird that it doesn't work.

Hi, I'm running into this issue also. Has there been any movement on it?

Still a problem...

Is the intent here to add functions with the references to a NuGet package and use this NuGet package in other function projects?

If so, why not package using a simple NetStandard class library project?

e.g: You can put all the cs files under the resources folder and add all the required references. when this project gets packaged, it will include the functions content and references.

Packaging app:

<Project Sdk="Microsoft.NET.Sdk">

  <PropertyGroup>
    <TargetFramework>netstandard2.0</TargetFramework>
  </PropertyGroup>

  <ItemGroup>
    <PackageReference Include="Microsoft.Azure.WebJobs.Extensions.CosmosDB" Version="3.0.5" />
  </ItemGroup>

  <ItemGroup>
    <Content Include="Resources\**">
      <Pack>true</Pack>
      <PackagePath>/contentFiles/cs/netcoreapp3.1</PackagePath>
    </Content>
  </ItemGroup>

  <ItemGroup>
    <Compile Remove="Resources\**" />
  </ItemGroup>

</Project>

Consuming Function app. ClassLibrary1 package will bring in the content and references.

<Project Sdk="Microsoft.NET.Sdk">
  <PropertyGroup>
    <TargetFramework>netcoreapp3.1</TargetFramework>
    <AzureFunctionsVersion>v3</AzureFunctionsVersion>
  </PropertyGroup>
  <ItemGroup>
    <PackageReference Include="ClassLibrary1" Version="1.0.0" />
    <PackageReference Include="Microsoft.NET.Sdk.Functions" Version="3.0.9" />
  </ItemGroup>
  <ItemGroup>
    <None Update="host.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
    </None>
    <None Update="local.settings.json">
      <CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
      <CopyToPublishDirectory>Never</CopyToPublishDirectory>
    </None>
  </ItemGroup>
</Project>

The goal of the initial request was to be able to develop code in libraries which are using versions exactly aligned with the Functions SDK versions, to prevent using versions which are too new vs the Azure Functions runtime. For example, back when the issue was raised, pointing to the wrong version of the Azure Storage library would cause Azure Functions to break. By adding a reference to Microsoft.NET.Sdk.Functions we are sure that our versions are aligned. Keep in mind that your sample code where everything is in the same project is not representative of how people work. For example, if I have code to share between the Azure Functions project and lets say an ASPNET core project, I would use another library in which I want to have the proper dependencies required by Az Function

If not using that Microsoft.NET.Sdk.Functions library which also includes the build step required to generate the configuration files, maybe another package with only the dependencies could be created in nuget so that it can be linked from other libraries? For example: Microsoft.NET.Sdk.Functions.Dependencies or whatever.

@SimonLuckenuik - Thanks for the quick response and explanation. I see your point. In the latest 3.0.9 version of the sdk, I have removed the code where publish was overriding pack.

https://github.com/Azure/azure-functions-vs-build-sdk/commit/0992e21cc695c18b08bcf9de22ca0dc2dcab9713#diff-60eb2d9d1ecbc014c8c0a62346773539L20-L35

Even though this is removed, one of the dependent packages block the pack gen for Azure Sdk functions. So don't think this is resolved yet.

Essentially you are looking for a way to replicate this dependency graph (below) without the build generation capabilities:
https://github.com/Azure/azure-functions-vs-build-sdk/blob/v3.x/src/Microsoft.NET.Sdk.Functions/Microsoft.NET.Sdk.Functions.csproj#L72-L78

Adding @fabiocav to hear his thoughts on this.

@vijayrkn, exactly for the dependency graph you are referring to, that would do the trick.
Currently, in order to be aligned we need to visit the complete graph for each of the dependencies listed and make sure we have the exact same versions.

With a package with the dependencies, it would allow us to simply refer to that one and any conflict for mismatching versions would be flagged by nuget. For example, if I would reference directly the nuget for the lastest Newtonsoft.Json v12 along with the new Microsoft.NET.Sdk.Functions.Dependencies, I would get a nuget warning directly in visual studio if I remember well.

You could even use Microsoft.NET.Sdk.Functions.Dependencies directly from Microsoft.NET.Sdk.Functions as well, so both your team and the developers would depend on the exact same package.

You could even use Microsoft.NET.Sdk.Functions.Dependencies directly from Microsoft.NET.Sdk.Functions as well, so both your team and the developers would depend on the exact same package.

Thanks for the input. Shouldn't be hard to implement but lets see what @fabiocav thinks about this approach.

If you're creating a shared library, the workaround could be to remove reference to Microsoft.NET.Sdk.Functions and instead reference some packages that Microsoft.NET.Sdk.Functions depends on. For example, I resolved this by replacing it with a reference to Microsoft.Azure.WebJobs.Extensions.Http that our library actually depends on.

@Alex-Sob Thank you so much, with that step I'm able to generate the package.

Was this page helpful?
0 / 5 - 0 ratings