Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for .NET 8 to Lambda Annotations #1658

Merged
merged 8 commits into from
Feb 14, 2024
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
42 changes: 19 additions & 23 deletions .github/workflows/source-generator-ci.yml
Original file line number Diff line number Diff line change
@@ -1,33 +1,31 @@
name: Source Generator CI
name: Lambda Annotations CI

on:
workflow_dispatch:
push:
branches:
- feature/annotations
- dev
pull_request:

jobs:
source-generator-build-pack-test:
lambda-annotations-build-pack-test:
runs-on: ubuntu-latest

steps:

- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Setup .NET 3.1
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v4
with:
dotnet-version: 3.1.x
- name: Setup .NET 6.0
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
- name: Setup .NET 8.0
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.100-rc.2.23502.2
dotnet-version: 8.0.x
- name: Configure AWS Credentials
uses: aws-actions/configure-aws-credentials@v1
uses: aws-actions/configure-aws-credentials@8c3f20df09ac63af7b3ae3d7c91f105f857d8497 #v4
with:
aws-access-key-id: ${{ secrets.CI_AWS_ACCESS_KEY_ID }}
aws-secret-access-key: ${{ secrets.CI_AWS_ACCESS_KEY_SECRET }}
Expand All @@ -49,9 +47,9 @@ jobs:
- name: Pack
run: dotnet pack Libraries/src/Amazon.Lambda.Annotations/Amazon.Lambda.Annotations.csproj -p:NuspecFile=../Amazon.Lambda.Annotations.nuspec --no-build --configuration Release --output "PackResults"
- name: Upload pack results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: source-generator-nuget-package
name: lambda-annotations-nuget-package
path: PackResults
# Use always() to always run this step to publish test results when there are test failures
if: ${{ always() }}
Expand All @@ -60,33 +58,31 @@ jobs:
dotnet test Libraries/test/Amazon.Lambda.Annotations.SourceGenerators.Tests/Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj --no-build --configuration Release --verbosity normal --logger trx --results-directory "TestResults"
dotnet test Libraries/test/TestServerlessApp.IntegrationTests/TestServerlessApp.IntegrationTests.csproj --no-build --configuration Release --verbosity normal --logger trx --results-directory "TestResults"
- name: Upload test results
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: source-generator-test-result
name: lambda-annotations-test-result
path: TestResults
# Use always() to always run this step to publish test results when there are test failures
if: ${{ always() }}

