AWSLambda: Only publish functions when source has changed (#5734)

This commit is contained in:
Bert Blommers 2022-12-05 09:31:20 -01:00 committed by GitHub
parent 7c44e48670
commit d359b5d074
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 44 additions and 5 deletions

View File

@ -1310,7 +1310,14 @@ class LambdaStorage(object):
if not self._functions[name]["latest"]: if not self._functions[name]["latest"]:
return None return None
new_version = len(self._functions[name]["versions"]) + 1 all_versions = self._functions[name]["versions"]
if all_versions:
latest_published = all_versions[-1]
if latest_published.code_sha_256 == function.code_sha_256:
# Nothing has changed, don't publish
return latest_published
new_version = len(all_versions) + 1
fn = copy.copy(self._functions[name]["latest"]) fn = copy.copy(self._functions[name]["latest"])
fn.set_version(new_version) fn.set_version(new_version)
if description: if description:
@ -1879,6 +1886,7 @@ class LambdaBackend(BaseBackend):
self, function_name: str, qualifier: str, body: Dict[str, Any] self, function_name: str, qualifier: str, body: Dict[str, Any]
) -> Optional[Dict[str, Any]]: ) -> Optional[Dict[str, Any]]:
fn: LambdaFunction = self.get_function(function_name, qualifier) fn: LambdaFunction = self.get_function(function_name, qualifier)
fn.update_function_code(body)
if body.get("Publish", False): if body.get("Publish", False):
fn = self.publish_function(function_name) # type: ignore[assignment] fn = self.publish_function(function_name) # type: ignore[assignment]

View File

@ -18,7 +18,9 @@ from .utilities import (
get_role_name, get_role_name,
get_test_zip_file1, get_test_zip_file1,
get_test_zip_file2, get_test_zip_file2,
get_test_zip_file3,
create_invalid_lambda, create_invalid_lambda,
_process_lambda,
) )
_lambda_region = "us-west-2" _lambda_region = "us-west-2"
@ -870,6 +872,7 @@ def test_list_versions_by_function():
MemorySize=128, MemorySize=128,
Publish=True, Publish=True,
) )
conn.update_function_code(FunctionName=function_name, ZipFile=get_test_zip_file1())
res = conn.publish_version(FunctionName=function_name) res = conn.publish_version(FunctionName=function_name)
assert res["ResponseMetadata"]["HTTPStatusCode"] == 201 assert res["ResponseMetadata"]["HTTPStatusCode"] == 201
@ -1041,12 +1044,14 @@ def test_update_function_zip(key):
Publish=True, Publish=True,
) )
name_or_arn = fxn[key] name_or_arn = fxn[key]
first_sha = fxn["CodeSha256"]
zip_content_two = get_test_zip_file2() zip_content_two = get_test_zip_file2()
conn.update_function_code( update1 = conn.update_function_code(
FunctionName=name_or_arn, ZipFile=zip_content_two, Publish=True FunctionName=name_or_arn, ZipFile=zip_content_two, Publish=True
) )
update1["CodeSha256"].shouldnt.equal(first_sha)
response = conn.get_function(FunctionName=function_name, Qualifier="2") response = conn.get_function(FunctionName=function_name, Qualifier="2")
@ -1066,6 +1071,30 @@ def test_update_function_zip(key):
config.should.have.key("FunctionName").equals(function_name) config.should.have.key("FunctionName").equals(function_name)
config.should.have.key("Version").equals("2") config.should.have.key("Version").equals("2")
config.should.have.key("LastUpdateStatus").equals("Successful") config.should.have.key("LastUpdateStatus").equals("Successful")
config.should.have.key("CodeSha256").equals(update1["CodeSha256"])
most_recent_config = conn.get_function(FunctionName=function_name)
most_recent_config["Configuration"]["CodeSha256"].should.equal(
update1["CodeSha256"]
)
# Publishing this again, with the same code, gives us the same version
same_update = conn.update_function_code(
FunctionName=name_or_arn, ZipFile=zip_content_two, Publish=True
)
same_update["FunctionArn"].should.equal(
most_recent_config["Configuration"]["FunctionArn"] + ":2"
)
same_update["Version"].should.equal("2")
# Only when updating the code should we have a new version
new_update = conn.update_function_code(
FunctionName=name_or_arn, ZipFile=get_test_zip_file3(), Publish=True
)
new_update["FunctionArn"].should.equal(
most_recent_config["Configuration"]["FunctionArn"] + ":3"
)
new_update["Version"].should.equal("3")
@mock_lambda @mock_lambda
@ -1191,6 +1220,8 @@ def test_multiple_qualifiers():
) )
for _ in range(10): for _ in range(10):
new_zip = _process_lambda(f"func content {_}")
client.update_function_code(FunctionName=fn_name, ZipFile=new_zip)
client.publish_version(FunctionName=fn_name) client.publish_version(FunctionName=fn_name)
resp = client.list_versions_by_function(FunctionName=fn_name)["Versions"] resp = client.list_versions_by_function(FunctionName=fn_name)["Versions"]

View File

@ -7,7 +7,7 @@ from botocore.exceptions import ClientError
from moto import mock_lambda, mock_s3 from moto import mock_lambda, mock_s3
from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID from moto.core import DEFAULT_ACCOUNT_ID as ACCOUNT_ID
from uuid import uuid4 from uuid import uuid4
from .utilities import get_role_name, get_test_zip_file1 from .utilities import get_role_name, get_test_zip_file1, get_test_zip_file2
_lambda_region = "us-west-2" _lambda_region = "us-west-2"
boto3.setup_default_session(region_name=_lambda_region) boto3.setup_default_session(region_name=_lambda_region)
@ -139,7 +139,7 @@ def test_get_policy_with_qualifier():
Publish=True, Publish=True,
) )
zip_content_two = get_test_zip_file1() zip_content_two = get_test_zip_file2()
conn.update_function_code( conn.update_function_code(
FunctionName=function_name, ZipFile=zip_content_two, Publish=True FunctionName=function_name, ZipFile=zip_content_two, Publish=True
@ -250,7 +250,7 @@ def test_remove_function_permission__with_qualifier(key):
name_or_arn = f[key] name_or_arn = f[key]
# Ensure Qualifier=2 exists # Ensure Qualifier=2 exists
zip_content_two = get_test_zip_file1() zip_content_two = get_test_zip_file2()
conn.update_function_code( conn.update_function_code(
FunctionName=function_name, ZipFile=zip_content_two, Publish=True FunctionName=function_name, ZipFile=zip_content_two, Publish=True
) )