Skip to content

Commit 33e7cab

Browse files
Merge branch 'develop'
2 parents 5ba3210 + 4e128b2 commit 33e7cab

File tree

10 files changed

+183
-91
lines changed

10 files changed

+183
-91
lines changed

.github/workflows/build.yml

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,10 @@ on:
1111
- develop
1212
- "feat*"
1313

14+
concurrency:
15+
group: ${{ github.ref }}
16+
cancel-in-progress: true
17+
1418
jobs:
1519
run-workflow:
1620
name: PR Workflow
@@ -264,7 +268,7 @@ jobs:
264268
- run: pytest -vv tests/integration/workflows/python_pip
265269

266270
ruby-integration:
267-
name: ${{ matrix.os }} / ${{ matrix.python }} / ruby-${{ matrix.ruby }}
271+
name: ${{ matrix.os }} / ${{ matrix.python }} / ruby
268272
if: github.repository_owner == 'aws'
269273
runs-on: ${{ matrix.os }}
270274
strategy:
@@ -278,17 +282,17 @@ jobs:
278282
- "3.8"
279283
- "3.9"
280284
- "3.10"
281-
ruby:
282-
- "3.1"
283-
- "2.7"
284285
steps:
285286
- uses: actions/checkout@v3
286287
- uses: actions/setup-python@v4
287288
with:
288289
python-version: ${{ matrix.python }}
289290
- uses: ruby/setup-ruby@v1
290291
with:
291-
ruby-version: ${{ matrix.ruby }}
292+
ruby-version: "3.2"
293+
- uses: ruby/setup-ruby@v1
294+
with:
295+
ruby-version: "2.7"
292296
- run: make init
293297
- run: pytest -vv tests/integration/workflows/ruby_bundler
294298

Makefile

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,9 @@ lint:
2020
# Liner performs static analysis to catch latent bugs
2121
ruff aws_lambda_builders
2222

23+
lint-fix:
24+
ruff aws_lambda_builders --fix
25+
2326
# Command to run everytime you make changes to verify everything works
2427
dev: lint test
2528

@@ -31,3 +34,5 @@ black-check:
3134

3235
# Verifications to run before sending a pull request
3336
pr: init dev black-check
37+
38+
format: lint-fix black

aws_lambda_builders/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,5 +4,5 @@
44

55
# Changing version will trigger a new release!
66
# Please make the version change as the last step of your development.
7-
__version__ = "1.31.0"
7+
__version__ = "1.32.0"
88
RPC_PROTOCOL_VERSION = "0.3"

aws_lambda_builders/validator.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
"python3.9": [ARM64, X86_64],
2020
"python3.10": [ARM64, X86_64],
2121
"ruby2.7": [ARM64, X86_64],
22+
"ruby3.2": [ARM64, X86_64],
2223
"java8": [ARM64, X86_64],
2324
"java11": [ARM64, X86_64],
2425
"java17": [ARM64, X86_64],

aws_lambda_builders/workflows/dotnet_clipackage/actions.py

Lines changed: 27 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@
77
import threading
88

99
from aws_lambda_builders.actions import ActionFailedError, BaseAction, Purpose
10-
from aws_lambda_builders.architecture import ARM64
10+
from aws_lambda_builders.architecture import ARM64, X86_64
1111
from aws_lambda_builders.workflow import BuildMode
1212

1313
from .dotnetcli import DotnetCLIExecutionError
@@ -62,13 +62,35 @@ def execute(self):
6262
class RunPackageAction(BaseAction):
6363
"""
6464
A Lambda Builder Action which builds the .NET Core project using the Amazon.Lambda.Tools .NET Core Global Tool
65+
66+
:param source_dir: str
67+
Path to a folder containing the source code
68+
69+
:param subprocess_dotnet:
70+
An instance of the dotnet process wrapper
71+
72+
:param artifacts_dir: str
73+
Path to a folder where the built artifacts should be placed
74+
75+
:param options:
76+
Dictionary of options ot pass to build action
77+
78+
:param mode: str
79+
Mode the build should produce
80+
81+
:param architecture: str
82+
Architecture to build for. Default value is X86_64 which is consistent with Amazon Lambda Tools
83+
84+
:param os_utils:
85+
Optional, OS utils
86+
6587
"""
6688

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