test-app-build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v2
- uses: actions/checkout@v4
- name: Setup .NET 6.0
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v4
with:
dotnet-version: 6.0.x
- name: Setup .NET 8.0
uses: actions/setup-dotnet@v1
uses: actions/setup-dotnet@v4
with:
dotnet-version: 8.0.100-rc.2.23502.2
dotnet-version: 8.0.x
- name: Restore dependencies
run: dotnet restore Libraries/test/TestServerlessApp/TestServerlessApp.csproj
- name: Build
run: dotnet build Libraries/test/TestServerlessApp/TestServerlessApp.csproj --no-restore --configuration Release --verbosity detailed
- name: Upload built assemblies
uses: actions/upload-artifact@v2
uses: actions/upload-artifact@v4
with:
name: test-app-build-result
path: Libraries/test/TestServerlessApp/bin/Debug/netcoreapp3.1
path: Libraries/test/TestServerlessApp/bin/Release/net6.0
7 changes: 4 additions & 3 deletions Libraries/Amazon.Lambda.Annotations.slnf
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,16 @@
"solution": {
"path": "Libraries.sln",
"projects": [
"src\\Amazon.Lambda.APIGatewayEvents\\Amazon.Lambda.APIGatewayEvents.csproj",
"src\\Amazon.Lambda.Annotations.SourceGenerator\\Amazon.Lambda.Annotations.SourceGenerator.csproj",
"src\\Amazon.Lambda.Annotations\\Amazon.Lambda.Annotations.csproj",
"src\\Amazon.Lambda.APIGatewayEvents\\Amazon.Lambda.APIGatewayEvents.csproj",
"src\\Amazon.Lambda.RuntimeSupport\\Amazon.Lambda.RuntimeSupport.csproj",
"src\\Amazon.Lambda.Core\\Amazon.Lambda.Core.csproj",
"src\\Amazon.Lambda.RuntimeSupport\\Amazon.Lambda.RuntimeSupport.csproj",
"src\\Amazon.Lambda.Serialization.SystemTextJson\\Amazon.Lambda.Serialization.SystemTextJson.csproj",
"test\\Amazon.Lambda.Annotations.SourceGenerators.Tests\\Amazon.Lambda.Annotations.SourceGenerators.Tests.csproj",
"test\\TestServerlessApp.IntegrationTests\\TestServerlessApp.IntegrationTests.csproj",
"test\\TestExecutableServerlessApp\\TestExecutableServerlessApp.csproj",
"test\\TestServerlessApp.IntegrationTests\\TestServerlessApp.IntegrationTests.csproj",
"test\\TestServerlessApp.NET8\\TestServerlessApp.NET8.csproj",
Copy link
Member Author

@ashovlin ashovlin Jan 18, 2024

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

fyi: I was only adding line 14, my VS sorted the list.

"test\\TestServerlessApp\\TestServerlessApp.csproj"
]
}
Expand Down
19 changes: 13 additions & 6 deletions Libraries/Libraries.sln
Original file line number Diff line number Diff line change
Expand Up @@ -130,14 +130,11 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Amazon.Lambda.LexV2Events",
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest", "test\Amazon.Lambda.RuntimeSupport.Tests\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest\CustomRuntimeAspNetCoreMinimalApiCustomSerializerTest.csproj", "{0BD83939-458C-4EF5-8663-7098AD1200F2}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "TestExecutableServerlessApp", "test\TestExecutableServerlessApp\TestExecutableServerlessApp.csproj", "{DD378063-C54A-44C7-9A6F-32A6A1AE94B3}"
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestExecutableServerlessApp", "test\TestExecutableServerlessApp\TestExecutableServerlessApp.csproj", "{DD378063-C54A-44C7-9A6F-32A6A1AE94B3}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "TestServerlessApp.NET8", "test\TestServerlessApp.NET8\TestServerlessApp.NET8.csproj", "{7300983D-8FCE-42EA-9B9E-B1C5347D15D8}"
EndProject
Global
GlobalSection(SharedMSBuildProjectFiles) = preSolution
test\EventsTests.Shared\EventsTests.Shared.projitems*{44e9d925-b61d-4234-97b7-61424c963ba6}*SharedItemsImports = 5
test\EventsTests.Shared\EventsTests.Shared.projitems*{a2cb78bb-e54f-48ca-bbfb-9553d27ef23d}*SharedItemsImports = 13
test\EventsTests.Shared\EventsTests.Shared.projitems*{c1bb30d2-3237-4cfc-ba93-627471148ec2}*SharedItemsImports = 5
EndGlobalSection
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
Expand Down Expand Up @@ -359,6 +356,10 @@ Global
{DD378063-C54A-44C7-9A6F-32A6A1AE94B3}.Debug|Any CPU.Build.0 = Debug|Any CPU
{DD378063-C54A-44C7-9A6F-32A6A1AE94B3}.Release|Any CPU.ActiveCfg = Release|Any CPU
{DD378063-C54A-44C7-9A6F-32A6A1AE94B3}.Release|Any CPU.Build.0 = Release|Any CPU
{7300983D-8FCE-42EA-9B9E-B1C5347D15D8}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{7300983D-8FCE-42EA-9B9E-B1C5347D15D8}.Debug|Any CPU.Build.0 = Debug|Any CPU
{7300983D-8FCE-42EA-9B9E-B1C5347D15D8}.Release|Any CPU.ActiveCfg = Release|Any CPU
{7300983D-8FCE-42EA-9B9E-B1C5347D15D8}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down Expand Up @@ -422,8 +423,14 @@ Global
{3C6AABF5-0372-41E0-874F-DF18ECCC7FB6} = {AAB54E74-20B1-42ED-BC3D-CE9F7BC7FD12}
{0BD83939-458C-4EF5-8663-7098AD1200F2} = {B5BD0336-7D08-492C-8489-42C987E29B39}
{DD378063-C54A-44C7-9A6F-32A6A1AE94B3} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69}
{7300983D-8FCE-42EA-9B9E-B1C5347D15D8} = {1DE4EE60-45BA-4EF7-BE00-B9EB861E4C69}
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {503678A4-B8D1-4486-8915-405A3E9CF0EB}
EndGlobalSection
GlobalSection(SharedMSBuildProjectFiles) = preSolution
test\EventsTests.Shared\EventsTests.Shared.projitems*{44e9d925-b61d-4234-97b7-61424c963ba6}*SharedItemsImports = 5
test\EventsTests.Shared\EventsTests.Shared.projitems*{a2cb78bb-e54f-48ca-bbfb-9553d27ef23d}*SharedItemsImports = 13
test\EventsTests.Shared\EventsTests.Shared.projitems*{c1bb30d2-3237-4cfc-ba93-627471148ec2}*SharedItemsImports = 5
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -1,6 +1,16 @@
; Shipped analyzer releases
; https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md

## Release 1.1.0
Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unrelated to this change, just moving the errors we added in 1.1.0 to the shipped file.

