Skip to content

Commit

Permalink
Merge branch 'develop'
Browse files Browse the repository at this point in the history
  • Loading branch information
aws-sam-cli-bot committed May 25, 2023
2 parents 5ba3210 + 4e128b2 commit 33e7cab
Show file tree
Hide file tree
Showing 10 changed files with 183 additions and 91 deletions.
14 changes: 9 additions & 5 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,10 @@ on:
- develop
- "feat*"

concurrency:
group: ${{ github.ref }}
cancel-in-progress: true

jobs:
run-workflow:
name: PR Workflow
Expand Down Expand Up @@ -264,7 +268,7 @@ jobs:
- run: pytest -vv tests/integration/workflows/python_pip

ruby-integration:
name: ${{ matrix.os }} / ${{ matrix.python }} / ruby-${{ matrix.ruby }}
name: ${{ matrix.os }} / ${{ matrix.python }} / ruby
if: github.repository_owner == 'aws'
runs-on: ${{ matrix.os }}
strategy:
Expand All @@ -278,17 +282,17 @@ jobs:
- "3.8"
- "3.9"
- "3.10"
ruby:
- "3.1"
- "2.7"
steps:
- uses: actions/checkout@v3
- uses: actions/setup-python@v4
with:
python-version: ${{ matrix.python }}
- uses: ruby/setup-ruby@v1
with:
ruby-version: ${{ matrix.ruby }}
ruby-version: "3.2"
- uses: ruby/setup-ruby@v1
with:
ruby-version: "2.7"
- run: make init
- run: pytest -vv tests/integration/workflows/ruby_bundler

Expand Down
5 changes: 5 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,9 @@ lint:
# Liner performs static analysis to catch latent bugs
ruff aws_lambda_builders

lint-fix:
ruff aws_lambda_builders --fix

# Command to run everytime you make changes to verify everything works
dev: lint test

Expand All @@ -31,3 +34,5 @@ black-check:

# Verifications to run before sending a pull request
pr: init dev black-check

format: lint-fix black
2 changes: 1 addition & 1 deletion aws_lambda_builders/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,5 +4,5 @@

# Changing version will trigger a new release!
# Please make the version change as the last step of your development.
__version__ = "1.31.0"
__version__ = "1.32.0"
RPC_PROTOCOL_VERSION = "0.3"
1 change: 1 addition & 0 deletions aws_lambda_builders/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
"python3.9": [ARM64, X86_64],
"python3.10": [ARM64, X86_64],
"ruby2.7": [ARM64, X86_64],
"ruby3.2": [ARM64, X86_64],
"java8": [ARM64, X86_64],
"java11": [ARM64, X86_64],
"java17": [ARM64, X86_64],
Expand Down
29 changes: 27 additions & 2 deletions aws_lambda_builders/workflows/dotnet_clipackage/actions.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
import threading

from aws_lambda_builders.actions import ActionFailedError, BaseAction, Purpose
from aws_lambda_builders.architecture import ARM64
from aws_lambda_builders.architecture import ARM64, X86_64
from aws_lambda_builders.workflow import BuildMode

from .dotnetcli import DotnetCLIExecutionError
Expand Down Expand Up @@ -62,13 +62,35 @@ def execute(self):
class RunPackageAction(BaseAction):
"""
A Lambda Builder Action which builds the .NET Core project using the Amazon.Lambda.Tools .NET Core Global Tool
:param source_dir: str
Path to a folder containing the source code
:param subprocess_dotnet:
An instance of the dotnet process wrapper
:param artifacts_dir: str
Path to a folder where the built artifacts should be placed
:param options:
Dictionary of options ot pass to build action
:param mode: str
Mode the build should produce
:param architecture: str
Architecture to build for. Default value is X86_64 which is consistent with Amazon Lambda Tools
:param os_utils:
Optional, OS utils
"""

NAME = "RunPackageAction"
DESCRIPTION = "Execute the `dotnet lambda package` command."
PURPOSE = Purpose.COMPILE_SOURCE

