Skip to content

Commit

Permalink
Prep Extensions.Rpc release: merge main into release/main (#2805)
Browse files Browse the repository at this point in the history
* Generators package version update (#2755)

* Generator tests: Add transitive dependency for System.Text.Json v8.0.5 & bump extension versions (#2760)

* Fixing Function Executor test

* Refactor WebJobs extension info  (#2762)

* skipBuildTagsForGitHubPullRequests when the PR is a fork (#2770)

* Bump System.Text.Json from 8.0.4 to 8.0.5 in /host/src/FunctionsNetHost (#2768)

Bumps [System.Text.Json](https://github.com/dotnet/runtime) from 8.0.4 to 8.0.5.
- [Release notes](https://github.com/dotnet/runtime/releases)
- [Commits](dotnet/runtime@v8.0.4...v8.0.5)

---
updated-dependencies:
- dependency-name: System.Text.Json
  dependency-type: direct:production
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>

* re-use FunctionsWorkerApplicationBuilder if called multiple times (#2774)

* Add worker extension validation to CI (#2764)

* ignore rider temp files

* Support SignalR trigger return value (#2771)

* add skipBuildTagsForGitHubPullRequests for extensions (#2779)

* Fix typos in CI referencing test projects (#2773)

* Adding a null check before initiating the internal Activity (#2765)

* Adding a null check for the internal Activity.

* Bump System.Text.Json to 8.0.5 (#2783)

* Use full namespace for Task.FromResult in function metadata provider generator to avoid namespace conflict (#2681)

* Analyzer for Multiple-Output Binding Scenarios with ASP.NET Core Integration (#2706)

* Remove documentation tag (#2751)

The parameter does not exist.

* Update global.json .net8 value (#2795)

* initial fix of duplicate registrations if AddFunctionsWorkerCore called twice (#2790)

* Ignoring fatal exceptions in InvocationHandler (#2789)

* Update nethost global json, update sample (#2797)

* Set extension RPC max message length (#2772)

* Set max message length for RPC client

* Update Rpc version and release notes

* Update packages (#2800)

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: Surbhi Gupta <surgupta@microsoft.com>
Co-authored-by: Lilian Kasem <likasem@microsoft.com>
Co-authored-by: Fabio Cavalcante <facaval@microsoft.com>
Co-authored-by: sarah <35204912+satvu@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Brett Samblanet <brettsam@microsoft.com>
Co-authored-by: Simon Cropp <simon.cropp@gmail.com>
Co-authored-by: yzt <zityang@microsoft.com>
Co-authored-by: Rohit Ranjan <90008725+RohitRanjanMS@users.noreply.github.com>
Co-authored-by: David Lee <10739819+DL444@users.noreply.github.com>
Co-authored-by: Jonathan <vanillajonathan@users.noreply.github.com>
  • Loading branch information
12 people authored Oct 23, 2024
1 parent 6a324b7 commit 6eb8998
Show file tree
Hide file tree
Showing 99 changed files with 1,468 additions and 153 deletions.
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -364,3 +364,4 @@ Migrations/
local.settings.json
/tools/localpack.ps1
/.vscode
/.idea
10 changes: 10 additions & 0 deletions Directory.Build.props
Original file line number Diff line number Diff line change
Expand Up @@ -5,4 +5,14 @@
<SuppressTfmSupportBuildWarnings Condition="'$(TargetFramework)' == 'net5.0'">true</SuppressTfmSupportBuildWarnings>
</PropertyGroup>

<PropertyGroup>
<RepoRoot>$(MSBuildThisFileDirectory)</RepoRoot>
<EngRoot>$(RepoRoot)eng/</EngRoot>
<TargetsRoot>$(EngRoot)build/</TargetsRoot>
</PropertyGroup>

<PropertyGroup Condition="'$(TF_BUILD)' == 'true'">
<ContinuousIntegrationBuild>true</ContinuousIntegrationBuild>
</PropertyGroup>

</Project>
2 changes: 1 addition & 1 deletion docs/analyzer-rules/AZFW0014.md
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# AZFW0011: Missing Registration for ASP.NET Core Integration
# AZFW0014: Missing Registration for ASP.NET Core Integration

| | Value |
|-|-|
Expand Down
44 changes: 44 additions & 0 deletions docs/analyzer-rules/AZFW0015.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
# AZFW0015: Missing HttpResult attribute for multi-output function

| | Value |
|-|-|
| **Rule ID** |AZFW00015|
| **Category** |[Usage]|
| **Severity** |Error|

## Cause

This rule is triggered when a multi-output function is missing a `HttpResultAttribute` on the HTTP response type.

## Rule description

For [functions with multiple output bindings](https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=windows#multiple-output-bindings) using ASP.NET Core integration, the property correlating with the HTTP response needs to be decorated with the `HttpResultAttribute` in order to write the HTTP response correctly. Properties of the type `HttpResponseData` will still have their responses written correctly.

## How to fix violations

Add the attribute `[HttpResult]` (or `[HttpResultAttribute]`) to the relevant property. Example:

```csharp
public static class MultiOutput
{
[Function(nameof(MultiOutput))]
public static MyOutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequest req,
FunctionContext context)
{
...
}
}

public class MyOutputType
{
[QueueOutput("myQueue")]
public string Name { get; set; }

[HttpResult]
public IActionResult HttpResponse { get; set; }
}
```

## When to suppress warnings

This rule should not be suppressed because this error will prevent the HTTP response from being written correctly.
46 changes: 46 additions & 0 deletions docs/analyzer-rules/AZFW0016.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# AZFW0016: Missing HttpResult attribute for multi-output function

| | Value |
|-|-|
| **Rule ID** |AZFW00016|
| **Category** |[Usage]|
| **Severity** |Warning|

## Cause

This rule is triggered when a multi-output function using `HttpResponseData` is missing a `HttpResultAttribute` on the HTTP response type.

## Rule description

Following the introduction of ASP.NET Core integration, for [functions with multiple output bindings](https://learn.microsoft.com/en-us/azure/azure-functions/dotnet-isolated-process-guide?tabs=windows#multiple-output-bindings), the property in a custom output type correlating with the HTTP response is expected to be decorated with the `HttpResultAttribute`.

`HttpResponseData` does not require this attribute for multi-output functions to work because support for it was available before the introduction of ASP.NET Core Integration. However, this is the expected convention moving forward as all other HTTP response types in this scenario will not work without this attribute.

## How to fix violations

Add the attribute `[HttpResult]` (or `[HttpResultAttribute]`) to the relevant property. Example:

```csharp
public static class MultiOutput
{
[Function(nameof(MultiOutput))]
public static MyOutputType Run([HttpTrigger(AuthorizationLevel.Anonymous, "get")] HttpRequestData req,
FunctionContext context)
{
...
}
}

public class MyOutputType
{
[QueueOutput("myQueue")]
public string Name { get; set; }

[HttpResult]
public HttpResponseData HttpResponse { get; set; }
}
```

## When to suppress warnings

This rule can be suppressed if there is no intention to migrate from `HttpResponseData` to other types (like `IActionResult`).
30 changes: 30 additions & 0 deletions eng/build/WorkerExtensions.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<Project>
<PropertyGroup>
<_ExtensionProjectTemplate>$(MSBuildThisFileDirectory)/extensionValidationProjectTemplate.txt</_ExtensionProjectTemplate>
<_ExtensionValidationLocation>$(IntermediateOutputPath)ExtensionValidation/</_ExtensionValidationLocation>
</PropertyGroup>

<Target Name="AddWebJobsExtensionInformation" BeforeTargets="GetAssemblyAttributes" Condition="'@(WebJobsExtension)' != ''">
<ItemGroup>
<_ExtensionInformationAttribute Include="@(WebJobsExtension->'Microsoft.Azure.Functions.Worker.Extensions.Abstractions.ExtensionInformationAttribute')">
<_Parameter1>%(WebJobsExtension.Identity)</_Parameter1>
<_Parameter2>%(WebJobsExtension.Version)</_Parameter2>
</_ExtensionInformationAttribute>
<AssemblyAttribute Include="@(_ExtensionInformationAttribute)" RemoveMetadata="Version" />
</ItemGroup>
</Target>

<Target Name="GenerateExtensionProject" AfterTargets="Compile" Condition="'@(WebJobsExtension)' != '' and '$(ContinuousIntegrationBuild)' == 'true'">
<MakeDir Directories="$(_ExtensionValidationLocation)" />
<WriteLinesToFile
File="$(_ExtensionValidationLocation)ExtensionValidation.csproj"
Lines="$([System.IO.File]::ReadAllText($(_ExtensionProjectTemplate))
.Replace('$PackageName$', '%(WebJobsExtension.Identity)')
.Replace('$PackageVersion$', '%(WebJobsExtension.Version)'))"
Overwrite="true" />
</Target>

<Target Name="RestoreGeneratedExtensionProject" AfterTargets="GenerateExtensionProject" Condition="'@(WebJobsExtension)' != '' and '$(ContinuousIntegrationBuild)' == 'true'">
<MSBuild Projects="$(_ExtensionValidationLocation)ExtensionValidation.csproj" Targets="Restore" />
</Target>
</Project>
10 changes: 10 additions & 0 deletions eng/build/extensionValidationProjectTemplate.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net8.0</TargetFramework>
<OutputType>Library</OutputType>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="$PackageName$" Version="$PackageVersion$" />
</ItemGroup>
</Project>
4 changes: 4 additions & 0 deletions eng/ci/public-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,10 @@ extends:
image: 1es-windows-2022
os: windows

settings:
# PR's from forks do not have sufficient permissions to set tags.
skipBuildTagsForGitHubPullRequests: ${{ variables['System.PullRequest.IsFork'] }}

stages:
- stage: Test

Expand Down
10 changes: 1 addition & 9 deletions eng/ci/templates/jobs/run-unit-tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -40,14 +40,6 @@ jobs:
projects: |
**\DotNetWorker.Opentelemetry.Tests.csproj
- task: DotNetCoreCLI@2
displayName: Application Insights Tests
inputs:
command: test
arguments: -v n
projects: |
**\DotNetWorker.ApplicationInsights.Tests.csproj
- task: DotNetCoreCLI@2
displayName: Sdk Tests
inputs:
Expand All @@ -56,7 +48,7 @@ jobs:
projects: |
**\SdkTests.csproj
**\Sdk.Analyzers.Tests.csproj
**\Sdk.Generatior.Tests.csproj
**\Sdk.Generator.Tests.csproj
- task: DotNetCoreCLI@2
displayName: Extension Tests
Expand Down
8 changes: 8 additions & 0 deletions extensions/Directory.Build.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
<Project>

<Import Project="$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, $(_DirectoryBuildTargetsFile)))/$(_DirectoryBuildTargetsFile)"
Condition=" '$([MSBuild]::GetDirectoryNameOfFileAbove($(MSBuildThisFileDirectory)../, $(_DirectoryBuildTargetsFile)))' != '' " />

<Import Project="$(TargetsRoot)WorkerExtensions.targets" />

</Project>
4 changes: 4 additions & 0 deletions extensions/Worker.Extensions.CosmosDB/ci/public-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ extends:
image: 1es-windows-2022
os: windows

settings:
# PR's from forks do not have sufficient permissions to set tags.
skipBuildTagsForGitHubPullRequests: ${{ variables['System.PullRequest.IsFork'] }}

stages:
- stage: Test

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,6 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Runtime.CompilerServices;
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;

[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.CosmosDB", "4.8.0")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
[assembly: InternalsVisibleTo("DynamicProxyGenAssembly2, PublicKey=0024000004800000940000000602000000240000525341310004000001000100c547cac37abd99c8db225ef2f6c8a3602f3b3606cc9891605d02baa56104f4cfc0734aa39b93bf7852f7d9266654753cc297e7d2edfe0bac1cdcf9f717241550e0a7b191195b7667bb4f64bcb8e2121380fd1d9d46ad2d92d2d15605093924cceaf74c4861eff62abf69b9291ed0a340e113be11e6a7d3113e92484cf7045cc7")]
Original file line number Diff line number Diff line change
Expand Up @@ -30,4 +30,8 @@
<SharedReference Include="..\..\Worker.Extensions.Shared\Worker.Extensions.Shared.csproj" />
</ItemGroup>

<ItemGroup>
<WebJobsExtension Include="Microsoft.Azure.WebJobs.Extensions.CosmosDB" Version="4.8.0" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions extensions/Worker.Extensions.EventGrid/ci/public-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ extends:
image: 1es-windows-2022
os: windows

settings:
# PR's from forks do not have sufficient permissions to set tags.
skipBuildTagsForGitHubPullRequests: ${{ variables['System.PullRequest.IsFork'] }}

stages:
- stage: Test

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,4 @@
using System.Runtime.CompilerServices;
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;

[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.EventGrid", "3.4.2")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
Original file line number Diff line number Diff line change
Expand Up @@ -23,4 +23,8 @@
<PackageReference Include="Azure.Messaging.EventGrid" Version="4.17.0" />
</ItemGroup>

<ItemGroup>
<WebJobsExtension Include="Microsoft.Azure.WebJobs.Extensions.EventGrid" Version="3.4.2" />
</ItemGroup>

</Project>
4 changes: 4 additions & 0 deletions extensions/Worker.Extensions.EventHubs/ci/public-build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,10 @@ extends:
image: 1es-windows-2022
os: windows

settings:
# PR's from forks do not have sufficient permissions to set tags.
skipBuildTagsForGitHubPullRequests: ${{ variables['System.PullRequest.IsFork'] }}

stages:
- stage: Test

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,5 @@
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Runtime.CompilerServices;
using Microsoft.Azure.Functions.Worker.Extensions.Abstractions;

[assembly: ExtensionInformation("Microsoft.Azure.WebJobs.Extensions.EventHubs", "6.3.5")]
[assembly: InternalsVisibleTo("Microsoft.Azure.Functions.Worker.Extensions.Tests, PublicKey=00240000048000009400000006020000002400005253413100040000010001005148be37ac1d9f58bd40a2e472c9d380d635b6048278f7d47480b08c928858f0f7fe17a6e4ce98da0e7a7f0b8c308aecd9e9b02d7e9680a5b5b75ac7773cec096fbbc64aebd429e77cb5f89a569a79b28e9c76426783f624b6b70327eb37341eb498a2c3918af97c4860db6cdca4732787150841e395a29cfacb959c1fd971c1")]
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,8 @@
<SharedReference Include="..\..\Worker.Extensions.Shared\Worker.Extensions.Shared.csproj" />
</ItemGroup>

<ItemGroup>
<WebJobsExtension Include="Microsoft.Azure.WebJobs.Extensions.EventHubs" Version="6.3.5" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,96 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.

using System.Collections.Immutable;
using System.Composition;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CodeActions;
using Microsoft.CodeAnalysis.CodeFixes;
using Microsoft.CodeAnalysis.CSharp;
using Microsoft.CodeAnalysis.CSharp.Syntax;

namespace Microsoft.Azure.Functions.Worker.Extensions.Http.AspNetCore
{
[ExportCodeFixProvider(LanguageNames.CSharp, Name = nameof(CodeFixForHttpResultAttribute)), Shared]
public sealed class CodeFixForHttpResultAttribute : CodeFixProvider
{
public override ImmutableArray<string> FixableDiagnosticIds =>
ImmutableArray.Create<string>(
DiagnosticDescriptors.MultipleOutputHttpTriggerWithoutHttpResultAttribute.Id,
DiagnosticDescriptors.MultipleOutputWithHttpResponseDataWithoutHttpResultAttribute.Id);

public override FixAllProvider GetFixAllProvider() => WellKnownFixAllProviders.BatchFixer;

public override Task RegisterCodeFixesAsync(CodeFixContext context)
{
Diagnostic diagnostic = context.Diagnostics.First();
context.RegisterCodeFix(new AddHttpResultAttribute(context.Document, diagnostic), diagnostic);

return Task.CompletedTask;
}

/// <summary>
/// CodeAction implementation which adds the HttpResultAttribute on the return type of a function using the multi-output bindings pattern.
/// </summary>
private sealed class AddHttpResultAttribute : CodeAction
{
private readonly Document _document;
private readonly Diagnostic _diagnostic;
private const string ExpectedAttributeName = "HttpResult";

internal AddHttpResultAttribute(Document document, Diagnostic diagnostic)
{
this._document = document;
this._diagnostic = diagnostic;
}

public override string Title => "Add HttpResultAttribute";

public override string EquivalenceKey => null;

/// <summary>
/// Asynchronously retrieves the modified <see cref="Document"/>, with the HttpResultAttribute added to the relevant property.
/// </summary>
/// <param name="cancellationToken">A token that can be used to propagate notifications that the operation should be canceled.</param>
/// <returns>An updated <see cref="Document"/> object.</returns>
protected override async Task<Document> GetChangedDocumentAsync(CancellationToken cancellationToken)
{
// Get the syntax root of the document
var root = await _document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false);
var semanticModel = await _document.GetSemanticModelAsync(cancellationToken).ConfigureAwait(false);

var typeNode = root.FindNode(this._diagnostic.Location.SourceSpan)
.FirstAncestorOrSelf<TypeSyntax>();

var typeSymbol = semanticModel.GetSymbolInfo(typeNode).Symbol;
var typeDeclarationSyntaxReference = typeSymbol.DeclaringSyntaxReferences.FirstOrDefault();
if (typeDeclarationSyntaxReference is null)
{
return _document;
}

var typeDeclarationNode = await typeDeclarationSyntaxReference.GetSyntaxAsync(cancellationToken);

var propertyNode = typeDeclarationNode.DescendantNodes()
.OfType<PropertyDeclarationSyntax>()
.First(prop =>
{
var propertyType = semanticModel.GetTypeInfo(prop.Type).Type;
return propertyType != null && (propertyType.Name == "IActionResult" || propertyType.Name == "HttpResponseData" || propertyType.Name == "IResult");
});

var attribute = SyntaxFactory.Attribute(SyntaxFactory.IdentifierName(ExpectedAttributeName));

var newPropertyNode = propertyNode
.AddAttributeLists(SyntaxFactory.AttributeList(SyntaxFactory.SingletonSeparatedList(attribute)));

var newRoot = root.ReplaceNode(propertyNode, newPropertyNode);

return _document.WithSyntaxRoot(newRoot);
}
}
}
}
Loading

0 comments on commit 6eb8998

Please sign in to comment.