Skip to content

Commit 932cb47

Browse files
authored
fix: use pre-installed Amazon.Lambda.Tools for dotnet6 builds (#899)
* fix: use pre-installed Amazon.Lambda.Tools for dotnet6 builds Amazon.Lambda.Tools 7.0.0 dropped support for net6.0, so installing or updating to latest at build time breaks dotnet6 container builds. For dotnet6, probe for a working tool first (dotnet lambda help) and skip the install/update when one is available - e.g. the version pre-installed in the SAM build image. Local builds without a pre-installed tool keep the existing install behavior. * fix: do not mark tool installed when dotnet6 skips, so other runtimes still update
1 parent dc190e9 commit 932cb47

3 files changed

Lines changed: 60 additions & 2 deletions

File tree

‎aws_lambda_builders/workflows/dotnet_clipackage/actions.py‎

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -28,9 +28,21 @@ class GlobalToolInstallAction(BaseAction):
2828
DESCRIPTION = "Install or update the Amazon.Lambda.Tools .NET Core Global Tool."
2929
PURPOSE = Purpose.COMPILE_SOURCE
3030

31-
def __init__(self, subprocess_dotnet):
31+
def __init__(self, subprocess_dotnet, runtime=None):
3232
super(GlobalToolInstallAction, self).__init__()
3333
self.subprocess_dotnet = subprocess_dotnet
34+
self.runtime = runtime
35+
36+
def _existing_tool_available(self):
37+
"""
38+
Returns True if a working Amazon.Lambda.Tools is already available on the PATH
39+
(e.g. pre-installed in the SAM build image).
40+
"""
41+
try:
42+
self.subprocess_dotnet.run(["lambda", "help"])
43+
return True
44+
except DotnetCLIExecutionError:
45+
return False
3446

3547
def execute(self):
3648
# run Amazon.Lambda.Tools update in sync block in case build is triggered in parallel
@@ -42,6 +54,15 @@ def execute(self):
4254
LOG.info("Skipping to update Amazon.Lambda.Tools install/update, since it is updated recently")
4355
return
4456

57+
# Amazon.Lambda.Tools 7.0.0 dropped support for dotnet6 (EOL runtime), so
58+
# installing/updating to latest breaks dotnet6 builds. If a working tool is
59+
# already available (e.g. pre-installed in the SAM build image), use it as is.
60+
# Deliberately not setting __tools_installed here so other runtimes in the
61+
# same process still install/update to latest as before.
62+
if self.runtime == "dotnet6" and self._existing_tool_available():
63+
LOG.info("Skipping Amazon.Lambda.Tools install/update for dotnet6; using the pre-installed version")
64+
return
65+
4566
try:
4667
LOG.debug("Installing Amazon.Lambda.Tools Global Tool")
4768
self.subprocess_dotnet.run(["tool", "install", "-g", "Amazon.Lambda.Tools", "--ignore-failed-sources"])

‎aws_lambda_builders/workflows/dotnet_clipackage/workflow.py‎

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ def __init__(self, source_dir, artifacts_dir, scratch_dir, manifest_path, runtim
2929

3030
options = kwargs["options"] if "options" in kwargs else {}
3131
subprocess_dotnetcli = SubprocessDotnetCLI(os_utils=OSUtils())
32-
dotnetcli_install = GlobalToolInstallAction(subprocess_dotnet=subprocess_dotnetcli)
32+
dotnetcli_install = GlobalToolInstallAction(subprocess_dotnet=subprocess_dotnetcli, runtime=runtime)
3333

3434
dotnetcli_deployment = RunPackageAction(
3535
source_dir,

‎tests/unit/workflows/dotnet_clipackage/test_actions.py‎

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -62,6 +62,43 @@ def test_global_tool_parallel(self):
6262
["tool", "install", "-g", "Amazon.Lambda.Tools", "--ignore-failed-sources"]
6363
)
6464

65+
def test_dotnet6_skips_install_when_tool_preinstalled(self):
66+
# `dotnet lambda help` succeeds -> a working tool is already available (e.g. SAM build image)
67+
action = GlobalToolInstallAction(self.subprocess_dotnet, runtime="dotnet6")
68+
action.execute()
69+
self.subprocess_dotnet.run.assert_called_once_with(["lambda", "help"])
70+
71+
def test_dotnet6_installs_when_no_tool_preinstalled(self):
72+
# `dotnet lambda help` fails -> no tool available, fall back to normal install
73+
self.subprocess_dotnet.run.side_effect = [DotnetCLIExecutionError(message="No tool"), None]
74+
action = GlobalToolInstallAction(self.subprocess_dotnet, runtime="dotnet6")
75+
action.execute()
76+
self.subprocess_dotnet.run.assert_any_call(["lambda", "help"])
77+
self.subprocess_dotnet.run.assert_any_call(
78+
["tool", "install", "-g", "Amazon.Lambda.Tools", "--ignore-failed-sources"]
79+
)
80+
81+
def test_other_runtimes_do_not_probe_for_preinstalled_tool(self):
82+
action = GlobalToolInstallAction(self.subprocess_dotnet, runtime="dotnet8")
83+
action.execute()
84+
self.subprocess_dotnet.run.assert_called_once_with(
85+
["tool", "install", "-g", "Amazon.Lambda.Tools", "--ignore-failed-sources"]
86+
)
87+
88+
def test_dotnet8_after_dotnet6_skip_still_installs(self):
89+
# dotnet6 skips because a working tool is pre-installed, but it must NOT mark the
90+
# tool as installed for the process - a subsequent dotnet8 build still installs
91+
# or updates to latest as before
92+
dotnet6_action = GlobalToolInstallAction(self.subprocess_dotnet, runtime="dotnet6")
93+
dotnet6_action.execute()
94+
self.subprocess_dotnet.reset_mock()
95+
96+
dotnet8_action = GlobalToolInstallAction(self.subprocess_dotnet, runtime="dotnet8")
97+
dotnet8_action.execute()
98+
self.subprocess_dotnet.run.assert_called_once_with(
99+
["tool", "install", "-g", "Amazon.Lambda.Tools", "--ignore-failed-sources"]
100+
)
101+
65102

66103
class TestRunPackageAction(TestCase):
67104
@patch("aws_lambda_builders.workflows.dotnet_clipackage.dotnetcli.SubprocessDotnetCLI")

0 commit comments

Comments
 (0)