def __init__(self, source_dir, subprocess_dotnet, artifacts_dir, options, mode, architecture=None, os_utils=None):
def __init__(self, source_dir, subprocess_dotnet, artifacts_dir, options, mode, architecture=X86_64, os_utils=None):
super(RunPackageAction, self).__init__()
self.source_dir = source_dir
self.subprocess_dotnet = subprocess_dotnet
Expand All @@ -90,6 +112,9 @@ def execute(self):
"package",
"--output-package",
zipfullpath,
# Pass function architecture to Amazon Lambda Tools.
"--function-architecture",
self.architecture,
# Specify the architecture with the --runtime MSBuild parameter
"--msbuild-parameters",
"--runtime " + self._get_runtime(),
Expand Down
156 changes: 86 additions & 70 deletions aws_lambda_builders/workflows/nodejs_npm_esbuild/esbuild.py
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
"""
import logging
from pathlib import Path
from typing import Any, Dict, List
from typing import Any, Callable, Dict, List, Union

from aws_lambda_builders.actions import ActionFailedError
from aws_lambda_builders.workflows.nodejs_npm.utils import OSUtils
Expand Down Expand Up @@ -99,28 +99,7 @@ def run(self, args, cwd=None):
return out.decode("utf8").strip()


# The esbuild API flags are broken up into three forms (https://esbuild.github.io/api/):
# Multi-word arguments are expected to be passed down using snake case e.g. entry_points
# Boolean types (--minify)
SUPPORTED_ESBUILD_APIS_BOOLEAN = [
"minify",
"sourcemap",
]

# single value types (--target=es2020)
SUPPORTED_ESBUILD_APIS_SINGLE_VALUE = [
"target",
"format",
"main_fields",
"sources_content",
]

# Multi-value types (--external:axios --external:aws-sdk)
SUPPORTED_ESBUILD_APIS_MULTI_VALUE = [
"external",
"loader",
"out_extension",
]
NON_CONFIGURABLE_VALUES = {"bundle", "platform", "outdir"}


class EsbuildCommandBuilder:
Expand Down Expand Up @@ -154,15 +133,96 @@ def build_esbuild_args_from_config(self) -> "EsbuildCommandBuilder":
"""
args = []

args.extend(self._get_boolean_args())
args.extend(self._get_single_value_args())
args.extend(self._get_multi_value_args())
for config_key, config_value in self._bundler_config.items():
if config_key in NON_CONFIGURABLE_VALUES:
LOG.debug(
"'%s=%s' was not a used configuration since AWS Lambda Builders "
"sets these values for the code to be correctly consumed by AWS Lambda",
config_key,
config_value,
)
continue
if config_key == "entry_points":
# Entry points are a required parameter and are handled by the build_entry_points() method
continue
configuration_type_callback = self._get_config_type_callback(config_value)
LOG.debug("Configuring the parameter '%s=%s'", config_key, config_value)
args.extend(configuration_type_callback(config_key, config_value))

LOG.debug("Found the following args in the config: %s", str(args))

self._command.extend(args)
return self

def _get_config_type_callback(
self, config_value: Union[bool, str, list]
) -> Callable[[str, Union[bool, str, list]], List[str]]:
"""
Determines the type of the command and returns the corresponding
function to build out that command line argument type
:param config_value: Union[bool, str, list]
The configuration value configured through the options. The configuration should be one
of the supported types as defined by the esbuild API (https://esbuild.github.io/api/).
:return: Callable[[str, Union[bool, str, list]], List[str]]
Returns a function that the caller can use to turn the relevant
configuration into the correctly formatted command line argument.
"""
if isinstance(config_value, bool):
return self._create_boolean_config
elif isinstance(config_value, str):
return self._create_str_config
elif isinstance(config_value, list):
return self._create_list_config
raise EsbuildCommandError("Failed to determine the type of the configuration: %s", config_value)

def _create_boolean_config(self, config_key: str, config_value: bool) -> List[str]:
"""
Given boolean-type configuration, convert it to a string representation suitable for the esbuild API
Should be created in the form ([--config-key])
:param config_key: str
The configuration key to be used
:param config_value: bool
The configuration value to be used
:return: List[str]
List of resolved command line arguments to be appended to the builder
"""
if config_value is True:
return [f"--{self._convert_snake_to_kebab_case(config_key)}"]
return []

def _create_str_config(self, config_key: str, config_value: str) -> List[str]:
"""
Given string-type configuration, convert it to a string representation suitable for the esbuild API
Should be created in the form ([--config-key=config_value])
:param config_key: str
The configuration key to be used
:param config_value: List[str]
The configuration value to be used
:return: List[str]
List of resolved command line arguments to be appended to the builder
"""
return [f"--{self._convert_snake_to_kebab_case(config_key)}={config_value}"]