### New Rules

Rule ID | Category | Severity | Notes
--------|----------|----------|-------
AWSLambda0111 | AWSLambdaCSharpGenerator | Error | If the GenerateMain global property is set to true but the project OutputType is not set to 'exe'
AWSLambda0112 | AWSLambdaCSharpGenerator | Error | An invalid runtime is selected in the LambdaGlobalProperties attribute
AWSLambda0113 | AWSLambdaCSharpGenerator | Error | The GenerateMain global property is set to true and the OutputType is set to 'exe', but no Lambda Function attributes are used
AWSLambda0114 | AWSLambdaCSharpGenerator | Error | The GenerateMain global property is set to true, but the project already contains a static Main method

## Release 1.0.0
Rule ID | Category | Severity | Notes
--------|----------|----------|-------
Expand Down
Original file line number Diff line number Diff line change
@@ -1,11 +1,2 @@
; Unshipped analyzer release
; https://github.com/dotnet/roslyn-analyzers/blob/master/src/Microsoft.CodeAnalysis.Analyzers/ReleaseTrackingAnalyzers.Help.md

### New Rules

Rule ID | Category | Severity | Notes
--------|----------|----------|-------
AWSLambda0111|AWSLambdaCSharpGenerator|Error|If the GenerateMain global property is set to true but the project OutputType is not set to 'exe'
AWSLambda0112|AWSLambdaCSharpGenerator|Error|An invalid runtime is selected in the LambdaGlobalProperties attribute
AWSLambda0113|AWSLambdaCSharpGenerator|Error|The GenerateMain global property is set to true and the OutputType is set to 'exe', but no Lambda Function attributes are used
AWSLambda0114|AWSLambdaCSharpGenerator|Error|The GenerateMain global property is set to true, but the project already contains a static Main method
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ public static class DiagnosticDescriptors
public static readonly DiagnosticDescriptor InvalidRuntimeSelection = new DiagnosticDescriptor(id: "AWSLambda0112",
title: "Invalid runtime selection",
messageFormat: "The runtime selected in the Amazon.Lambda.Annotations.LambdaGlobalPropertiesAttribute is not a supported value. " +
$"The valid values are: {string.Join(", ", Generator._allowdRuntimeValues.ToArray())}",
$"The valid values are: {string.Join(", ", Generator._allowedRuntimeValues.ToArray())}",
category: "AWSLambdaCSharpGenerator",
DiagnosticSeverity.Error,
isEnabledByDefault: true);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,9 +1,4 @@
using System;
using System.Linq;
using System.Reflection;
using System.Text;
using System.Text.RegularExpressions;
using Amazon.Lambda.Annotations.SourceGenerator.Diagnostics;
using Amazon.Lambda.Annotations.SourceGenerator.Diagnostics;
using Amazon.Lambda.Annotations.SourceGenerator.Extensions;
using Amazon.Lambda.Annotations.SourceGenerator.FileIO;
using Amazon.Lambda.Annotations.SourceGenerator.Models;
Expand All @@ -13,23 +8,37 @@
using Microsoft.CodeAnalysis;
using Microsoft.CodeAnalysis.CSharp.Syntax;
using Microsoft.CodeAnalysis.Text;
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;

