From 3aadeb9bfd21b8e69279c9fe80ac661ed672ad1a Mon Sep 17 00:00:00 2001 From: Stephen Liedig Date: Sun, 12 Apr 2026 23:49:27 +0800 Subject: [PATCH 1/2] feat: remove dotnet6 runtime from supported surfaces and register as deprecated AWS Lambda deprecated the dotnet6 runtime on December 20, 2024. Changes: - Add dotnet6 to DEPRECATED_RUNTIMES in samcli/lib/build/constants.py - Remove dotnet6 from INIT_RUNTIMES, RUNTIME_DEP_TEMPLATE_MAPPING, LAMBDA_IMAGES_RUNTIMES_MAP, and SAM_RUNTIME_TO_SCHEMAS_CODE_LANG_MAPPING in samcli/local/common/runtime_template.py - Remove dotnet6 from SUPPORTED_RUNTIMES in samcli/lib/utils/architecture.py - Remove dotnet6 from selectors_by_runtime and subfolders_by_runtime in samcli/lib/build/workflow_config.py - Remove dotnet6 from samcli/lib/init/local_manifest.json and add missing dotnet8/dotnet10 entries - Remove dotnet6 from schema/samcli.json runtime and base image enums - Update sam build DESCRIPTION to remove Dotnet6 from help text - Retain dotnet6 in Runtime enum and debug settings for local invocation compatibility during migration Test updates: - Add dotnet6 to deprecated runtimes test in test_app_builder.py - Remove dotnet6 from supported runtime tests in test_workflow_config.py, test_architecture.py, test_cli.py, and test_manifest.json - Add dotnet8/dotnet10 to test_architecture.py and test_cli.py - Remove dotnet6 parameterizations from integration and e2e tests" --- samcli/commands/build/command.py | 2 +- samcli/lib/build/constants.py | 1 + samcli/lib/build/workflow_config.py | 2 - samcli/lib/init/local_manifest.json | 12 ++++- samcli/lib/utils/architecture.py | 1 - samcli/local/common/runtime_template.py | 5 +-- schema/samcli.json | 13 +++--- tests/end_to_end/test_runtimes_e2e.py | 3 -- tests/integration/buildcmd/test_build_cmd.py | 21 --------- .../buildcmd/test_build_cmd_dotnet.py | 45 +------------------ tests/unit/commands/buildcmd/test_utils.py | 8 ++-- tests/unit/commands/init/test_cli.py | 22 +++------ tests/unit/commands/init/test_manifest.json | 10 ----- .../unit/lib/build_module/test_app_builder.py | 1 + .../lib/build_module/test_workflow_config.py | 2 +- tests/unit/lib/utils/test_architecture.py | 3 +- tests/unit/local/docker/test_lambda_image.py | 1 - 17 files changed, 34 insertions(+), 118 deletions(-) diff --git a/samcli/commands/build/command.py b/samcli/commands/build/command.py index 14600b357d4..ff137c039e2 100644 --- a/samcli/commands/build/command.py +++ b/samcli/commands/build/command.py @@ -61,7 +61,7 @@ 2. Nodejs 24.x, 22.x, 20.x, 18.x, 16.x, 14.x, 12.x using NPM\n 3. Ruby 3.2, 3.3, 3.4 using Bundler\n 4. Java 8, Java 11, Java 17, Java 21, Java 25 using Gradle and Maven\n - 5. Dotnet6, Dotnet8, Dotnet10 using Dotnet CLI\n + 5. Dotnet8, Dotnet10 using Dotnet CLI\n 6. Go 1.x using Go Modules (without --use-container)\n """ diff --git a/samcli/lib/build/constants.py b/samcli/lib/build/constants.py index d9c7ccff88e..85ff8b652df 100644 --- a/samcli/lib/build/constants.py +++ b/samcli/lib/build/constants.py @@ -20,5 +20,6 @@ "python3.7", "ruby2.5", "ruby2.7", + "dotnet6", } BUILD_PROPERTIES = "BuildProperties" diff --git a/samcli/lib/build/workflow_config.py b/samcli/lib/build/workflow_config.py index a44cba3ef4f..8f937cf200d 100644 --- a/samcli/lib/build/workflow_config.py +++ b/samcli/lib/build/workflow_config.py @@ -107,7 +107,6 @@ def get_layer_subfolder(build_workflow: str) -> str: "java17": "java", "java21": "java", "java25": "java", - "dotnet6": "dotnet", "dotnet8": "dotnet", "dotnet10": "dotnet", # User is responsible for creating subfolder in these workflows @@ -175,7 +174,6 @@ def get_workflow_config( "ruby3.2": BasicWorkflowSelector(RUBY_BUNDLER_CONFIG), "ruby3.3": BasicWorkflowSelector(RUBY_BUNDLER_CONFIG), "ruby3.4": BasicWorkflowSelector(RUBY_BUNDLER_CONFIG), - "dotnet6": BasicWorkflowSelector(DOTNET_CLIPACKAGE_CONFIG), "dotnet8": BasicWorkflowSelector(DOTNET_CLIPACKAGE_CONFIG), "dotnet10": BasicWorkflowSelector(DOTNET_CLIPACKAGE_CONFIG), "go1.x": BasicWorkflowSelector(GO_MOD_CONFIG), diff --git a/samcli/lib/init/local_manifest.json b/samcli/lib/init/local_manifest.json index 098452776ac..65a9c36ec0d 100644 --- a/samcli/lib/init/local_manifest.json +++ b/samcli/lib/init/local_manifest.json @@ -1,5 +1,15 @@ { - "dotnet6": [ + "dotnet10": [ + { + "directory": "template/cookiecutter-aws-sam-hello-dotnet", + "displayName": "Hello World Example", + "dependencyManager": "cli-package", + "appTemplate": "hello-world", + "packageType": "Zip", + "useCaseName": "Hello World Example" + } + ], + "dotnet8": [ { "directory": "template/cookiecutter-aws-sam-hello-dotnet", "displayName": "Hello World Example", diff --git a/samcli/lib/utils/architecture.py b/samcli/lib/utils/architecture.py index 0e867576582..58baddbef0b 100644 --- a/samcli/lib/utils/architecture.py +++ b/samcli/lib/utils/architecture.py @@ -36,7 +36,6 @@ "java21": [ARM64, X86_64], "java25": [ARM64, X86_64], "go1.x": [X86_64], - "dotnet6": [ARM64, X86_64], "dotnet8": [ARM64, X86_64], "dotnet10": [ARM64, X86_64], "provided": [X86_64], diff --git a/samcli/local/common/runtime_template.py b/samcli/local/common/runtime_template.py index dd8419a36a3..61caf275d92 100644 --- a/samcli/local/common/runtime_template.py +++ b/samcli/local/common/runtime_template.py @@ -48,7 +48,7 @@ ], "dotnet": [ { - "runtimes": ["dotnet10", "dotnet8", "dotnet6"], + "runtimes": ["dotnet10", "dotnet8"], "dependency_manager": "cli-package", "init_location": os.path.join(_templates, "cookiecutter-aws-sam-hello-dotnet"), "build": True, @@ -109,7 +109,6 @@ def get_local_lambda_images_location(mapping, runtime): # dotnet runtimes in descending order "dotnet10", "dotnet8", - "dotnet6", # go runtimes in descending order "go1.x", # java runtimes in descending order @@ -146,7 +145,6 @@ def get_local_lambda_images_location(mapping, runtime): LAMBDA_IMAGES_RUNTIMES_MAP = { "dotnet10": "amazon/dotnet10-base", "dotnet8": "amazon/dotnet8-base", - "dotnet6": "amazon/dotnet6-base", "go1.x": "amazon/go1.x-base", "go (provided.al2)": "amazon/go-provided.al2-base", "go (provided.al2023)": "amazon/go-provided.al2023-base", @@ -190,7 +188,6 @@ def get_local_lambda_images_location(mapping, runtime): "python3.12": "Python36", "python3.13": "Python36", "python3.14": "Python36", - "dotnet6": "dotnet6", "dotnet8": "dotnet6", "dotnet10": "dotnet6", "go1.x": "Go1", diff --git a/schema/samcli.json b/schema/samcli.json index 11f99b1885d..54c26060e68 100644 --- a/schema/samcli.json +++ b/schema/samcli.json @@ -54,7 +54,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: dotnet10, dotnet8, dotnet6, go1.x, java25, java21, java17, java11, java8.al2, nodejs24.x, nodejs22.x, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.14, python3.13, python3.12, python3.11, python3.10, ruby3.4, ruby3.3, 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/dotnet10-base, 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/java25-base, amazon/java8.al2-base, amazon/nodejs16.x-base, amazon/nodejs18.x-base, amazon/nodejs20.x-base, amazon/nodejs22.x-base, amazon/nodejs24.x-base, amazon/python3.10-base, amazon/python3.11-base, amazon/python3.12-base, amazon/python3.13-base, amazon/python3.14-base, amazon/python3.8-base, amazon/python3.9-base, amazon/ruby3.2-base, amazon/ruby3.3-base, amazon/ruby3.4-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: dotnet10, dotnet8, go1.x, java25, java21, java17, java11, java8.al2, nodejs24.x, nodejs22.x, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.14, python3.13, python3.12, python3.11, python3.10, ruby3.4, ruby3.3, 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/dotnet10-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/java25-base, amazon/java8.al2-base, amazon/nodejs16.x-base, amazon/nodejs18.x-base, amazon/nodejs20.x-base, amazon/nodejs22.x-base, amazon/nodejs24.x-base, amazon/python3.10-base, amazon/python3.11-base, amazon/python3.12-base, amazon/python3.13-base, amazon/python3.14-base, amazon/python3.8-base, amazon/python3.9-base, amazon/ruby3.2-base, amazon/ruby3.3-base, amazon/ruby3.4-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.", "type": "object", "properties": { "no_interactive": { @@ -79,10 +79,9 @@ "runtime": { "title": "runtime", "type": "string", - "description": "Lambda runtime for application.\n\nRuntimes: dotnet10, dotnet8, dotnet6, go1.x, java25, java21, java17, java11, java8.al2, nodejs24.x, nodejs22.x, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.14, python3.13, python3.12, python3.11, python3.10, ruby3.4, ruby3.3, ruby3.2", + "description": "Lambda runtime for application.\n\nRuntimes: dotnet10, dotnet8, go1.x, java25, java21, java17, java11, java8.al2, nodejs24.x, nodejs22.x, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.14, python3.13, python3.12, python3.11, python3.10, ruby3.4, ruby3.3, ruby3.2", "enum": [ "dotnet10", - "dotnet6", "dotnet8", "go1.x", "java11", @@ -122,10 +121,9 @@ "base_image": { "title": "base_image", "type": "string", - "description": "Lambda base image for deploying IMAGE based package type.\n\nBase images: amazon/dotnet10-base, 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/java25-base, amazon/java8.al2-base, amazon/nodejs16.x-base, amazon/nodejs18.x-base, amazon/nodejs20.x-base, amazon/nodejs22.x-base, amazon/nodejs24.x-base, amazon/python3.10-base, amazon/python3.11-base, amazon/python3.12-base, amazon/python3.13-base, amazon/python3.14-base, amazon/python3.8-base, amazon/python3.9-base, amazon/ruby3.2-base, amazon/ruby3.3-base, amazon/ruby3.4-base", + "description": "Lambda base image for deploying IMAGE based package type.\n\nBase images: amazon/dotnet10-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/java25-base, amazon/java8.al2-base, amazon/nodejs16.x-base, amazon/nodejs18.x-base, amazon/nodejs20.x-base, amazon/nodejs22.x-base, amazon/nodejs24.x-base, amazon/python3.10-base, amazon/python3.11-base, amazon/python3.12-base, amazon/python3.13-base, amazon/python3.14-base, amazon/python3.8-base, amazon/python3.9-base, amazon/ruby3.2-base, amazon/ruby3.3-base, amazon/ruby3.4-base", "enum": [ "amazon/dotnet10-base", - "amazon/dotnet6-base", "amazon/dotnet8-base", "amazon/go-provided.al2-base", "amazon/go-provided.al2023-base", @@ -498,7 +496,7 @@ "properties": { "parameters": { "title": "Parameters for the local invoke command", - "description": "Available parameters for the local invoke command:\n* terraform_plan_file:\nUsed for passing a custom plan file when executing the Terraform hook.\n* hook_name:\nHook package id to extend AWS SAM CLI commands functionality. \n\nExample: `terraform` to extend AWS SAM CLI commands functionality to support terraform applications. \n\nAvailable Hook Names: ['terraform']\n* skip_prepare_infra:\nSkip preparation stage when there are no infrastructure changes. Only used in conjunction with --hook-name.\n* event:\nJSON file containing event data passed to the Lambda function during invoke. If this option is not specified, no event is assumed. Pass in the value '-' to input JSON via stdin\n* no_event:\nDEPRECATED: By default no event is assumed.\n* runtime:\nLambda runtime used to invoke the function.\n\nRuntimes: dotnet10, dotnet8, dotnet6, go1.x, java25, java21, java17, java11, java8.al2, nodejs24.x, nodejs22.x, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.14, python3.13, python3.12, python3.11, python3.10, ruby3.4, ruby3.3, ruby3.2\n* tenant_id:\nTenant ID for multi-tenant Lambda functions. Used to ensure compute isolation between different tenants. Must be 1-256 characters, the allowed characters are a-z and A-Z, numbers, spaces, and the characters _ . : / = + - @\n* durable_execution_name:\nName for the durable execution (for durable functions only).\n* mount_symlinks:\nSpecify if symlinks at the top level of the code should be mounted inside the container. Activating this flag could allow access to locations outside of your workspace by using a symbolic link. By default symlinks are not mounted.\n* template_file:\nAWS SAM template which references built artifacts for resources in the template. (if applicable)\n* env_vars:\nJSON file containing values for Lambda function's environment variables.\n* parameter_overrides:\nString that contains AWS CloudFormation parameter overrides encoded as key=value pairs.\n* debug_port:\nWhen specified, Lambda function container will start in debug mode and will expose this port on localhost.\n* debugger_path:\nHost path to a debugger that will be mounted into the Lambda container.\n* debug_args:\nAdditional arguments to be passed to the debugger.\n* container_env_vars:\nJSON file containing additional environment variables to be set within the container when used in a debugging session locally.\n* docker_volume_basedir:\nSpecify the location basedir where the SAM template exists. If Docker is running on a remote machine, Path of the SAM template must be mounted on the Docker machine and modified to match the remote machine.\n* log_file:\nFile to capture output logs.\n* layer_cache_basedir:\nSpecify the location basedir where the lambda layers used by the template will be downloaded to.\n* skip_pull_image:\nSkip pulling down the latest Docker image for Lambda runtime.\n* docker_network:\nName or ID of an existing docker network for AWS Lambda docker containers to connect to, along with the default bridge network. If not specified, the Lambda containers will only connect to the default bridge docker network.\n* force_image_build:\nForce rebuilding the image used for invoking functions with layers.\n* shutdown:\nEmulate a shutdown event after invoke completes, to test extension handling of shutdown behavior.\n* container_host:\nHost of locally emulated Lambda container. This option is useful when the container runs on a different host than AWS SAM CLI. For example, if one wants to run AWS SAM CLI in a Docker container on macOS, this option could specify `host.docker.internal`\n* container_host_interface:\nIP address of the host network interface that container ports should bind to. Use 0.0.0.0 to bind to all interfaces.\n* add_host:\nPasses a hostname to IP address mapping to the Docker container's host file. This parameter can be passed multiple times.Example:--add-host example.com:127.0.0.1\n* container_dns:\nSet custom DNS servers for the Lambda container. This parameter can be passed multiple times to specify multiple DNS servers. Example: --container-dns 8.8.8.8 --container-dns 1.1.1.1\n* invoke_image:\nContainer image URIs for invoking functions or starting api and function. One can specify the image URI used for the local function invocation (--invoke-image public.ecr.aws/sam/build-nodejs20.x:latest). One can also specify for each individual function with (--invoke-image Function1=public.ecr.aws/sam/build-nodejs20.x:latest). If a function does not have invoke image specified, the default AWS SAM CLI emulation image will be used.\n* no_memory_limit:\nRemoves the Memory limit during emulation. With this parameter, the underlying container will run without a --memory parameter\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* profile:\nSelect a specific profile from your credential file to get AWS credentials.\n* region:\nSet the AWS Region of the service. (e.g. us-east-1)\n* save_params:\nSave the parameters provided via the command line to the configuration file.", + "description": "Available parameters for the local invoke command:\n* terraform_plan_file:\nUsed for passing a custom plan file when executing the Terraform hook.\n* hook_name:\nHook package id to extend AWS SAM CLI commands functionality. \n\nExample: `terraform` to extend AWS SAM CLI commands functionality to support terraform applications. \n\nAvailable Hook Names: ['terraform']\n* skip_prepare_infra:\nSkip preparation stage when there are no infrastructure changes. Only used in conjunction with --hook-name.\n* event:\nJSON file containing event data passed to the Lambda function during invoke. If this option is not specified, no event is assumed. Pass in the value '-' to input JSON via stdin\n* no_event:\nDEPRECATED: By default no event is assumed.\n* runtime:\nLambda runtime used to invoke the function.\n\nRuntimes: dotnet10, dotnet8, go1.x, java25, java21, java17, java11, java8.al2, nodejs24.x, nodejs22.x, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.14, python3.13, python3.12, python3.11, python3.10, ruby3.4, ruby3.3, ruby3.2\n* tenant_id:\nTenant ID for multi-tenant Lambda functions. Used to ensure compute isolation between different tenants. Must be 1-256 characters, the allowed characters are a-z and A-Z, numbers, spaces, and the characters _ . : / = + - @\n* durable_execution_name:\nName for the durable execution (for durable functions only).\n* mount_symlinks:\nSpecify if symlinks at the top level of the code should be mounted inside the container. Activating this flag could allow access to locations outside of your workspace by using a symbolic link. By default symlinks are not mounted.\n* template_file:\nAWS SAM template which references built artifacts for resources in the template. (if applicable)\n* env_vars:\nJSON file containing values for Lambda function's environment variables.\n* parameter_overrides:\nString that contains AWS CloudFormation parameter overrides encoded as key=value pairs.\n* debug_port:\nWhen specified, Lambda function container will start in debug mode and will expose this port on localhost.\n* debugger_path:\nHost path to a debugger that will be mounted into the Lambda container.\n* debug_args:\nAdditional arguments to be passed to the debugger.\n* container_env_vars:\nJSON file containing additional environment variables to be set within the container when used in a debugging session locally.\n* docker_volume_basedir:\nSpecify the location basedir where the SAM template exists. If Docker is running on a remote machine, Path of the SAM template must be mounted on the Docker machine and modified to match the remote machine.\n* log_file:\nFile to capture output logs.\n* layer_cache_basedir:\nSpecify the location basedir where the lambda layers used by the template will be downloaded to.\n* skip_pull_image:\nSkip pulling down the latest Docker image for Lambda runtime.\n* docker_network:\nName or ID of an existing docker network for AWS Lambda docker containers to connect to, along with the default bridge network. If not specified, the Lambda containers will only connect to the default bridge docker network.\n* force_image_build:\nForce rebuilding the image used for invoking functions with layers.\n* shutdown:\nEmulate a shutdown event after invoke completes, to test extension handling of shutdown behavior.\n* container_host:\nHost of locally emulated Lambda container. This option is useful when the container runs on a different host than AWS SAM CLI. For example, if one wants to run AWS SAM CLI in a Docker container on macOS, this option could specify `host.docker.internal`\n* container_host_interface:\nIP address of the host network interface that container ports should bind to. Use 0.0.0.0 to bind to all interfaces.\n* add_host:\nPasses a hostname to IP address mapping to the Docker container's host file. This parameter can be passed multiple times.Example:--add-host example.com:127.0.0.1\n* container_dns:\nSet custom DNS servers for the Lambda container. This parameter can be passed multiple times to specify multiple DNS servers. Example: --container-dns 8.8.8.8 --container-dns 1.1.1.1\n* invoke_image:\nContainer image URIs for invoking functions or starting api and function. One can specify the image URI used for the local function invocation (--invoke-image public.ecr.aws/sam/build-nodejs20.x:latest). One can also specify for each individual function with (--invoke-image Function1=public.ecr.aws/sam/build-nodejs20.x:latest). If a function does not have invoke image specified, the default AWS SAM CLI emulation image will be used.\n* no_memory_limit:\nRemoves the Memory limit during emulation. With this parameter, the underlying container will run without a --memory parameter\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* profile:\nSelect a specific profile from your credential file to get AWS credentials.\n* region:\nSet the AWS Region of the service. (e.g. us-east-1)\n* save_params:\nSave the parameters provided via the command line to the configuration file.", "type": "object", "properties": { "terraform_plan_file": { @@ -530,10 +528,9 @@ "runtime": { "title": "runtime", "type": "string", - "description": "Lambda runtime used to invoke the function.\n\nRuntimes: dotnet10, dotnet8, dotnet6, go1.x, java25, java21, java17, java11, java8.al2, nodejs24.x, nodejs22.x, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.14, python3.13, python3.12, python3.11, python3.10, ruby3.4, ruby3.3, ruby3.2", + "description": "Lambda runtime used to invoke the function.\n\nRuntimes: dotnet10, dotnet8, go1.x, java25, java21, java17, java11, java8.al2, nodejs24.x, nodejs22.x, nodejs20.x, nodejs18.x, nodejs16.x, provided, provided.al2, provided.al2023, python3.9, python3.8, python3.14, python3.13, python3.12, python3.11, python3.10, ruby3.4, ruby3.3, ruby3.2", "enum": [ "dotnet10", - "dotnet6", "dotnet8", "go1.x", "java11", diff --git a/tests/end_to_end/test_runtimes_e2e.py b/tests/end_to_end/test_runtimes_e2e.py index 6182c05bf37..98d6e5a352a 100644 --- a/tests/end_to_end/test_runtimes_e2e.py +++ b/tests/end_to_end/test_runtimes_e2e.py @@ -69,7 +69,6 @@ def validate(self, command_result: CommandResult): @parameterized_class( ("runtime", "dependency_manager"), [ - ("dotnet6", "cli-package"), ("python3.11", "pip"), ], ) @@ -103,7 +102,6 @@ def test_hello_world_default_workflow(self): @parameterized_class( ("runtime", "dependency_manager"), [ - ("dotnet6", "cli-package"), ("python3.11", "pip"), ], ) @@ -141,7 +139,6 @@ def test_hello_world_workflow(self): @parameterized_class( ("runtime", "dependency_manager"), [ - ("dotnet6", "cli-package"), ("python3.11", "pip"), ], ) diff --git a/tests/integration/buildcmd/test_build_cmd.py b/tests/integration/buildcmd/test_build_cmd.py index d857e40a4ed..92b606c2324 100644 --- a/tests/integration/buildcmd/test_build_cmd.py +++ b/tests/integration/buildcmd/test_build_cmd.py @@ -1041,13 +1041,6 @@ class TestBuildWithDedupBuilds(DedupBuildIntegBase): @parameterized.expand( [ # in process - ( - False, - "Dotnet6", - "HelloWorld::HelloWorld.FirstFunction::FunctionHandler", - "HelloWorld::HelloWorld.SecondFunction::FunctionHandler", - "dotnet6", - ), ( False, "Java/gradlew/8", @@ -1173,13 +1166,6 @@ class TestBuildWithCacheBuilds(CachedBuildIntegBase): @parameterized.expand( [ # in process - ( - False, - "Dotnet6", - "HelloWorld::HelloWorld.FirstFunction::FunctionHandler", - "HelloWorld::HelloWorld.SecondFunction::FunctionHandler", - "dotnet6", - ), ( False, "Java/gradlew/8", @@ -1365,13 +1351,6 @@ class TestParallelBuilds(DedupBuildIntegBase): @parameterized.expand( [ # in process - ( - False, - "Dotnet6", - "HelloWorld::HelloWorld.FirstFunction::FunctionHandler", - "HelloWorld::HelloWorld.SecondFunction::FunctionHandler", - "dotnet6", - ), ( False, "Java/gradlew/8", diff --git a/tests/integration/buildcmd/test_build_cmd_dotnet.py b/tests/integration/buildcmd/test_build_cmd_dotnet.py index 6b02bc5b14a..edb6fb67724 100644 --- a/tests/integration/buildcmd/test_build_cmd_dotnet.py +++ b/tests/integration/buildcmd/test_build_cmd_dotnet.py @@ -58,31 +58,6 @@ def test_dotnet_al2(self, runtime, code_uri, mode, mount_mode): self.validate_build_artifacts(self.EXPECTED_FILES_PROJECT_MANIFEST_PROVIDED) self.validate_invoke_command(overrides, runtime) - @parameterized.expand( - [ - ("dotnet6", "Dotnet6", None, None), - ("dotnet6", "Dotnet6", None, MountMode.WRITE), - ("dotnet6", "Dotnet6", "debug", None), - ("dotnet6", "Dotnet6", "debug", MountMode.WRITE), - ] - ) - def test_dotnet_6(self, runtime, code_uri, mode, mount_mode): - if mount_mode and SKIP_DOCKER_TESTS or SKIP_DOCKER_BUILD: - self.skipTest(SKIP_DOCKER_MESSAGE) - - overrides = { - "Runtime": runtime, - "CodeUri": code_uri, - "Handler": "HelloWorld::HelloWorld.Function::FunctionHandler", - "Architectures": "x86_64", - } - - self.validate_build_command(overrides, mode, mount_mode) - self.validate_build_artifacts(self.EXPECTED_FILES_PROJECT_MANIFEST) - - if not SKIP_DOCKER_TESTS: - self.validate_invoke_command(overrides, runtime) - @parameterized.expand( [ ("dotnet8", "Dotnet8", None, None), @@ -160,24 +135,6 @@ def test_dotnet_al2_in_container(self, runtime, code_uri, mode): self.validate_build_artifacts(self.EXPECTED_FILES_PROJECT_MANIFEST_PROVIDED) self.validate_invoke_command(overrides, runtime) - @parameterized.expand( - [ - ("dotnet6", "Dotnet6", None), - ("dotnet6", "Dotnet6", "debug"), - ] - ) - def test_dotnet_6_in_container(self, runtime, code_uri, mode): - overrides = { - "Runtime": runtime, - "CodeUri": code_uri, - "Handler": "HelloWorld::HelloWorld.Function::FunctionHandler", - "Architectures": "x86_64", - } - - self.validate_build_command(overrides, mode, use_container=True, input="y") - self.validate_build_artifacts(self.EXPECTED_FILES_PROJECT_MANIFEST) - self.validate_invoke_command(overrides, runtime) - @parameterized.expand( [ ("dotnet8", "Dotnet8", None), @@ -200,7 +157,7 @@ def test_dotnet_al2023_in_container(self, runtime, code_uri, mode): self.validate_build_artifacts(self.EXPECTED_FILES_PROJECT_MANIFEST) self.validate_invoke_command(overrides, runtime) - @parameterized.expand([("dotnet6", "Dotnet6"), ("dotnet8", "Dotnet8")]) + @parameterized.expand([("dotnet8", "Dotnet8")]) def test_must_fail_in_container_mount_without_write_interactive(self, runtime, code_uri): use_container = True overrides = { diff --git a/tests/unit/commands/buildcmd/test_utils.py b/tests/unit/commands/buildcmd/test_utils.py index 2784f7c78c6..876bff750f1 100644 --- a/tests/unit/commands/buildcmd/test_utils.py +++ b/tests/unit/commands/buildcmd/test_utils.py @@ -16,8 +16,8 @@ class TestBuildUtils(TestCase): def test_must_prompt_for_layer(self, prompt_mock): base_dir = "/mybase" - # dotnet6 need write permissions - metadata1 = {"BuildMethod": "dotnet6"} + # dotnet8 need write permissions + metadata1 = {"BuildMethod": "dotnet8"} metadata2 = {"BuildMethod": "python3.8"} layer1 = LayerVersion( "layer1", @@ -85,7 +85,7 @@ def test_must_prompt_for_function(self, prompt_mock): function_id="function_id", name="logical_id", functionname="function_name", - runtime="dotnet6", + runtime="dotnet8", memory=1234, timeout=12, handler="handler", @@ -187,7 +187,7 @@ def test_must_not_prompt_for_image_function(self, prompt_mock): function_id="function_id", name="logical_id", functionname="function_name", - runtime="dotnet6", + runtime="dotnet8", memory=1234, timeout=12, handler="handler", diff --git a/tests/unit/commands/init/test_cli.py b/tests/unit/commands/init/test_cli.py index 3b7ad9b4dfa..92d890d75d3 100644 --- a/tests/unit/commands/init/test_cli.py +++ b/tests/unit/commands/init/test_cli.py @@ -2181,7 +2181,8 @@ def test_init_cli_must_not_generate_default_hello_world_app( def test_must_return_runtime_from_base_image_name(self): base_images = [ - "amazon/dotnet6-base", + "amazon/dotnet10-base", + "amazon/dotnet8-base", "amazon/go1.x-base", "amazon/java11-base", "amazon/nodejs20.x-base", @@ -2191,7 +2192,8 @@ def test_must_return_runtime_from_base_image_name(self): ] expected_runtime = [ - "dotnet6", + "dotnet10", + "dotnet8", "go1.x", "java11", "nodejs20.x", @@ -2230,18 +2232,6 @@ def test_must_process_manifest(self, _get_manifest_mock): preprocess_manifest = template.get_preprocessed_manifest() expected_result = { "Hello World Example": { - "dotnet6": { - "Zip": [ - { - "directory": "dotnet6/cookiecutter-aws-sam-hello-dotnet", - "displayName": "Hello World Example", - "dependencyManager": "cli-package", - "appTemplate": "hello-world", - "packageType": "Zip", - "useCaseName": "Hello World Example", - } - ] - }, "go1.x": { "Zip": [ { @@ -2837,12 +2827,12 @@ def test_init_cli_generate_app_template_from_local_cli_templates( # WHEN the user follows interactive init prompts # 1: AWS Quick Start Templates - # 2: Java 11 + # 4: Java 11 (shifted after dotnet6 removal and dotnet10/dotnet8 addition) # test-project: response to name user_input = """ 1 N -3 +4 2 N N diff --git a/tests/unit/commands/init/test_manifest.json b/tests/unit/commands/init/test_manifest.json index 05a3938ddaa..6e35651b73c 100644 --- a/tests/unit/commands/init/test_manifest.json +++ b/tests/unit/commands/init/test_manifest.json @@ -1,14 +1,4 @@ { - "dotnet6": [ - { - "directory": "dotnet6/cookiecutter-aws-sam-hello-dotnet", - "displayName": "Hello World Example", - "dependencyManager": "cli-package", - "appTemplate": "hello-world", - "packageType": "Zip", - "useCaseName": "Hello World Example" - } - ], "go1.x": [ { "directory": "go1.x/cookiecutter-aws-sam-hello-golang", diff --git a/tests/unit/lib/build_module/test_app_builder.py b/tests/unit/lib/build_module/test_app_builder.py index bbb41732009..d8fa8cd54d3 100644 --- a/tests/unit/lib/build_module/test_app_builder.py +++ b/tests/unit/lib/build_module/test_app_builder.py @@ -520,6 +520,7 @@ def test_must_raise_for_functions_with_multi_architecture( ("nodejs14.x",), ("dotnetcore2.1",), ("dotnetcore3.1",), + ("dotnet6",), ] ) def test_deprecated_runtimes(self, runtime): diff --git a/tests/unit/lib/build_module/test_workflow_config.py b/tests/unit/lib/build_module/test_workflow_config.py index fae35f0127b..b7e56dfdfad 100644 --- a/tests/unit/lib/build_module/test_workflow_config.py +++ b/tests/unit/lib/build_module/test_workflow_config.py @@ -74,7 +74,7 @@ def test_must_work_for_provided_with_build_method_dotnet7(self, runtime): self.assertIn(Event("BuildWorkflowUsed", "dotnet-cli-package"), EventTracker.get_tracked_events()) self.assertTrue(result.must_mount_with_write_in_container) - @parameterized.expand([("dotnet6",), ("provided.al2", "dotnet7")]) + @parameterized.expand([("provided.al2", "dotnet7")]) def test_must_mount_with_write_for_dotnet_in_container(self, runtime, specified_workflow=None): result = get_workflow_config(runtime, self.code_dir, self.project_dir, specified_workflow) self.assertTrue(result.must_mount_with_write_in_container) diff --git a/tests/unit/lib/utils/test_architecture.py b/tests/unit/lib/utils/test_architecture.py index b97183862b8..843a2b41837 100644 --- a/tests/unit/lib/utils/test_architecture.py +++ b/tests/unit/lib/utils/test_architecture.py @@ -44,7 +44,8 @@ def test_validate_architecture_errors(self, value): [ ("nodejs20.x", X86_64, ZIP), ("java8.al2", ARM64, ZIP), - ("dotnet6", ARM64, ZIP), + ("dotnet8", ARM64, ZIP), + ("dotnet10", ARM64, ZIP), (None, X86_64, IMAGE), (None, ARM64, IMAGE), (None, X86_64, IMAGE), diff --git a/tests/unit/local/docker/test_lambda_image.py b/tests/unit/local/docker/test_lambda_image.py index 587fc4ecbaa..ab6ae7e6b66 100644 --- a/tests/unit/local/docker/test_lambda_image.py +++ b/tests/unit/local/docker/test_lambda_image.py @@ -32,7 +32,6 @@ class TestRuntime(TestCase): ("java17", "java:17-x86_64"), ("java21", "java:21-x86_64"), ("go1.x", "go:1"), - ("dotnet6", "dotnet:6-x86_64"), ("dotnet8", "dotnet:8-x86_64"), ("dotnet10", "dotnet:10-x86_64"), ("provided", "provided:alami"), From 176da490f8f322fbf03f0dfe04d8d7894f1890bf Mon Sep 17 00:00:00 2001 From: Stephen Liedig Date: Mon, 13 Apr 2026 09:53:25 +0800 Subject: [PATCH 2/2] docs: update DEVELOPMENT_GUIDE.md Python version references from 3.8 to 3.10 The minimum supported Python version is now 3.10 per pyproject.toml. Updated all examples, pyenv virtualenv names, and version references accordingly. Also corrected setup.py reference to pyproject.toml. --- DEVELOPMENT_GUIDE.md | 46 ++++++++++++++++++++++---------------------- 1 file changed, 23 insertions(+), 23 deletions(-) diff --git a/DEVELOPMENT_GUIDE.md b/DEVELOPMENT_GUIDE.md index 0ddf50a9386..ae76f86c2be 100644 --- a/DEVELOPMENT_GUIDE.md +++ b/DEVELOPMENT_GUIDE.md @@ -20,7 +20,7 @@ Gitpod is free for 50 hours per month - make sure to stop your workspace when yo ## Environment Setup ### 1. Prerequisites (Python Virtual Environment) -AWS SAM CLI is mainly written in Python 3 and we support Python 3.8 and above. +AWS SAM CLI is mainly written in Python 3 and we support Python 3.10 and above. So, having a Python environment with this version is required. Having a dedicated Python virtual environment ensures it won't "pollute" or get "polluted" @@ -64,10 +64,10 @@ exec $SHELL # restart your shell to enable pyenv-virtualenv Next, setup a virtual environment and activate it: ```sh -# Assuming you want to develop AWS SAM CLI in Python 3.8.9 -pyenv install 3.8.9 # install Python 3.8.9 using pyenv -pyenv virtualenv 3.8.9 samcli38 # create a virtual environment using 3.8.9 named "samcli38" -pyenv activate samcli38 # activate the virtual environment +# Assuming you want to develop AWS SAM CLI in Python 3.12 +pyenv install 3.12 # install Python 3.12 using pyenv +pyenv virtualenv 3.12 samcli312 # create a virtual environment using 3.12 named "samcli312" +pyenv activate samcli312 # activate the virtual environment ``` ### 2. Initialize dependencies and create `samdev` available in `$PATH` @@ -142,7 +142,7 @@ Make sure you are in the same virtual environment as the one you are using with ```sh source /.venv/bin/activate # if you chose to use venv to setup the virtual environment # or -pyenv activate samcli38 # if you chose to use pyenv to setup the virtual environment +pyenv activate samcli312 # if you chose to use pyenv to setup the virtual environment ``` Install the SAM Transformer in editable mode so that @@ -173,27 +173,27 @@ contribute to the repository, there are a few more things to consider. ### Make Sure AWS SAM CLI Work in Multiple Python Versions -We support version 3.8 and above. Our CI/CD pipeline is setup to run +We support version 3.10 and above. Our CI/CD pipeline is setup to run unit tests against all Python versions. So make sure you test it with all versions before sending a Pull Request. See [Unit testing with multiple Python versions](#unit-testing-with-multiple-python-versions-optional). -This is most important if you are developing in a Python version greater than the minimum supported version (currently 3.8), as any new features released in 3.9+ will not work. +This is most important if you are developing in a Python version greater than the minimum supported version (currently 3.10), as any new features released in 3.11+ will not work. If you chose to use `pyenv` in the previous session, setting up a different Python version should be easy: -(assuming you are in virtual environment named `samcli39` with Python version 3.9.x) +(assuming you are in virtual environment named `samcli312` with Python version 3.12.x) ```sh -# Your shell now should look like "(samcli39) $" -pyenv deactivate samcli39 # "(samcli39)" will disappear -pyenv install 3.8.9 # one time setup -pyenv virtualenv 3.8.9 samcli38 # one time setup -pyenv activate samcli38 -# Your shell now should look like "(samcli38) $" +# Your shell now should look like "(samcli312) $" +pyenv deactivate samcli312 # "(samcli312)" will disappear +pyenv install 3.10 # one time setup +pyenv virtualenv 3.10 samcli310 # one time setup +pyenv activate samcli310 +# Your shell now should look like "(samcli310) $" # You can verify the version of Python -python --version # Python 3.8.9 +python --version # Python 3.10.x make init # one time setup, this will put a file `samdev` available in $PATH ``` @@ -235,11 +235,11 @@ and this will happen: pyenv: black: command not found The `black' command exists in these Python versions: - 3.8.9/envs/samcli38 - samcli38 + 3.12/envs/samcli312 + samcli312 ``` -A simple workaround is to use `/Users//.pyenv/versions/samcli37/bin/black` +A simple workaround is to use `/Users//.pyenv/versions/samcli312/bin/black` instead of `/Users//.pyenv/shims/black`. #### (Option 3) Pre-commit @@ -265,10 +265,10 @@ We also suggest to run `make pr` or `./Make -pr` in all Python versions. #### Unit Testing with Multiple Python Versions (Optional) -Currently, SAM CLI only supports Python3 versions (see setup.py for exact versions). For the most -part, code that works in Python3.8 will work in Python3.9. You only run into problems if you are -trying to use features released in a higher version (for example features introduced into Python3.9 -will not work in Python3.8). If you want to test in many versions, you can create a virtualenv for +Currently, SAM CLI only supports Python3 versions (see pyproject.toml for exact versions). For the most +part, code that works in Python3.10 will work in Python3.11. You only run into problems if you are +trying to use features released in a higher version (for example features introduced into Python3.11 +will not work in Python3.10). If you want to test in many versions, you can create a virtualenv for each version and flip between them (sourcing the activate script). Typically, we run all tests in one python version locally and then have our ci (appveyor) run all supported versions.