1
votes

I have a .NET Core 3.1 Azure Function (maybe not relevant) and have modified my .csproj to zip the binaries using ZipDirectory after the build runs. When zipping, I noticed that ZipDirectory is not zipping the folders for each function that gets created during the build, but it zips everything else. I am running MSBuild through the Developer Command Prompt for VS 2019 with msbuild /p:platform="Any CPU" /p:configuration="Release" /p:VisualStudioVersion="16.0" in the same directory that my solution is located. I have provided my .csproj and my only .cs file in the project:

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

  <Target Name="DeleteArtifactsFolder" AfterTargets="Build">
    <RemoveDir Directories="$(OutputPath)\..\..\..\Artifacts" />
  </Target>

  <Target Name="CreateArtifactsDirectory" AfterTargets="DeleteArtifactsFolder">
    <MakeDir Directories="$(OutputPath)\..\..\..\Artifacts" />
  </Target>

  <Target Name="ZipBinariesToArtifacts" AfterTargets="CreateArtifactsDirectory">
    <ZipDirectory SourceDirectory="$(OutputPath)" DestinationFile="$(OutputPath)\..\..\..\Artifacts\Artifacts.zip" />
  </Target>
</Project>

Here is the only .cs file in the project:

namespace MyFunctionApp
{
    using Microsoft.AspNetCore.Http;
    using Microsoft.AspNetCore.Mvc;
    using Microsoft.Azure.WebJobs;
    using Microsoft.Azure.WebJobs.Extensions.Http;
    using Microsoft.Extensions.Logging;

    using System.Threading.Tasks;
    public static class Functions
    {
        [FunctionName("Function1")]
        public static async Task<IActionResult> Run(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "1")] HttpRequest req,
            ILogger log)
        {
            return new OkResult();
        }

        [FunctionName("Function2")]
        public static async Task<IActionResult> Run2(
            [HttpTrigger(AuthorizationLevel.Anonymous, "get", Route = "1")] HttpRequest req,
            ILogger log)
        {
            return new OkResult();
        }
    }
}

Here are screenshots of the files that I expect to be zipped and the files that actually get zipped. One thing I noticed is that it's copying the MyFunctionApp.pdb file from the bin into the root of the zip.

Edit: I did a test by purposely making the zip task error out by zipping to a folder that doesn't exist yet, and I noticed that the zip task errors out before the Function1 and Function2 folders are created but after the other build files are made. This makes me thing the zip task is beginning before the build finishes. Does anyone know what I've done wrong?

1
Ah thanks @PerryQian-MSFT! Forgot to mark it as solved after the 2-day waiting period!user13308826

1 Answers

2
votes

I found out the issue is related to the build steps for Azure Functions (or my expectations of the build steps). When we build C# libraries, the Build target ends with CopyFilesToOutputDirectory. For Azure Functions, the Build target ends with _FunctionsPostBuildDepsCopy (the "PostBuild" is misleading), which comes after CopyFilesToOutputDirectory.

Finally, there are 2 post-build events that get called after this: _GenerateFunctionsPostBuild and then _GenerateFunctionsExtensionsMetadataPostBuild. The _GenerateFunctionsPostBuild target is what creates the folders and files for each function. After this target is run, we can begin zipping our Azure Function's binaries. This was important for me because I needed the folder for each function in order to use WebDeploy with a zip archive. Otherwise, I would have deployed an Azure Function resource with no functions.