diff --git a/DotNetWorker.sln b/DotNetWorker.sln index a0ce8d085..102591a1b 100644 --- a/DotNetWorker.sln +++ b/DotNetWorker.sln @@ -134,6 +134,8 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Worker.Extensions.Tests", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "AspNetIntegration", "samples\AspNetIntegration\AspNetIntegration.csproj", "{D2F67410-9933-42E8-B04A-E17634D83A30}" EndProject +Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "Net7Worker", "samples\Net7Worker\Net7Worker.csproj", "{EC1A321B-70F6-420B-85D4-56C7869BB71B}" +EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -332,6 +334,10 @@ Global {D2F67410-9933-42E8-B04A-E17634D83A30}.Debug|Any CPU.Build.0 = Debug|Any CPU {D2F67410-9933-42E8-B04A-E17634D83A30}.Release|Any CPU.ActiveCfg = Release|Any CPU {D2F67410-9933-42E8-B04A-E17634D83A30}.Release|Any CPU.Build.0 = Release|Any CPU + {EC1A321B-70F6-420B-85D4-56C7869BB71B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU + {EC1A321B-70F6-420B-85D4-56C7869BB71B}.Debug|Any CPU.Build.0 = Debug|Any CPU + {EC1A321B-70F6-420B-85D4-56C7869BB71B}.Release|Any CPU.ActiveCfg = Release|Any CPU + {EC1A321B-70F6-420B-85D4-56C7869BB71B}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE @@ -390,6 +396,7 @@ Global {286F9EE3-00AE-4EFA-BFD8-A2E58BC809D2} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378} {17BDCE12-6964-4B87-B2AC-68CE270A3E9A} = {FD7243E4-BF18-43F8-8744-BA1D17ACF378} {D2F67410-9933-42E8-B04A-E17634D83A30} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6} + {EC1A321B-70F6-420B-85D4-56C7869BB71B} = {9D6603BD-7EA2-4D11-A69C-0D9E01317FD6} EndGlobalSection GlobalSection(ExtensibilityGlobals) = postSolution SolutionGuid = {497D2ED4-A13E-4BCA-8D29-F30CA7D0EA4A} diff --git a/sdk/Sdk/ExtensionsCsprojGenerator.cs b/sdk/Sdk/ExtensionsCsprojGenerator.cs index ad565f787..c54553c9c 100644 --- a/sdk/Sdk/ExtensionsCsprojGenerator.cs +++ b/sdk/Sdk/ExtensionsCsprojGenerator.cs @@ -32,16 +32,13 @@ public void Generate() var extensionsCsprojFilePath = Path.Combine(_outputPath, ExtensionsProjectName); string csproj = GetCsProjContent(); - - // Incremental build support: write the new csproj only if contents have changed. - // By keeping one from a previous build around, our restore & build has a chance - // to follow incremental build and no-op if nothing needs to be done. if (File.Exists(extensionsCsprojFilePath)) { string existing = File.ReadAllText(extensionsCsprojFilePath); if (string.Equals(csproj, existing, StringComparison.Ordinal)) { - // Up to date, nothing to do. + // If contents are the same, only touch the file to update timestamp. + File.SetLastWriteTimeUtc(extensionsCsprojFilePath, DateTime.UtcNow); return; } } diff --git a/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.targets b/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.targets index 77767d968..4b4767cc8 100644 --- a/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.targets +++ b/sdk/Sdk/Targets/Microsoft.Azure.Functions.Worker.Sdk.targets @@ -8,429 +8,217 @@ WARNING: DO NOT MODIFY this file unless you are knowledgeable about MSBuild and *********************************************************************************************** --> - - - <_ToolingSuffix> - <_AzureFunctionsNotSet Condition="'$(AzureFunctionsVersion)' == ''">true - v3 - <_ToolingSuffix Condition="($(AzureFunctionsVersion.StartsWith('v3',StringComparison.OrdinalIgnoreCase)) Or $(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase))) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v5.0'">net5-isolated - <_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v6.0'">net6-isolated - <_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v7.0'">net7-isolated - <_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v8.0'">net8-isolated - <_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETFramework'">netfx-isolated - $(_ToolingSuffix) - <_FunctionsTaskFramework Condition=" '$(MSBuildRuntimeType)' == 'Core'">netstandard2.0 - <_FunctionsTaskFramework Condition=" '$(_FunctionsTaskFramework)' == ''">net472 - <_FunctionsTasksDir Condition=" '$(_FunctionsTasksDir)'=='' ">$(MSBuildThisFileDirectory)..\tools\$(_FunctionsTaskFramework)\ - <_FunctionsTaskAssemblyFullPath Condition=" '$(_FunctionsTaskAssemblyFullPath)'=='' ">$(_FunctionsTasksDir)\Microsoft.Azure.Functions.Worker.Sdk.dll - - <_FunctionsWorkerConfigInputFile>$(MSBuildThisFileDirectory)\..\tools\worker.config.json - - <_FunctionsMetadataLoaderExtensionFile>$(MSBuildThisFileDirectory)\..\tools\netstandard2.0\Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader.dll - <_FunctionsExtensionsDirectory>.azurefunctions - <_FunctionsExtensionsJsonName>extensions.json - <_FunctionsExtensionsFullPublish Condition="$(NoBuild) == '' And $(_FunctionsExtensionsFullPublish) == ''">True - <_FunctionsExtensionsFullPublish Condition="$(_FunctionsExtensionsFullPublish) == ''">!$(NoBuild) - $(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed.Functions\ - - false - true - false - true - false - true - true - false - true - - - - - - - - - - - - - - - - - - - - - - - - <_FunctionsWorkerConfigOutputFile>$(TargetDir)\worker.config.json - $([System.IO.Path]::GetFullPath($(IntermediateOutputPath)WorkExtensions)) - - - - - - - - - - - - - - - - - - - - - - - - - + + + <_ToolingSuffix> + <_AzureFunctionsNotSet Condition="'$(AzureFunctionsVersion)' == ''">true + v3 + <_ToolingSuffix Condition="($(AzureFunctionsVersion.StartsWith('v3',StringComparison.OrdinalIgnoreCase)) Or $(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase))) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v5.0'">net5-isolated + <_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v6.0'">net6-isolated + <_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v7.0'">net7-isolated + <_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETCoreApp' And '$(TargetFrameworkVersion)' == 'v8.0'">net8-isolated + <_ToolingSuffix Condition="$(AzureFunctionsVersion.StartsWith('v4',StringComparison.OrdinalIgnoreCase)) And '$(TargetFrameworkIdentifier)' == '.NETFramework'">netfx-isolated + $(_ToolingSuffix) + <_FunctionsTaskFramework Condition=" '$(MSBuildRuntimeType)' == 'Core'">netstandard2.0 + <_FunctionsTaskFramework Condition=" '$(_FunctionsTaskFramework)' == ''">net472 + <_FunctionsTasksDir Condition=" '$(_FunctionsTasksDir)'=='' ">$(MSBuildThisFileDirectory)..\tools\$(_FunctionsTaskFramework)\ + <_FunctionsTaskAssemblyFullPath Condition=" '$(_FunctionsTaskAssemblyFullPath)'=='' ">$(_FunctionsTasksDir)\Microsoft.Azure.Functions.Worker.Sdk.dll + + <_FunctionsExtensionCommonProps>ImportDirectoryBuildProps=false;ImportDirectoryBuildTargets=false;ImportDirectoryPackagesProps=false + <_FunctionsWorkerConfigInputFile>$(MSBuildThisFileDirectory)\..\tools\worker.config.json + + <_FunctionsMetadataLoaderExtensionFile>$(MSBuildThisFileDirectory)\..\tools\netstandard2.0\Microsoft.Azure.WebJobs.Extensions.FunctionMetadataLoader.dll + <_FunctionsExtensionsDirectory>.azurefunctions + <_FunctionsExtensionsJsonName>extensions.json + $(MSBuildExtensionsPath)\Microsoft\VisualStudio\Managed.Functions\ + + false + true + false + true + false + true + true + false + true + + + + + + + + + + + + + + + + + + + - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - <_FilesInTargetDir Include="$(TargetDir)**\*" /> - - - - - - - - - - - - - - - - - $(FunctionsDir) - $(PublishDir)\ - $(PublishDir)bin\$(TargetFileName) - $(FunctionsDir) - - - + + - - - - - - - - $(PublishIntermediateOutputPath) - $(PublishDir)\ - $(PublishDir)bin\$(TargetFileName) - $(PublishIntermediateOutputPath) - - - - - <_PublishTempFiles Include="$(PublishIntermediateOutputPath)**\*.*" /> - - - - - - - - - - - - - - + + + + - - _InitializeDeployOnBuildProperties; - Publish; - $(_DotNetPublishFiles); - + <_FunctionsMetadataPath>$(IntermediateOutputPath)functions.metadata + <_FunctionsWorkerConfigPath>$(IntermediateOutputPath)worker.config.json + $([System.IO.Path]::GetFullPath($(IntermediateOutputPath)WorkerExtensions)) + $([System.IO.Path]::Combine($(ExtensionsCsProjDirectory), WorkerExtensions.csproj)) + <_FunctionsIntermediateExtensionJsonPath>$(ExtensionsCsProjDirectory)\buildout\bin\$(_FunctionsExtensionsJsonName) + <_FunctionsIntermediateExtensionUpdatedJsonPath>$(IntermediateOutputPath)$(_FunctionsExtensionsJsonName) + - - - - - - $(PublishDir)\worker.config.json - $([System.IO.Path]::Combine($([System.IO.Path]::GetTempPath()), $([System.IO.Path]::GetRandomFileName()))) - - - - - - - - - - - - - $(PublishDir)\worker.config.json - $([System.IO.Path]::Combine($([System.IO.Path]::GetTempPath()), $([System.IO.Path]::GetRandomFileName()))) - + + + + + + + + - + + + + + + + - + + + + - + + - + - - - - - - - - - - - - - - - - - - - - - - - - + + + + - - - _GenerateFunctionsAndCopyContentFiles; - _WorkerExtensionsRestorePublish; - _WorkerExtensionsFullPublish; - _WorkerExtensionsPublishCopy; - _EnhanceFunctionsExtensionsMetadataPostPublish - - - _GenerateFunctionsAndCopyContentFiles; - _WorkerExtensionsPublishCopyNoBuild - - + + + + - - + + + + - + + + + - + + + + <_ExtensionBinaries Include="$(ExtensionsCsProjDirectory)\buildout\bin\**" + Exclude="$(ExtensionsCsProjDirectory)\buildout\bin\runtimes\**;$(_FunctionsIntermediateExtensionJsonPath)" + CopyToOutputDirectory="PreserveNewest" + CopyToPublishDirectory="PreserveNewest" /> + <_ExtensionRuntimeBinaries Include="$(ExtensionsCsProjDirectory)\buildout\runtimes\**" + CopyToOutputDirectory="PreserveNewest" + CopyToPublishDirectory="PreserveNewest" /> + + + + + + + + + + + + + + <_NoneWithTargetPath Include="@(_ExtensionFilesWithTargetPath)" TargetPath="$(_FunctionsExtensionsDirectory)/%(_ExtensionFilesWithTargetPath.TargetPath)" /> + + - - - - - - - + + + <_WorkerExtFilesToClean Include="$(ExtensionsCsProjDirectory)\**" Condition="'$(ExtensionsCsProjDirectory)' != ''" /> + <_WorkerExtFilesToClean Include="$(TargetDir)$(_FunctionsExtensionsDirectory)\**" /> + <_WorkerExtFilesToClean Include="$(_FunctionsMetadataPath)" /> + <_WorkerExtFilesToClean Include="$(_FunctionsWorkerConfigPath)" /> + <_WorkerExtFilesToClean Include="$(TargetDir)worker.config.json" /> + <_WorkerExtFilesToClean Include="$(TargetDir)extensions.json" /> + <_WorkerExtFilesToClean Include="$(TargetDir)functions.metadata" /> + <_WorkerExtFilesToClean Include="$(_FunctionsIntermediateExtensionUpdatedJsonPath)" /> + + + + + + - - - - + \ No newline at end of file diff --git a/sdk/Sdk/Tasks/EnhanceExtensionsMetadata.cs b/sdk/Sdk/Tasks/EnhanceExtensionsMetadata.cs index 8fbaf5c13..c76bb4871 100644 --- a/sdk/Sdk/Tasks/EnhanceExtensionsMetadata.cs +++ b/sdk/Sdk/Tasks/EnhanceExtensionsMetadata.cs @@ -34,8 +34,6 @@ public override bool Execute() string newJson = JsonSerializer.Serialize(extensionsMetadata, _serializerOptions); File.WriteAllText(OutputPath, newJson); - File.Delete(ExtensionsJsonPath); - return true; } } diff --git a/sdk/release_notes.md b/sdk/release_notes.md index 36a1697ad..5bb97cb31 100644 --- a/sdk/release_notes.md +++ b/sdk/release_notes.md @@ -7,9 +7,11 @@ ### Microsoft.Azure.Functions.Worker.Sdk 1.15.0-preview1 -- Improve incremental build support for worker extension project inner build [#1749](https://github.com/Azure/azure-functions-dotnet-worker/pull/1749) - - Now builds to intermediate output path - - Avoids disk writes for generated .csproj and file copies if nothing has changed +- Improve incremental build support for worker extension project inner build [#1749](https://github.com/Azure/azure-functions-dotnet-worker/pull/1749) + - Now builds to intermediate output path - adding support for `nuget.config` +- Integrate inner build with existing .NET SDK targets [##1861](https://github.com/Azure/azure-functions-dotnet-worker/pull/1861) + - Targets have been refactored to participate with `CopyToOutputDirectory` and `CopyToPublishDirectory` instead of manually copying + - Incremental build support further improved ### Microsoft.Azure.Functions.Worker.Sdk.Analyzers (delete if not updated) diff --git a/test/FunctionMetadataGeneratorTests/ExtensionsCsProjGeneratorTests.cs b/test/FunctionMetadataGeneratorTests/ExtensionsCsProjGeneratorTests.cs index 05f148941..3af598ce7 100644 --- a/test/FunctionMetadataGeneratorTests/ExtensionsCsProjGeneratorTests.cs +++ b/test/FunctionMetadataGeneratorTests/ExtensionsCsProjGeneratorTests.cs @@ -33,20 +33,23 @@ public void GetCsProjContent_Succeeds(FuncVersion version) [InlineData(FuncVersion.V4)] public void GetCsProjContent_IncrementalSupport(FuncVersion version) { - DateTime RunGenerate(string subPath) + DateTime RunGenerate(string subPath, out string contents) { var generator = GetGenerator(version, subPath); generator.Generate(); + string path = Path.Combine(subPath, ExtensionsCsprojGenerator.ExtensionsProjectName); + contents = File.ReadAllText(path); var csproj = new FileInfo(Path.Combine(subPath, ExtensionsCsprojGenerator.ExtensionsProjectName)); return csproj.LastWriteTimeUtc; } string subPath = Guid.NewGuid().ToString(); - DateTime firstRun = RunGenerate(subPath); - DateTime secondRun = RunGenerate(subPath); + DateTime firstRun = RunGenerate(subPath, out string first); + DateTime secondRun = RunGenerate(subPath, out string second); - Assert.Equal(firstRun, secondRun); + Assert.NotEqual(firstRun, secondRun); + Assert.Equal(first, second); } static ExtensionsCsprojGenerator GetGenerator(FuncVersion version, string subPath = "")