71-
def __init__(self, source_dir, subprocess_dotnet, artifacts_dir, options, mode, architecture=None, os_utils=None):
93+
def __init__(self, source_dir, subprocess_dotnet, artifacts_dir, options, mode, architecture=X86_64, os_utils=None):
7294
super(RunPackageAction, self).__init__()
7395
self.source_dir = source_dir
7496
self.subprocess_dotnet = subprocess_dotnet
@@ -90,6 +112,9 @@ def execute(self):
90112
"package",
91113
"--output-package",
92114
zipfullpath,
115+
# Pass function architecture to Amazon Lambda Tools.
116+
"--function-architecture",
117+
self.architecture,
93118
# Specify the architecture with the --runtime MSBuild parameter
94119
"--msbuild-parameters",
95120
"--runtime " + self._get_runtime(),

aws_lambda_builders/workflows/nodejs_npm_esbuild/esbuild.py

Lines changed: 86 additions & 70 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
"""
44
import logging
55
from pathlib import Path
6-
from typing import Any, Dict, List
6+
from typing import Any, Callable, Dict, List, Union
77

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

101101

102-
# The esbuild API flags are broken up into three forms (https://esbuild.github.io/api/):
103-
# Multi-word arguments are expected to be passed down using snake case e.g. entry_points
104-
# Boolean types (--minify)
105-
SUPPORTED_ESBUILD_APIS_BOOLEAN = [
106-
"minify",
107-
"sourcemap",
108-
]
109-
110-
# single value types (--target=es2020)
111-
SUPPORTED_ESBUILD_APIS_SINGLE_VALUE = [
112-
"target",
113-
"format",
114-
"main_fields",
115-
"sources_content",
116-
]
117-
118-
# Multi-value types (--external:axios --external:aws-sdk)
119-
SUPPORTED_ESBUILD_APIS_MULTI_VALUE = [
120-
"external",
121-
"loader",
122-
"out_extension",
123-
]
102+
NON_CONFIGURABLE_VALUES = {"bundle", "platform", "outdir"}
124103

125104

126105
class EsbuildCommandBuilder:
@@ -154,15 +133,96 @@ def build_esbuild_args_from_config(self) -> "EsbuildCommandBuilder":
154133
"""
155134
args = []
156135

157-
args.extend(self._get_boolean_args())
158-
args.extend(self._get_single_value_args())
159-
args.extend(self._get_multi_value_args())
136+
for config_key, config_value in self._bundler_config.items():
137+
if config_key in NON_CONFIGURABLE_VALUES:
138+
LOG.debug(
139+
"'%s=%s' was not a used configuration since AWS Lambda Builders "
140+
"sets these values for the code to be correctly consumed by AWS Lambda",
141+
config_key,
142+
config_value,
143+
)
144+
continue
145+
if config_key == "entry_points":
146+
# Entry points are a required parameter and are handled by the build_entry_points() method
147+
continue
148+
configuration_type_callback = self._get_config_type_callback(config_value)
149+
LOG.debug("Configuring the parameter '%s=%s'", config_key, config_value)
150+
args.extend(configuration_type_callback(config_key, config_value))
160151

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

163154
self._command.extend(args)
164155
return self
165156

