From 2ff0c7b587f3f6a19363ba0209b0aebdc0760802 Mon Sep 17 00:00:00 2001 From: Beau Gosse Date: Wed, 21 Feb 2024 02:01:34 -0600 Subject: [PATCH] feat: add dotnet8 support (#6429) * feat: add dotnet8 support * Update dotnet8 test dependencies and remove extra using directives * Update samcli/lib/utils/preview_runtimes.py --------- Co-authored-by: Wing Fung Lau <4760060+hawflau@users.noreply.github.com> --- .gitignore | 2 ++ samcli/commands/build/command.py | 2 +- samcli/lib/build/workflow_config.py | 2 ++ samcli/lib/utils/architecture.py | 1 + samcli/local/common/runtime_template.py | 6 +++- samcli/local/docker/lambda_debug_settings.py | 4 +++ samcli/local/docker/lambda_image.py | 1 + schema/samcli.json | 8 +++-- tests/integration/buildcmd/test_build_cmd.py | 8 ++++- .../buildcmd/Dotnet8/HelloWorld.csproj | 15 ++++++++ .../testdata/buildcmd/Dotnet8/Program.cs | 36 +++++++++++++++++++ .../Dotnet8/aws-lambda-tools-defaults.json | 19 ++++++++++ .../validate/test_validate_command.py | 1 + .../local/docker/test_lambda_container.py | 3 +- .../docker/test_lambda_debug_settings.py | 1 + tests/unit/local/docker/test_lambda_image.py | 1 + 16 files changed, 103 insertions(+), 7 deletions(-) create mode 100644 tests/integration/testdata/buildcmd/Dotnet8/HelloWorld.csproj create mode 100644 tests/integration/testdata/buildcmd/Dotnet8/Program.cs create mode 100644 tests/integration/testdata/buildcmd/Dotnet8/aws-lambda-tools-defaults.json diff --git a/.gitignore b/.gitignore index 784bc4af7c..9eba302782 100644 --- a/.gitignore +++ b/.gitignore @@ -416,6 +416,8 @@ tests/integration/testdata/buildcmd/Dotnet6/bin tests/integration/testdata/buildcmd/Dotnet6/obj tests/integration/testdata/buildcmd/Dotnet7/bin tests/integration/testdata/buildcmd/Dotnet7/obj +tests/integration/testdata/buildcmd/Dotnet8/bin +tests/integration/testdata/buildcmd/Dotnet8/obj tests/integration/testdata/invoke/credential_tests/inprocess/dotnet/STS/obj tests/integration/testdata/sync/code/after/dotnet_function/src/HelloWorld/obj/ tests/integration/testdata/sync/code/before/dotnet_function/src/HelloWorld/obj/ diff --git a/samcli/commands/build/command.py b/samcli/commands/build/command.py index 250ba01daf..d6bf29fc63 100644 --- a/samcli/commands/build/command.py +++ b/samcli/commands/build/command.py @@ -57,7 +57,7 @@ 2. Nodejs 20.x, 18.x, 16.x, 14.x, 12.x using NPM\n 3. Ruby 3.2 using Bundler\n 4. Java 8, Java 11, Java 17, Java 21 using Gradle and Maven\n - 5. Dotnet6 using Dotnet CLI (without --use-container)\n + 5. Dotnet8, Dotnet6 using Dotnet CLI\n 6. Go 1.x using Go Modules (without --use-container)\n """ diff --git a/samcli/lib/build/workflow_config.py b/samcli/lib/build/workflow_config.py index 51db4425da..ef7aeada5c 100644 --- a/samcli/lib/build/workflow_config.py +++ b/samcli/lib/build/workflow_config.py @@ -104,6 +104,7 @@ def get_layer_subfolder(build_workflow: str) -> str: "java17": "java", "java21": "java", "dotnet6": "dotnet", + "dotnet8": "dotnet", # User is responsible for creating subfolder in these workflows "makefile": "", } @@ -163,6 +164,7 @@ def get_workflow_config( "nodejs20.x": BasicWorkflowSelector(NODEJS_NPM_CONFIG), "ruby3.2": BasicWorkflowSelector(RUBY_BUNDLER_CONFIG), "dotnet6": BasicWorkflowSelector(DOTNET_CLIPACKAGE_CONFIG), + "dotnet8": BasicWorkflowSelector(DOTNET_CLIPACKAGE_CONFIG), "go1.x": BasicWorkflowSelector(GO_MOD_CONFIG), # When Maven builder exists, add to this list so we can automatically choose a builder based on the supported # manifest diff --git a/samcli/lib/utils/architecture.py b/samcli/lib/utils/architecture.py index 310a429d3f..49713baf6a 100644 --- a/samcli/lib/utils/architecture.py +++ b/samcli/lib/utils/architecture.py @@ -32,6 +32,7 @@ "java21": [ARM64, X86_64], "go1.x": [X86_64], "dotnet6": [ARM64, X86_64], + "dotnet8": [ARM64, X86_64], "provided": [X86_64], "provided.al2": [ARM64, X86_64], "provided.al2023": [ARM64, X86_64], diff --git a/samcli/local/common/runtime_template.py b/samcli/local/common/runtime_template.py index aadcebdb6c..d9910b76d6 100644 --- a/samcli/local/common/runtime_template.py +++ b/samcli/local/common/runtime_template.py @@ -40,7 +40,7 @@ ], "dotnet": [ { - "runtimes": ["dotnet6"], + "runtimes": ["dotnet8", "dotnet6"], "dependency_manager": "cli-package", "init_location": os.path.join(_templates, "cookiecutter-aws-sam-hello-dotnet"), "build": True, @@ -99,7 +99,9 @@ def get_local_lambda_images_location(mapping, runtime): # Runtimes are ordered in alphabetical fashion with reverse version order (latest versions first) INIT_RUNTIMES = [ # dotnet runtimes in descending order + "dotnet8", "dotnet6", + # go runtimes in descending order "go1.x", # java runtimes in descending order "java21", @@ -128,6 +130,7 @@ def get_local_lambda_images_location(mapping, runtime): LAMBDA_IMAGES_RUNTIMES_MAP = { + "dotnet8": "amazon/dotnet8-base", "dotnet6": "amazon/dotnet6-base", "go1.x": "amazon/go1.x-base", "go (provided.al2)": "amazon/go-provided.al2-base", @@ -167,6 +170,7 @@ def get_local_lambda_images_location(mapping, runtime): "python3.11": "Python36", "python3.12": "Python36", "dotnet6": "dotnet6", + "dotnet8": "dotnet6", "go1.x": "Go1", } diff --git a/samcli/local/docker/lambda_debug_settings.py b/samcli/local/docker/lambda_debug_settings.py index 44ce87c2e1..a591e22d37 100644 --- a/samcli/local/docker/lambda_debug_settings.py +++ b/samcli/local/docker/lambda_debug_settings.py @@ -107,6 +107,10 @@ def get_debug_settings(debug_port, debug_args_list, _container_env_vars, runtime entry + ["/var/runtime/bootstrap"] + debug_args_list, container_env_vars={"_AWS_LAMBDA_DOTNET_DEBUGGING": "1", **_container_env_vars}, ), + Runtime.dotnet8.value: lambda: DebugSettings( + entry + ["/var/runtime/bootstrap"] + debug_args_list, + container_env_vars={"_AWS_LAMBDA_DOTNET_DEBUGGING": "1", **_container_env_vars}, + ), Runtime.go1x.value: lambda: DebugSettings( entry, container_env_vars={ diff --git a/samcli/local/docker/lambda_image.py b/samcli/local/docker/lambda_image.py index 8500872989..d625dc86ac 100644 --- a/samcli/local/docker/lambda_image.py +++ b/samcli/local/docker/lambda_image.py @@ -50,6 +50,7 @@ class Runtime(Enum): java21 = "java21" go1x = "go1.x" dotnet6 = "dotnet6" + dotnet8 = "dotnet8" provided = "provided" providedal2 = "provided.al2" providedal2023 = "provided.al2023" diff --git a/schema/samcli.json b/schema/samcli.json index b9a5560b9d..a61150aeb2 100644 --- a/schema/samcli.json +++ b/schema/samcli.json @@ -23,7 +23,7 @@ "properties": { "parameters": { "title": "Parameters for the init command", - "description": "Available parameters for the init command:\n* no_interactive:\nDisable interactive prompting for init parameters. (fail if any required values are missing)\n* architecture:\nArchitectures for Lambda functions.\n\nArchitectures: ['arm64', 'x86_64']\n* location:\nTemplate location (git, mercurial, http(s), zip, path).\n* runtime:\nLambda runtime for application.\n\nRuntimes: dotnet6, go1.x, java21, java17, java11, java8.al2, java8, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.7, python3.12, python3.11, python3.10, ruby3.2\n* package_type:\nLambda deployment package type.\n\nPackage Types: Zip, Image\n* base_image:\nLambda base image for deploying IMAGE based package type.\n\nBase images: amazon/dotnet6-base, amazon/go-provided.al2-base, amazon/go-provided.al2023-base, amazon/go1.x-base, amazon/java11-base, amazon/java17-base, amazon/java21-base, amazon/java8-base, amazon/java8.al2-base, amazon/nodejs16.x-base, amazon/nodejs18.x-base, amazon/nodejs20.x-base, amazon/python3.10-base, amazon/python3.11-base, amazon/python3.12-base, amazon/python3.7-base, amazon/python3.8-base, amazon/python3.9-base, amazon/ruby3.2-base\n* dependency_manager:\nDependency manager for Lambda runtime.\n\nDependency managers: bundler, cli-package, gradle, maven, mod, npm, pip\n* output_dir:\nDirectory to initialize AWS SAM application.\n* name:\nName of AWS SAM Application.\n* app_template:\nIdentifier of the managed application template to be used. Alternatively, run '$sam init' without options for an interactive workflow.\n* no_input:\nDisable Cookiecutter prompting and accept default values defined in the cookiecutter config.\n* extra_context:\nOverride custom parameters in the template's cookiecutter.json configuration e.g. {\"customParam1\": \"customValue1\", \"customParam2\":\"customValue2\"}\n* tracing:\nEnable AWS X-Ray tracing for application.\n* application_insights:\nEnable CloudWatch Application Insights monitoring for application.\n* structured_logging:\nEnable Structured Logging for application.\n* beta_features:\nEnable/Disable beta features.\n* debug:\nTurn on debug logging to print debug message generated by AWS SAM CLI and display timestamps.\n* save_params:\nSave the parameters provided via the command line to the configuration file.", + "description": "Available parameters for the init command:\n* no_interactive:\nDisable interactive prompting for init parameters. (fail if any required values are missing)\n* architecture:\nArchitectures for Lambda functions.\n\nArchitectures: ['arm64', 'x86_64']\n* location:\nTemplate location (git, mercurial, http(s), zip, path).\n* runtime:\nLambda runtime for application.\n\nRuntimes: dotnet8, dotnet6, go1.x, java21, java17, java11, java8.al2, java8, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.7, python3.12, python3.11, python3.10, ruby3.2\n* package_type:\nLambda deployment package type.\n\nPackage Types: Zip, Image\n* base_image:\nLambda base image for deploying IMAGE based package type.\n\nBase images: amazon/dotnet6-base, amazon/go-provided.al2-base, amazon/go-provided.al2023-base, amazon/go1.x-base, amazon/java11-base, amazon/java17-base, amazon/java21-base, amazon/java8-base, amazon/java8.al2-base, amazon/nodejs16.x-base, amazon/nodejs18.x-base, amazon/nodejs20.x-base, amazon/python3.10-base, amazon/python3.11-base, amazon/python3.12-base, amazon/python3.7-base, amazon/python3.8-base, amazon/python3.9-base, amazon/ruby3.2-base\n* dependency_manager:\nDependency manager for Lambda runtime.\n\nDependency managers: bundler, cli-package, gradle, maven, mod, npm, pip\n* output_dir:\nDirectory to initialize AWS SAM application.\n* name:\nName of AWS SAM Application.\n* app_template:\nIdentifier of the managed application template to be used. Alternatively, run '$sam init' without options for an interactive workflow.\n* no_input:\nDisable Cookiecutter prompting and accept default values defined in the cookiecutter config.\n* extra_context:\nOverride custom parameters in the template's cookiecutter.json configuration e.g. {\"customParam1\": \"customValue1\", \"customParam2\":\"customValue2\"}\n* tracing:\nEnable AWS X-Ray tracing for application.\n* application_insights:\nEnable CloudWatch Application Insights monitoring for application.\n* structured_logging:\nEnable Structured Logging for application.\n* beta_features:\nEnable/Disable beta features.\n* debug:\nTurn on debug logging to print debug message generated by AWS SAM CLI and display timestamps.\n* save_params:\nSave the parameters provided via the command line to the configuratio "type": "object", "properties": { "no_interactive": { @@ -48,9 +48,10 @@ "runtime": { "title": "runtime", "type": "string", - "description": "Lambda runtime for application.\n\nRuntimes: dotnet6, go1.x, java21, java17, java11, java8.al2, java8, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.7, python3.12, python3.11, python3.10, ruby3.2", + "description": "Lambda runtime for application.\n\nRuntimes: dotnet8, dotnet6, go1.x, java21, java17, java11, java8.al2, java8, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.7, python3.12, python3.11, python3.10, "enum": [ "dotnet6", + "dotnet8", "go1.x", "java11", "java17", @@ -84,9 +85,10 @@ "base_image": { "title": "base_image", "type": "string", - "description": "Lambda base image for deploying IMAGE based package type.\n\nBase images: amazon/dotnet6-base, amazon/go-provided.al2-base, amazon/go-provided.al2023-base, amazon/go1.x-base, amazon/java11-base, amazon/java17-base, amazon/java21-base, amazon/java8-base, amazon/java8.al2-base, amazon/nodejs16.x-base, amazon/nodejs18.x-base, amazon/nodejs20.x-base, amazon/python3.10-base, amazon/python3.11-base, amazon/python3.12-base, amazon/python3.7-base, amazon/python3.8-base, amazon/python3.9-base, amazon/ruby3.2-base", + "description": "Lambda base image for deploying IMAGE based package type.\n\nBase images: amazon/dotnet6-base, amazon/dotnet8-base, amazon/go-provided.al2-base, amazon/go-provided.al2023-base, amazon/go1.x-base, amazon/java11-base, amazon/java17-base, amazon/java21-base, amazon/java8-base, amazon/java8.al2-base, amazon/nodejs16.x-base, amazon/nodejs18.x-base, amazon/nodejs20.x-base, amazon/python3.10-base, amazon/python3.11-base, amazon/python3.12-base, amazon/python3.7-base, amazon/python3.8-base, amazon/python3.9-base, amazon/ruby3.2-base", "enum": [ "amazon/dotnet6-base", + "amazon/dotnet8-base", "amazon/go-provided.al2-base", "amazon/go-provided.al2023-base", "amazon/go1.x-base", diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index d86d5642a6..d86280ac6e 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -1190,6 +1190,8 @@ class TestBuildCommand_Dotnet_cli_package(BuildIntegBase): ("dotnet6", "Dotnet6", None), ("dotnet6", "Dotnet6", "debug"), ("provided.al2", "Dotnet7", None), + ("dotnet8", "Dotnet8", None), + ("dotnet8", "Dotnet8", "debug"), ] ) def test_dotnet_in_process(self, runtime, code_uri, mode, architecture="x86_64"): @@ -1260,6 +1262,8 @@ def test_dotnet_in_process(self, runtime, code_uri, mode, architecture="x86_64") # force to run tests on arm64 machines may cause dotnet7 test failing # because Native AOT Lambda functions require the host and lambda architectures to match ("provided.al2", "Dotnet7", None), + ("dotnet8", "Dotnet8", None), + ("dotnet8", "Dotnet8", "debug"), ] ) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @@ -1332,6 +1336,8 @@ def test_dotnet_in_container_mount_with_write_explicit(self, runtime, code_uri, # force to run tests on arm64 machines may cause dotnet7 test failing # because Native AOT Lambda functions require the host and lambda architectures to match ("provided.al2", "Dotnet7", None), + ("dotnet8", "Dotnet8", None), + ("dotnet8", "Dotnet8", "debug"), ] ) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) @@ -1401,7 +1407,7 @@ def test_dotnet_in_container_mount_with_write_interactive( ) self.verify_docker_container_cleanedup(runtime) - @parameterized.expand([("dotnet6", "Dotnet6")]) + @parameterized.expand([("dotnet6", "Dotnet6"), ("dotnet8", "Dotnet8")]) @skipIf(SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD, SKIP_DOCKER_MESSAGE) def test_must_fail_on_container_mount_without_write_interactive(self, runtime, code_uri): use_container = True diff --git a/tests/integration/testdata/buildcmd/Dotnet8/HelloWorld.csproj b/tests/integration/testdata/buildcmd/Dotnet8/HelloWorld.csproj new file mode 100644 index 0000000000..1ca34ecbcc --- /dev/null +++ b/tests/integration/testdata/buildcmd/Dotnet8/HelloWorld.csproj @@ -0,0 +1,15 @@ + + + + net8.0 + true + + + + + + + + + + \ No newline at end of file diff --git a/tests/integration/testdata/buildcmd/Dotnet8/Program.cs b/tests/integration/testdata/buildcmd/Dotnet8/Program.cs new file mode 100644 index 0000000000..f841dafdf1 --- /dev/null +++ b/tests/integration/testdata/buildcmd/Dotnet8/Program.cs @@ -0,0 +1,36 @@ +using Amazon.Lambda.Core; +using Amazon.Lambda.APIGatewayEvents; + +// Assembly attribute to enable the Lambda function's JSON input to be converted into a .NET class. +[assembly: LambdaSerializer(typeof(Amazon.Lambda.Serialization.Json.JsonSerializer))] + +namespace HelloWorld +{ + + public class Function + { + + public string FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context) + { + return "{'message': 'Hello World'}"; + } + } + + public class FirstFunction + { + + public string FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context) + { + return "Hello World"; + } + } + + public class SecondFunction + { + + public string FunctionHandler(APIGatewayProxyRequest apigProxyEvent, ILambdaContext context) + { + return "Hello Mars"; + } + } +} \ No newline at end of file diff --git a/tests/integration/testdata/buildcmd/Dotnet8/aws-lambda-tools-defaults.json b/tests/integration/testdata/buildcmd/Dotnet8/aws-lambda-tools-defaults.json new file mode 100644 index 0000000000..d4a2ed5caf --- /dev/null +++ b/tests/integration/testdata/buildcmd/Dotnet8/aws-lambda-tools-defaults.json @@ -0,0 +1,19 @@ +{ + "Information" : [ + "This file provides default values for the deployment wizard inside Visual Studio and the AWS Lambda commands added to the .NET Core CLI.", + "To learn more about the Lambda commands with the .NET Core CLI execute the following command at the command line in the project root directory.", + + "dotnet lambda help", + + "All the command line options for the Lambda command can be specified in this file." + ], + + "profile":"", + "region" : "", + "configuration": "Release", + "framework": "net8.0", + "function-runtime":"dotnet8", + "function-memory-size" : 256, + "function-timeout" : 30, + "function-handler" : "HelloWorld::HelloWorld.Function::FunctionHandler" +} diff --git a/tests/integration/validate/test_validate_command.py b/tests/integration/validate/test_validate_command.py index cfd47d0e6e..11905a96f8 100644 --- a/tests/integration/validate/test_validate_command.py +++ b/tests/integration/validate/test_validate_command.py @@ -132,6 +132,7 @@ def test_lint_supported_runtimes(self): "Resources": {}, } supported_runtimes = [ + "dotnet8", "dotnet6", "go1.x", "java21", diff --git a/tests/unit/local/docker/test_lambda_container.py b/tests/unit/local/docker/test_lambda_container.py index 681931402d..47e8e89873 100644 --- a/tests/unit/local/docker/test_lambda_container.py +++ b/tests/unit/local/docker/test_lambda_container.py @@ -13,7 +13,7 @@ from samcli.local.docker.lambda_debug_settings import DebuggingNotSupported from samcli.local.docker.lambda_image import RAPID_IMAGE_TAG_PREFIX -RUNTIMES_WITH_ENTRYPOINT = [Runtime.dotnet6.value, Runtime.go1x.value] +RUNTIMES_WITH_ENTRYPOINT = [Runtime.dotnet6.value, Runtime.dotnet8.value, Runtime.go1x.value] RUNTIMES_WITH_BOOTSTRAP_ENTRYPOINT = [ Runtime.nodejs16x.value, @@ -26,6 +26,7 @@ Runtime.python311.value, Runtime.python312.value, Runtime.dotnet6.value, + Runtime.dotnet8.value, ] RUNTIMES_WITH_DEBUG_ENV_VARS_ONLY = [ diff --git a/tests/unit/local/docker/test_lambda_debug_settings.py b/tests/unit/local/docker/test_lambda_debug_settings.py index d9501f4e7b..394a3731fa 100644 --- a/tests/unit/local/docker/test_lambda_debug_settings.py +++ b/tests/unit/local/docker/test_lambda_debug_settings.py @@ -12,6 +12,7 @@ Runtime.java17, Runtime.java21, Runtime.dotnet6, + Runtime.dotnet8, Runtime.go1x, Runtime.nodejs16x, Runtime.nodejs18x, diff --git a/tests/unit/local/docker/test_lambda_image.py b/tests/unit/local/docker/test_lambda_image.py index a8e0d776b7..f89d60c1e0 100644 --- a/tests/unit/local/docker/test_lambda_image.py +++ b/tests/unit/local/docker/test_lambda_image.py @@ -33,6 +33,7 @@ class TestRuntime(TestCase): ("java21", "java:21-x86_64"), ("go1.x", "go:1"), ("dotnet6", "dotnet:6-x86_64"), + ("dotnet8", "dotnet:8-x86_64"), ("provided", "provided:alami"), ("provided.al2", "provided:al2-x86_64"), ("provided.al2023", "provided:al2023-x86_64"),