Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/Azure.Functions.Sdk/Targets/Azure.Functions.Sdk.props
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
<Project>

<PropertyGroup>
<_WorkerConfigFileName>worker.config.json</_WorkerConfigFileName>
<AzureFunctionsVersion>v4</AzureFunctionsVersion>
<MSBuildFunctionsTargetsPath>$(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed.Functions\</MSBuildFunctionsTargetsPath>
</PropertyGroup>
Expand Down
11 changes: 6 additions & 5 deletions src/Azure.Functions.Sdk/Targets/Azure.Functions.Sdk.targets
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
<UsingTask TaskName="$(AzureFunctionsTaskNamespace).GenerateWorkerConfig" AssemblyFile="$(AzureFunctionsSdkTasksAssembly)" />

<PropertyGroup>
<_WorkerConfigOutputPath>$(IntermediateOutputPath)$(_WorkerConfigFileName)</_WorkerConfigOutputPath>
<_AzureFunctionsVersionStandardized>$(AzureFunctionsVersion.ToLowerInvariant().Split('-')[0])</_AzureFunctionsVersionStandardized>
<_FunctionsRuntimeMajorVersion>$(_AzureFunctionsVersionStandardized.TrimStart('vV'))</_FunctionsRuntimeMajorVersion>
<_ToolingSuffix Condition="'$(TargetFrameworkIdentifier)' == '.NETCoreApp'">net$([MSBuild]::GetTargetFrameworkVersion('$(TargetFramework)', 1))-isolated</_ToolingSuffix>
Expand Down Expand Up @@ -94,11 +95,6 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
</Target>

<Target Name="_PreGenerateWorkerConfig" Returns="@(_WorkerConfig)">
<PropertyGroup>
<_WorkerConfigFileName>worker.config.json</_WorkerConfigFileName>
<_WorkerConfigOutputPath>$(IntermediateOutputPath)$(_WorkerConfigFileName)</_WorkerConfigOutputPath>
</PropertyGroup>

<ItemGroup>
<_WorkerConfig Include="$(_WorkerConfigOutputPath)" TargetPath="$(_WorkerConfigFileName)" />
</ItemGroup>
Expand Down Expand Up @@ -136,4 +132,9 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
</ItemGroup>
</Target>

<!-- Cleans intermediate worker.config.json that CoreClean does not track. -->
<Target Name="_CleanWorkerConfig" AfterTargets="CoreClean">
<Delete Files="$(_WorkerConfigOutputPath)" TreatErrorsAsWarnings="true" />
</Target>
Comment thread
jviau marked this conversation as resolved.

</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -127,6 +127,21 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and
</Copy>
</Target>

<!--
Cleans Functions extension artifacts that CoreClean does not track:
the generated extension project directory, intermediate extensions.json,
and the .azurefunctions output directory.
-->
<Target Name="_CleanFunctionsExtensions" AfterTargets="CoreClean">
<ItemGroup>
<_FunctionsProjectDirToClean Include="@(_AzureFunctionsTargetFramework->'%(ProjectFile)')" />
</ItemGroup>
<RemoveDir Directories="@(_FunctionsProjectDirToClean->'%(RootDir)%(Directory)')" />
<Delete Files="$(_FunctionsIntermediateExtensionJsonPath)" TreatErrorsAsWarnings="true" />
<Delete Files="$(_FunctionsIntermediateExtensionJsonPath).hash" TreatErrorsAsWarnings="true" />
<RemoveDir Directories="$(TargetDir).azurefunctions" />
</Target>

<!--
Until there is a consistent post-restore hook which gives a guarantee to run our targets after restore,
_VerifyRestoredFunctionsExtensions will verify the restore hook has run. If extension restore hook has not
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using Microsoft.Build.Utilities.ProjectCreation;

namespace Azure.Functions.Sdk.Tests.Integration;

public partial class SdkEndToEndTests
{
[Fact]
public void Clean_RemovesFunctionsArtifacts()
{
// Arrange
ProjectCreator project = ProjectCreator.Templates.AzureFunctionsProject(
GetTempCsproj())
.Property("AssemblyName", "MyFunctionApp")
.WriteSourceFile("Program.cs", Resources.Program_Minimal_cs);

project.Build(restore: true).Should().BeSuccessful().And.HaveNoIssues();

string outputPath = project.GetOutputPath();
string intermediatePath = project.GetIntermediateOutputPath();
string extensionProjectDir = project.GetFunctionsExtensionProjectDirectory();

// Verify artifacts exist after build.
File.Exists(Path.Combine(outputPath, "worker.config.json")).Should().BeTrue("worker.config.json should exist in output after build");
File.Exists(Path.Combine(outputPath, "extensions.json")).Should().BeTrue("extensions.json should exist in output after build");
Directory.Exists(Path.Combine(outputPath, Constants.ExtensionsOutputFolder)).Should().BeTrue(".azurefunctions should exist in output after build");
File.Exists(Path.Combine(intermediatePath, "worker.config.json")).Should().BeTrue("worker.config.json should exist in intermediate after build");
File.Exists(Path.Combine(intermediatePath, "extensions.json")).Should().BeTrue("extensions.json should exist in intermediate after build");
File.Exists(Path.Combine(intermediatePath, "extensions.json.hash")).Should().BeTrue("extensions.json.hash should exist in intermediate after build");
Directory.Exists(extensionProjectDir).Should().BeTrue("extension project directory should exist after build");

// Act
BuildOutput cleanOutput = project.Clean();

// Assert
cleanOutput.Should().BeSuccessful();
File.Exists(Path.Combine(intermediatePath, "worker.config.json")).Should().BeFalse("worker.config.json should be cleaned from intermediate");
File.Exists(Path.Combine(intermediatePath, "extensions.json")).Should().BeFalse("extensions.json should be cleaned from intermediate");
File.Exists(Path.Combine(intermediatePath, "extensions.json.hash")).Should().BeFalse("extensions.json.hash should be cleaned from intermediate");
Directory.Exists(extensionProjectDir).Should().BeFalse("extension project directory should be cleaned");
Directory.Exists(Path.Combine(outputPath, Constants.ExtensionsOutputFolder)).Should().BeFalse(".azurefunctions should be cleaned from output");
}
Comment thread
jviau marked this conversation as resolved.

[Fact]
public void Clean_MultiTarget_RemovesFunctionsArtifacts()
{
// Arrange
string[] targetFrameworks = ["net8.0", "net481"];
ProjectCreator project = ProjectCreator.Templates.AzureFunctionsProject(
GetTempCsproj(), targetFramework: null)
.TargetFrameworks(targetFrameworks)
.Property("AssemblyName", "MyFunctionApp")
.Property("LangVersion", "latest")
.WriteSourceFile("Program.cs", Resources.Program_Minimal_cs);

project.Build(restore: true).Should().BeSuccessful().And.HaveNoIssues();

// Verify artifacts exist for each TFM after build.
foreach (string tfm in targetFrameworks)
{
string outputPath = GetMultiTargetOutputPath(project, tfm);
string extensionProjectDir = project.GetFunctionsExtensionProjectDirectory(tfm);

File.Exists(Path.Combine(outputPath, "worker.config.json")).Should().BeTrue($"worker.config.json should exist in {tfm} output after build");
Directory.Exists(Path.Combine(outputPath, Constants.ExtensionsOutputFolder)).Should().BeTrue($".azurefunctions should exist in {tfm} output after build");
Directory.Exists(extensionProjectDir).Should().BeTrue($"extension project directory should exist for {tfm} after build");
}

// Act
BuildOutput cleanOutput = project.Clean();

// Assert
cleanOutput.Should().BeSuccessful();
foreach (string tfm in targetFrameworks)
{
string outputPath = GetMultiTargetOutputPath(project, tfm);
string extensionProjectDir = project.GetFunctionsExtensionProjectDirectory(tfm);

Directory.Exists(extensionProjectDir).Should().BeFalse($"extension project directory should be cleaned for {tfm}");
Directory.Exists(Path.Combine(outputPath, Constants.ExtensionsOutputFolder)).Should().BeFalse($".azurefunctions should be cleaned from {tfm} output");
}
Comment thread
jviau marked this conversation as resolved.
}
}
6 changes: 6 additions & 0 deletions test/Azure.Functions.Sdk.Tests/ProjectCreatorExtensions.cs
Original file line number Diff line number Diff line change
Expand Up @@ -205,6 +205,12 @@ public BuildOutput Publish(bool build = false, bool restore = false, IDictionary
return output;
}

public BuildOutput Clean(IDictionary<string, string>? globalProperties = null)
{
project.TryBuild("Clean", globalProperties, out _, out BuildOutput output);
return output;
}

public TargetResult? RunTarget(string targetName, IDictionary<string, string>? globalProperties = null)
{
project.TryBuild(
Expand Down
Loading