diff --git a/src/integrations/prefect-docker/prefect_docker/deployments/steps.py b/src/integrations/prefect-docker/prefect_docker/deployments/steps.py index 1ae3a4ae2a69..013b065587f1 100644 --- a/src/integrations/prefect-docker/prefect_docker/deployments/steps.py +++ b/src/integrations/prefect-docker/prefect_docker/deployments/steps.py @@ -97,8 +97,9 @@ def cacheable(func): @wraps(func) def wrapper(*args, **kwargs): if ignore_cache := kwargs.pop("ignore_cache", False): - logger.debug("Ignoring `@cacheable` decorator for build_docker_image.") + logger.debug(f"Ignoring `@cacheable` decorator for {func.__name__}.") key = ( + func.__name__, tuple(_make_hashable(arg) for arg in args), tuple((k, _make_hashable(v)) for k, v in sorted(kwargs.items())), ) diff --git a/src/integrations/prefect-docker/tests/deployments/test_steps.py b/src/integrations/prefect-docker/tests/deployments/test_steps.py index 7a58e027548d..7b1b25cba538 100644 --- a/src/integrations/prefect-docker/tests/deployments/test_steps.py +++ b/src/integrations/prefect-docker/tests/deployments/test_steps.py @@ -503,3 +503,28 @@ def test_uncached_push_docker_image(self, mock_docker_client): assert mock_docker_client.login.call_count == 3 expected_push_calls = 1 + len(additional_tags) assert mock_docker_client.api.push.call_count == expected_push_calls * 3 + + def test_avoids_aggressive_caching(self, mock_docker_client): + """this is a regression test for https://github.com/PrefectHQ/prefect/issues/15258 + where all decorated functions were sharing a cache, so dict(image=..., tag=...) passed to + build_docker_image and push_docker_image would hit the cache for push_docker_image, + even though the function was different and should not have been cached. + + here we test that the caches are distinct for each decorated function. + """ + image_name = "registry/repo" + tag = "latest" + + build_docker_image( + image_name=image_name, + tag=tag, + ) + + # Push the image (this should not hit the cache) + push_docker_image( + image_name=image_name, + tag=tag, + ) + + mock_docker_client.api.build.assert_called_once() + mock_docker_client.api.push.assert_called_once()