157+
def _get_config_type_callback(
158+
self, config_value: Union[bool, str, list]
159+
) -> Callable[[str, Union[bool, str, list]], List[str]]:
160+
"""
161+
Determines the type of the command and returns the corresponding
162+
function to build out that command line argument type
163+
164+
:param config_value: Union[bool, str, list]
165+
The configuration value configured through the options. The configuration should be one
166+
of the supported types as defined by the esbuild API (https://esbuild.github.io/api/).
167+
:return: Callable[[str, Union[bool, str, list]], List[str]]
168+
Returns a function that the caller can use to turn the relevant
169+
configuration into the correctly formatted command line argument.
170+
"""
171+
if isinstance(config_value, bool):
172+
return self._create_boolean_config
173+
elif isinstance(config_value, str):
174+
return self._create_str_config
175+
elif isinstance(config_value, list):
176+
return self._create_list_config
177+
raise EsbuildCommandError("Failed to determine the type of the configuration: %s", config_value)
178+
179+
def _create_boolean_config(self, config_key: str, config_value: bool) -> List[str]:
180+
"""
181+
Given boolean-type configuration, convert it to a string representation suitable for the esbuild API
182+
Should be created in the form ([--config-key])
183+
184+
:param config_key: str
185+
The configuration key to be used
186+
:param config_value: bool
187+
The configuration value to be used
188+
:return: List[str]
189+
List of resolved command line arguments to be appended to the builder
190+
"""
191+
if config_value is True:
192+
return [f"--{self._convert_snake_to_kebab_case(config_key)}"]
193+
return []
194+
195+
def _create_str_config(self, config_key: str, config_value: str) -> List[str]:
196+
"""
197+
Given string-type configuration, convert it to a string representation suitable for the esbuild API
198+
Should be created in the form ([--config-key=config_value])
199+
200+
:param config_key: str
201+
The configuration key to be used
202+
:param config_value: List[str]
203+
The configuration value to be used
204+
:return: List[str]
205+
List of resolved command line arguments to be appended to the builder
206+
"""
207+
return [f"--{self._convert_snake_to_kebab_case(config_key)}={config_value}"]
208+
209+
def _create_list_config(self, config_key: str, config_value: List[str]) -> List[str]:
210+
"""
211+
Given list-type configuration, convert it to a string representation suitable for the esbuild API
212+
Should be created in the form ([--config-key:config_value_a, --config_key:config_value_b])
213+
214+
:param config_key: str
215+
The configuration key to be used
216+
:param config_value: List[str]
217+
The configuration value to be used
218+
:return: List[str]
219+
List of resolved command line arguments to be appended to the builder
220+
"""
221+
args = []
222+
for config_item in config_value:
223+
args.append(f"--{self._convert_snake_to_kebab_case(config_key)}:{config_item}")
224+
return args
225+
166226
def build_entry_points(self) -> "EsbuildCommandBuilder":
167227
"""
168228
Build the entry points to the command
@@ -227,50 +287,6 @@ def build_with_no_dependencies(self) -> "EsbuildCommandBuilder":
227287
self._command.extend(args)
228288
return self
229289

230-
def _get_boolean_args(self) -> List[str]:
231-
"""
232-
Get a list of all the boolean value flag types (e.g. --minify)
233-
234-
:rtype: List[str]
235-
:return: Arguments to be appended to the command list
236-
"""
237-
args = []
238-
for param in SUPPORTED_ESBUILD_APIS_BOOLEAN:
239-
if param in self._bundler_config and self._bundler_config[param] is True:
240-
args.append(f"--{self._convert_snake_to_kebab_case(param)}")
241-
return args
242-
243-
def _get_single_value_args(self) -> List[str]:
244-
"""
245-
Get a list of all the single value flag types (e.g. --target=es2020)
246-
247-
:rtype: List[str]
248-
:return: Arguments to be appended to the command list
249-
"""
250-
args = []
251-
for param in SUPPORTED_ESBUILD_APIS_SINGLE_VALUE:
252-
if param in self._bundler_config:
253-
value = self._bundler_config.get(param)
254-
args.append(f"--{self._convert_snake_to_kebab_case(param)}={value}")
255-
return args
256-
257-
def _get_multi_value_args(self) -> List[str]:
258-
"""
259-
Get a list of all the multi-value flag types (e.g. --external:aws-sdk)
260-
261-
:rtype: List[str]
262-
:return: Arguments to be appended to the command list
263-
"""
264-
args = []
265-
for param in SUPPORTED_ESBUILD_APIS_MULTI_VALUE:
266-
if param in self._bundler_config:
267-
values = self._bundler_config.get(param)
268-
if not isinstance(values, list):
269-
raise EsbuildCommandError(f"Invalid type for property {param}, must be a dict.")
270-
for param_item in values:
271-
args.append(f"--{self._convert_snake_to_kebab_case(param)}:{param_item}")
272-
return args
273-
274290
def _get_explicit_file_type(self, entry_point, entry_path):
275291
"""
276292
Get an entry point with an explicit .ts or .js suffix.

requirements/dev.txt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
coverage==7.2.3
1+
coverage==7.2.5
22
flake8==3.3.0; python_version < '3.8'
33
flake8==3.8.4; python_version >= '3.8'
44
pytest-cov==4.0.0
@@ -12,4 +12,4 @@ pyelftools~=0.29 # Used to verify the generated Go binary architecture in integr
1212

1313
# formatter
1414
black==23.3.0
15-
ruff==0.0.261
15+
ruff==0.0.269

tests/integration/workflows/ruby_bundler/test_ruby.py

Lines changed: 11 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
from unittest import TestCase, mock
66

7+
from parameterized import parameterized_class
8+
79
from aws_lambda_builders.builder import LambdaBuilder
810
from aws_lambda_builders.exceptions import WorkflowFailedError
911

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

1517

18+
@parameterized_class(
19+
("runtime",),
20+
[
21+
("ruby2.7",),
22+
("ruby3.2",),
23+
],
24+
)
1625
class TestRubyWorkflow(TestCase):
1726
"""
1827
Verifies that `ruby` workflow works by building a Lambda using Bundler
1928
"""
2029

30+
runtime = ""
31+
2132
TEST_DATA_FOLDER = os.path.join(os.path.dirname(__file__), "testdata")
2233

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

3141
def tearDown(self):
3242
shutil.rmtree(self.artifacts_dir)

0 commit comments

Comments
 (0)