namespace Amazon.Lambda.Annotations.SourceGenerator
{
using System.Collections.Generic;

[Generator]
public class Generator : ISourceGenerator
{
private const string DEFAULT_LAMBDA_SERIALIZER = "Amazon.Lambda.Serialization.SystemTextJson.DefaultLambdaJsonSerializer";
private readonly IFileManager _fileManager = new FileManager();
private readonly IDirectoryManager _directoryManager = new DirectoryManager();

internal static readonly List<string> _allowdRuntimeValues = new List<string>(2)
/// <summary>
/// Maps .NET TargetFramework values to the corresponding Lambda runtime CloudFormation value
/// </summary>
internal static readonly Dictionary<string, string> _targetFrameworksToRuntimes = new Dictionary<string, string>(2)
{
{ "net6.0", "dotnet6" },
{ "net8.0", "dotnet8" }
};

internal static readonly List<string> _allowedRuntimeValues = new List<string>(4)
{
"dotnet6",
"provided.al2",
"provided.al2023"
"provided.al2023",
"dotnet8"
};

// Only allow alphanumeric characters
Expand All @@ -41,10 +50,10 @@ public class Generator : ISourceGenerator
public Generator()
{
#if DEBUG
//if (!Debugger.IsAttached)
//{
// Debugger.Launch();
//}
// if (!Debugger.IsAttached)
// {
// Debugger.Launch();
// }
#endif
}

Expand All @@ -63,7 +72,7 @@ public void Execute(GeneratorExecutionContext context)
// Check to see if any of the current syntax trees has any error diagnostics. If so
// Skip generation. We only want to sync the CloudFormation template if the project
// can compile.
foreach(var syntaxTree in context.Compilation.SyntaxTrees)
foreach (var syntaxTree in context.Compilation.SyntaxTrees)
{
if(syntaxTree.GetDiagnostics().Any(x => x.Severity == DiagnosticSeverity.Error))
{
Expand Down Expand Up @@ -102,13 +111,23 @@ public void Execute(GeneratorExecutionContext context)

var defaultRuntime = "dotnet6";

// Try to determine the target framework from the source generator context
if (context.AnalyzerConfigOptions.GlobalOptions.TryGetValue("build_property.TargetFramework", out var targetFramework))
{
if (_targetFrameworksToRuntimes.ContainsKey(targetFramework))
{
defaultRuntime = _targetFrameworksToRuntimes[targetFramework];
}
}

// The runtime specified in the global property has precedence over the one we determined from the TFM (if we did)
if (globalPropertiesAttribute != null)
{
var generateMain = globalPropertiesAttribute.NamedArguments.FirstOrDefault(kvp => kvp.Key == "GenerateMain").Value;
var runtimeAttributeValue = globalPropertiesAttribute.NamedArguments.FirstOrDefault(kvp => kvp.Key == "Runtime").Value;
var runtime = runtimeAttributeValue.Value == null ? defaultRuntime : runtimeAttributeValue.Value.ToString();

if (!_allowdRuntimeValues.Contains(runtime))
if (!_allowedRuntimeValues.Contains(runtime))
{
diagnosticReporter.Report(Diagnostic.Create(DiagnosticDescriptors.InvalidRuntimeSelection, Location.None));
return;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ public class LambdaGlobalPropertiesAttribute : Attribute
public bool GenerateMain { get; set; }

/// <summary>
/// The runtime to set in the generated CloudFormation template. Either 'dotnet6', 'provided.al2' or 'provided.al2023'.
/// The runtime to set in the generated CloudFormation template. Either 'dotnet6', 'provided.al2', 'provided.al2023', or 'dotnet8'.
/// </summary>
public string Runtime { get; set; }
}
Expand Down
2 changes: 1 addition & 1 deletion Libraries/src/Amazon.Lambda.Annotations/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -315,7 +315,7 @@ To auto-generate the `static Main` method, first ensure the `OutputType` in your
</PropertyGroup>
```

Once the output type is set to executable, add the `LambdaGlobalProperties` assembly attribute and set the `GenerateMain` property to true. You can also configure the `Runtime` in the generated CloudFormation template.
Once the output type is set to executable, add the `LambdaGlobalProperties` assembly attribute and set the `GenerateMain` property to true. If `Runtime` is not specified in the global attribute, Lambda Annotations will attempt to determine it from your project file. You can also configure the `Runtime` in the generated CloudFormation template.

To allow for multiple Lambda functions in the same executable an Environment Variable is used to determine which handler is executed. When using the `GenerateMain` attribute, ensure you also set the `ANNOTATIONS_HANDLER` environment variable on the deployed Lambda function.

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,15 @@
<Content Remove="..\TestServerlessApp\obj\**" />
<Content Remove="..\TestServerlessApp\bin\**" />
<Content Remove="..\TestServerlessApp\serverless.template" />

<Content Include="..\TestServerlessApp.NET8\**">
<Link>TestServerlessApp.NET8\%(RecursiveDir)/%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
</Content>
<Content Remove="..\TestServerlessApp.NET8\obj\**" />
<Content Remove="..\TestServerlessApp.NET8\bin\**" />
<Content Remove="..\TestServerlessApp.NET8\serverless.template" />

<Content Include="..\TestExecutableServerlessApp\**">
<Link>TestExecutableServerlessApp\%(RecursiveDir)/%(FileName)%(Extension)</Link>
<CopyToOutputDirectory>Always</CopyToOutputDirectory>
Expand Down Expand Up @@ -137,6 +146,7 @@
<None Remove="Snapshots\ServerlessTemplates\customizeResponse.template" />
<None Remove="Snapshots\ServerlessTemplates\dynamicexample.template" />
<None Remove="Snapshots\ServerlessTemplates\intrinsicexample.template" />
<None Remove="Snapshots\ServerlessTemplates\net8.template" />
<None Remove="Snapshots\ServerlessTemplates\nullreferenceexample.template" />
<None Remove="Snapshots\ServerlessTemplates\sourcegeneratorserializationexample.template" />
<None Remove="Snapshots\ServerlessTemplates\subnamespace.template" />
Expand Down
Loading
Loading