azure-functions-core-tools: F# function based on azure-functions-templates doesn't start; "Host.json file in missing"
This is similar to #1734 . I created a new F♯ function from the templates in Azure/azure-functions-templates.
I also installed v3 of the core tools via chocolatey, and when I try to run the function from the project directory, this is the result:
Here’s the project file:
<?xml version="1.0" encoding="utf-8"?>
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netcoreapp3.1</TargetFramework>
<AzureFunctionsVersion>v3</AzureFunctionsVersion>
</PropertyGroup>
<ItemGroup>
<Compile Include="Program.fs" />
</ItemGroup>
<ItemGroup>
<None Update="host.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>PreserveNewest</CopyToPublishDirectory>
</None>
<None Update="local.settings.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
</None>
</ItemGroup>
<Import Project="..\..\.paket\Paket.Restore.targets" />
</Project>
I’ve opened an issue over in the template repository, but there’s been no response yet, and I’m a bit at a loss for how to get this to work. https://github.com/Azure/azure-functions-templates/issues/945
About this issue
- Original URL
- State: open
- Created 4 years ago
- Reactions: 4
- Comments: 23 (8 by maintainers)
Commits related to this issue
- Explicitly including Functions json files As noted in https://github.com/Azure/azure-functions-core-tools/issues/1963#issuecomment-641019816 because F# requires all files to be explicitly included wi... — committed to aaronpowell/azure-functions-templates by aaronpowell 4 years ago
- conditionally including files for F# (see https://github.com/Azure/azure-functions-core-tools/issues/1963) — committed to aaronpowell/blazor-workshop by aaronpowell 4 years ago
It looks like the problem is related to the F# project template.
Let’s take a look at the project file here: https://github.com/Azure/azure-functions-templates/blob/dev/Functions.Templates/ProjectTemplate/FSharp/Company.FunctionApp.fsproj#L11-L17
Both of these items are
<None>
with a “include type” ofUpdate
. What happens here is that when MSBuild runs it will update any reference tohost.json
and set it’sCopyToOutputDirectory
toPreserveNewest
. But, that file hasn’t been added to the MSBuild “file list” that it’s internally tracking and because it’s an “Update” not an “InsertOrUpdate”, it doesn’t have anything to update and thus it’s ignored.If you change it to
<None Include="host.json">
it will tell MSBuild that you want to explicitly include that file with the following metadata, which is why it then works.So, if you look at the C# project template (https://github.com/Azure/azure-functions-templates/blob/dev/Functions.Templates/ProjectTemplate/CSharp/Company.FunctionApp.csproj#L11-L17) you might notice that it does the same as F# but doesn’t have the same problem and you as yourself “why is that?”, well, it’s because C# will include files by default, whereas F# is explicit includes (and that’s why you don’t need
<Compile>
items for all.cs
files in SDK projects).This is controlled by the file
Microsoft.NET.Sdk.DefaultItems.targets
- https://github.com/dotnet/sdk/blob/master/src/Tasks/Microsoft.NET.Build.Tasks/targets/Microsoft.NET.Sdk.DefaultItems.targets#L19 and this file is referenced implicitly when you use SDK project templates. F# on the other hand usesMicrosoft.FSharp.NetSdk.props
- https://github.com/dotnet/fsharp/blob/master/src/fsharp/FSharp.Build/Microsoft.FSharp.NetSdk.props#L34Since the
.props
file is referenced first, it sets the value ofEnableDefaultNoneItems
tofalse
and then when theMicrosoft.NET.Sdk.DefaultItems.targets
is used, the value is already set, so it won’t set it totrue
.The result is that the
host.json
andlocal.settings.json
aren’t included in the files MSBuild is tracking and thus output by MSBuild (either when you rundotnet build
orfunc start
).TL;DR: Change
<None Update="host.json">
to<None Include="host.json">
and I’ll open a PR.(PS: Big thanks to @davidwengier for helping me to understand MSBuild better and for this video)
This seems to work for me without having to create stub files during the CI build.
.fsproj:
I also came across this issue. I created the function using:
dotnet new func --language F#
dotnet new timer --language F# --name Timer
@anthonychu The fsproj file has a reference to the Functions SDK:
I used @aggieben 's workaround with the BeforeTargets hook to copy the files to the output directory which works for the time being. Thanks!
@isaacabraham I created a PR for the template to fix it: https://github.com/Azure/azure-functions-templates/pull/954 but as @cartermp points out, this is a related issue on the compiler/build (https://github.com/dotnet/fsharp/issues/8914), and as @vjraitila points out, changing the inclusion mode can result in it being published to Azure, which you don’t want.
I think using the
Condition
attribute of theNone
for inclusion is probably the quickest solution, but it’s not a perfect one.Wow. I just fell for this as well. Just changing from Update to Include fixes it.
What I’ve done in my CD workflow is simply create a stub file before build—because
<CopyToPublishDirectory>Never</CopyToPublishDirectory>
is set it’ll never make it into the published output dir..fsproj:
action: