Skip to content

Commit b0b2cd7

Browse files
Use latest buildpack image tag when no tag is provided
Fixes gh-28921
1 parent 467c092 commit b0b2cd7

File tree

2 files changed

+42
-10
lines changed
  • spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src

2 files changed

+42
-10
lines changed

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/main/java/org/springframework/boot/buildpack/platform/build/ImageBuildpack.java

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -54,14 +54,15 @@ final class ImageBuildpack implements Buildpack {
5454
private final ExportedLayers exportedLayers;
5555

5656
private ImageBuildpack(BuildpackResolverContext context, ImageReference imageReference) {
57+
ImageReference reference = imageReference.inTaggedOrDigestForm();
5758
try {
58-
Image image = context.fetchImage(imageReference, ImageType.BUILDPACK);
59+
Image image = context.fetchImage(reference, ImageType.BUILDPACK);
5960
BuildpackMetadata buildpackMetadata = BuildpackMetadata.fromImage(image);
6061
this.coordinates = BuildpackCoordinates.fromBuildpackMetadata(buildpackMetadata);
61-
this.exportedLayers = new ExportedLayers(context, imageReference);
62+
this.exportedLayers = new ExportedLayers(context, reference);
6263
}
6364
catch (IOException | DockerEngineException ex) {
64-
throw new IllegalArgumentException("Error pulling buildpack image '" + imageReference + "'", ex);
65+
throw new IllegalArgumentException("Error pulling buildpack image '" + reference + "'", ex);
6566
}
6667
}
6768

spring-boot-project/spring-boot-tools/spring-boot-buildpack-platform/src/test/java/org/springframework/boot/buildpack/platform/build/ImageBuildpackTests.java

Lines changed: 38 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,7 @@
3131
import org.mockito.invocation.InvocationOnMock;
3232

3333
import org.springframework.boot.buildpack.platform.docker.type.Image;
34+
import org.springframework.boot.buildpack.platform.docker.type.ImageReference;
3435
import org.springframework.boot.buildpack.platform.io.IOBiConsumer;
3536
import org.springframework.boot.buildpack.platform.io.TarArchive;
3637
import org.springframework.boot.buildpack.platform.json.AbstractJsonTests;
@@ -40,6 +41,7 @@
4041
import static org.assertj.core.api.Assertions.fail;
4142
import static org.assertj.core.api.Assertions.tuple;
4243
import static org.mockito.ArgumentMatchers.any;
44+
import static org.mockito.ArgumentMatchers.eq;
4345
import static org.mockito.BDDMockito.given;
4446
import static org.mockito.BDDMockito.willAnswer;
4547
import static org.mockito.Mockito.mock;
@@ -64,10 +66,11 @@ void setUp() {
6466
@Test
6567
void resolveWhenFullyQualifiedReferenceReturnsBuilder() throws Exception {
6668
Image image = Image.of(getContent("buildpack-image.json"));
69+
ImageReference imageReference = ImageReference.of("example/buildpack1:1.0.0");
6770
BuildpackResolverContext resolverContext = mock(BuildpackResolverContext.class);
68-
given(resolverContext.fetchImage(any(), any())).willReturn(image);
69-
willAnswer(this::withMockLayers).given(resolverContext).exportImageLayers(any(), any());
70-
BuildpackReference reference = BuildpackReference.of("docker://example/buildpack1:latest");
71+
given(resolverContext.fetchImage(eq(imageReference), eq(ImageType.BUILDPACK))).willReturn(image);
72+
willAnswer(this::withMockLayers).given(resolverContext).exportImageLayers(eq(imageReference), any());
73+
BuildpackReference reference = BuildpackReference.of("docker://example/buildpack1:1.0.0");
7174
Buildpack buildpack = ImageBuildpack.resolve(resolverContext, reference);
7275
assertThat(buildpack.getCoordinates()).hasToString("example/[email protected]");
7376
assertHasExpectedLayers(buildpack);
@@ -76,10 +79,38 @@ void resolveWhenFullyQualifiedReferenceReturnsBuilder() throws Exception {
7679
@Test
7780
void resolveWhenUnqualifiedReferenceReturnsBuilder() throws Exception {
7881
Image image = Image.of(getContent("buildpack-image.json"));
82+
ImageReference imageReference = ImageReference.of("example/buildpack1:1.0.0");
7983
BuildpackResolverContext resolverContext = mock(BuildpackResolverContext.class);
80-
given(resolverContext.fetchImage(any(), any())).willReturn(image);
81-
willAnswer(this::withMockLayers).given(resolverContext).exportImageLayers(any(), any());
82-
BuildpackReference reference = BuildpackReference.of("example/buildpack1:latest");
84+
given(resolverContext.fetchImage(eq(imageReference), eq(ImageType.BUILDPACK))).willReturn(image);
85+
willAnswer(this::withMockLayers).given(resolverContext).exportImageLayers(eq(imageReference), any());
86+
BuildpackReference reference = BuildpackReference.of("example/buildpack1:1.0.0");
87+
Buildpack buildpack = ImageBuildpack.resolve(resolverContext, reference);
88+
assertThat(buildpack.getCoordinates()).hasToString("example/[email protected]");
89+
assertHasExpectedLayers(buildpack);
90+
}
91+
92+
@Test
93+
void resolveReferenceWithoutTagUsesLatestTag() throws Exception {
94+
Image image = Image.of(getContent("buildpack-image.json"));
95+
ImageReference imageReference = ImageReference.of("example/buildpack1:latest");
96+
BuildpackResolverContext resolverContext = mock(BuildpackResolverContext.class);
97+
given(resolverContext.fetchImage(eq(imageReference), eq(ImageType.BUILDPACK))).willReturn(image);
98+
willAnswer(this::withMockLayers).given(resolverContext).exportImageLayers(eq(imageReference), any());
99+
BuildpackReference reference = BuildpackReference.of("example/buildpack1");
100+
Buildpack buildpack = ImageBuildpack.resolve(resolverContext, reference);
101+
assertThat(buildpack.getCoordinates()).hasToString("example/[email protected]");
102+
assertHasExpectedLayers(buildpack);
103+
}
104+
105+
@Test
106+
void resolveReferenceWithDigestUsesDigest() throws Exception {
107+
Image image = Image.of(getContent("buildpack-image.json"));
108+
String digest = "sha256:4acb6bfd6c4f0cabaf7f3690e444afe51f1c7de54d51da7e63fac709c56f1c30";
109+
ImageReference imageReference = ImageReference.of("example/buildpack1@" + digest);
110+
BuildpackResolverContext resolverContext = mock(BuildpackResolverContext.class);
111+
given(resolverContext.fetchImage(eq(imageReference), eq(ImageType.BUILDPACK))).willReturn(image);
112+
willAnswer(this::withMockLayers).given(resolverContext).exportImageLayers(eq(imageReference), any());
113+
BuildpackReference reference = BuildpackReference.of("example/buildpack1@" + digest);
83114
Buildpack buildpack = ImageBuildpack.resolve(resolverContext, reference);
84115
assertThat(buildpack.getCoordinates()).hasToString("example/[email protected]");
85116
assertHasExpectedLayers(buildpack);
@@ -89,7 +120,7 @@ void resolveWhenUnqualifiedReferenceReturnsBuilder() throws Exception {
89120
void resolveWhenWhenImageNotPulledThrowsException() throws Exception {
90121
BuildpackResolverContext resolverContext = mock(BuildpackResolverContext.class);
91122
given(resolverContext.fetchImage(any(), any())).willThrow(IOException.class);
92-
BuildpackReference reference = BuildpackReference.of("docker://example/buildpack1:latest");
123+
BuildpackReference reference = BuildpackReference.of("docker://example/buildpack1");
93124
assertThatIllegalArgumentException().isThrownBy(() -> ImageBuildpack.resolve(resolverContext, reference))
94125
.withMessageContaining("Error pulling buildpack image")
95126
.withMessageContaining("example/buildpack1:latest");

0 commit comments

Comments
 (0)