Skip to content

Commit 26d1e47

Browse files
committedSep 2, 2024
Adds support to delete old versions when successful deployment
1 parent 7d0800a commit 26d1e47

File tree

3 files changed

+43
-5
lines changed

3 files changed

+43
-5
lines changed
 

‎samcli/lib/sync/flows/alias_version_sync_flow.py

+16
Original file line numberDiff line numberDiff line change
@@ -23,12 +23,14 @@ class AliasVersionSyncFlow(SyncFlow):
2323

2424
_function_identifier: str
2525
_alias_name: str
26+
_delete_old_alias: bool
2627
_lambda_client: Any
2728

2829
def __init__(
2930
self,
3031
function_identifier: str,
3132
alias_name: str,
33+
delete_old_alias: bool,
3234
build_context: "BuildContext",
3335
deploy_context: "DeployContext",
3436
sync_context: "SyncContext",
@@ -64,6 +66,7 @@ def __init__(
6466
self._function_identifier = function_identifier
6567
self._alias_name = alias_name
6668
self._lambda_client = None
69+
self._delete_old_alias = delete_old_alias
6770

6871
@property
6972
def sync_state_identifier(self) -> str:
@@ -90,13 +93,18 @@ def compare_remote(self) -> bool:
9093

9194
def sync(self) -> None:
9295
function_physical_id = self.get_physical_id(self._function_identifier)
96+
current_alias_version = self._get_version_alias_if_exists()
9397
version = self._lambda_client.publish_version(FunctionName=function_physical_id).get("Version")
9498
self._local_sha = str_checksum(str(version), hashlib.sha256())
9599
LOG.debug("%sCreated new function version: %s", self.log_prefix, version)
96100
if version:
97101
self._lambda_client.update_alias(
98102
FunctionName=function_physical_id, Name=self._alias_name, FunctionVersion=version
99103
)
104+
if self._delete_old_alias and current_alias_version:
105+
function_name_w_version = "{}:{}".format(function_physical_id, current_alias_version)
106+
self._lambda_client.delete_function(FunctionName=function_name_w_version)
107+
100108

101109
def gather_dependencies(self) -> List[SyncFlow]:
102110
return []
@@ -107,3 +115,11 @@ def _get_resource_api_calls(self) -> List[ResourceAPICall]:
107115
def _equality_keys(self) -> Any:
108116
"""Combination of function identifier and alias name can used to identify each unique SyncFlow"""
109117
return self._function_identifier, self._alias_name
118+
119+
def _get_version_alias_if_exists(self) -> Optional[str]:
120+
try:
121+
return str(self._lambda_client.get_alias(FunctionName=self.get_physical_id(self._function_identifier),
122+
Name=self._alias_name)
123+
.get("FunctionVersion"))
124+
except self._lambda_client.exceptions.ResourceNotFoundException:
125+
return None

‎samcli/lib/sync/flows/function_sync_flow.py

+2
Original file line numberDiff line numberDiff line change
@@ -109,11 +109,13 @@ def gather_dependencies(self) -> List[SyncFlow]:
109109
raise FunctionNotFound(f"Unable to find function {self._function_identifier}")
110110

111111
auto_publish_alias_name = function_resource.get("Properties", dict()).get("AutoPublishAlias", None)
112+
auto_delete_old_alias = function_resource.get("Properties", dict()).get("AutoDeleteOldAlias", False)
112113
if auto_publish_alias_name:
113114
sync_flows.append(
114115
AliasVersionSyncFlow(
115116
self._function_identifier,
116117
auto_publish_alias_name,
118+
auto_delete_old_alias,
117119
self._build_context,
118120
self._deploy_context,
119121
self._sync_context,

‎tests/unit/lib/sync/flows/test_alias_version_sync_flow.py

+25-5
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,17 @@
1-
import os
21
import hashlib
3-
4-
from samcli.lib.sync.sync_flow import SyncFlow
52
from unittest import TestCase
6-
from unittest.mock import ANY, MagicMock, call, mock_open, patch
3+
from unittest.mock import MagicMock, patch
74

85
from samcli.lib.sync.flows.alias_version_sync_flow import AliasVersionSyncFlow
96
from samcli.lib.utils.hash import str_checksum
107

118

129
class TestAliasVersionSyncFlow(TestCase):
13-
def create_sync_flow(self):
10+
def create_sync_flow(self, delete_old_alias = False):
1411
sync_flow = AliasVersionSyncFlow(
1512
"Function1",
1613
"Alias1",
14+
delete_old_alias,
1715
build_context=MagicMock(),
1816
deploy_context=MagicMock(),
1917
sync_context=MagicMock(),
@@ -76,3 +74,25 @@ def test_local_sha(self, session_mock):
7674

7775
sync_flow.sync()
7876
self.assertEqual(sync_flow._local_sha, str_checksum("2", hashlib.sha256()))
77+
78+
@patch("samcli.lib.sync.sync_flow.Session")
79+
def test_delete_old_alias(self, session_mock):
80+
sync_flow = self.create_sync_flow(True)
81+
82+
sync_flow.get_physical_id = MagicMock()
83+
sync_flow.get_physical_id.return_value = "PhysicalFunction1"
84+
85+
sync_flow.set_up()
86+
87+
sync_flow._lambda_client.get_alias.return_value = {"FunctionVersion": "1"}
88+
sync_flow._lambda_client.publish_version.return_value = {"Version": "2"}
89+
90+
sync_flow.sync()
91+
92+
sync_flow._lambda_client.publish_version.assert_called_once_with(FunctionName="PhysicalFunction1")
93+
sync_flow._lambda_client.update_alias.assert_called_once_with(
94+
FunctionName="PhysicalFunction1", Name="Alias1", FunctionVersion="2"
95+
)
96+
sync_flow._lambda_client.delete_function.assert_called_once_with(
97+
FunctionName="{}:{}".format("PhysicalFunction1", "1")
98+
)

0 commit comments

Comments
 (0)
Failed to load comments.