def _create_list_config(self, config_key: str, config_value: List[str]) -> List[str]:
"""
Given list-type configuration, convert it to a string representation suitable for the esbuild API
Should be created in the form ([--config-key:config_value_a, --config_key:config_value_b])
:param config_key: str
The configuration key to be used
:param config_value: List[str]
The configuration value to be used
:return: List[str]
List of resolved command line arguments to be appended to the builder
"""
args = []
for config_item in config_value:
args.append(f"--{self._convert_snake_to_kebab_case(config_key)}:{config_item}")
return args

def build_entry_points(self) -> "EsbuildCommandBuilder":
"""
Build the entry points to the command
Expand Down Expand Up @@ -227,50 +287,6 @@ def build_with_no_dependencies(self) -> "EsbuildCommandBuilder":
self._command.extend(args)
return self

def _get_boolean_args(self) -> List[str]:
"""
Get a list of all the boolean value flag types (e.g. --minify)
:rtype: List[str]
:return: Arguments to be appended to the command list
"""
args = []
for param in SUPPORTED_ESBUILD_APIS_BOOLEAN:
if param in self._bundler_config and self._bundler_config[param] is True:
args.append(f"--{self._convert_snake_to_kebab_case(param)}")
return args

def _get_single_value_args(self) -> List[str]:
"""
Get a list of all the single value flag types (e.g. --target=es2020)
:rtype: List[str]
:return: Arguments to be appended to the command list
"""
args = []
for param in SUPPORTED_ESBUILD_APIS_SINGLE_VALUE:
if param in self._bundler_config:
value = self._bundler_config.get(param)
args.append(f"--{self._convert_snake_to_kebab_case(param)}={value}")
return args

def _get_multi_value_args(self) -> List[str]:
"""
Get a list of all the multi-value flag types (e.g. --external:aws-sdk)
:rtype: List[str]
:return: Arguments to be appended to the command list
"""
args = []
for param in SUPPORTED_ESBUILD_APIS_MULTI_VALUE:
if param in self._bundler_config:
values = self._bundler_config.get(param)
if not isinstance(values, list):
raise EsbuildCommandError(f"Invalid type for property {param}, must be a dict.")
for param_item in values:
args.append(f"--{self._convert_snake_to_kebab_case(param)}:{param_item}")
return args

def _get_explicit_file_type(self, entry_point, entry_path):
"""
Get an entry point with an explicit .ts or .js suffix.
Expand Down
4 changes: 2 additions & 2 deletions requirements/dev.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
coverage==7.2.3
coverage==7.2.5
flake8==3.3.0; python_version < '3.8'
flake8==3.8.4; python_version >= '3.8'
pytest-cov==4.0.0
Expand All @@ -12,4 +12,4 @@ pyelftools~=0.29 # Used to verify the generated Go binary architecture in integr

# formatter
black==23.3.0
ruff==0.0.261
ruff==0.0.269
12 changes: 11 additions & 1 deletion tests/integration/workflows/ruby_bundler/test_ruby.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,8 @@

from unittest import TestCase, mock

from parameterized import parameterized_class

from aws_lambda_builders.builder import LambdaBuilder
from aws_lambda_builders.exceptions import WorkflowFailedError

Expand All @@ -13,11 +15,20 @@
workflow_logger = logging.getLogger("aws_lambda_builders.workflows.ruby_bundler.workflow")


@parameterized_class(
("runtime",),
[
("ruby2.7",),
("ruby3.2",),
],
)
class TestRubyWorkflow(TestCase):
"""
Verifies that `ruby` workflow works by building a Lambda using Bundler
"""

runtime = ""

TEST_DATA_FOLDER = os.path.join(os.path.dirname(__file__), "testdata")

def setUp(self):
Expand All @@ -26,7 +37,6 @@ def setUp(self):
self.dependencies_dir = tempfile.mkdtemp()
self.no_deps = os.path.join(self.TEST_DATA_FOLDER, "no-deps")
self.builder = LambdaBuilder(language="ruby", dependency_manager="bundler", application_framework=None)
self.runtime = "ruby2.7"

def tearDown(self):
shutil.rmtree(self.artifacts_dir)
Expand Down
Loading

0 comments on commit 33e7cab

Please sign in to comment.