diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/BuildAndCacheApplicationLayerStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/BuildAndCacheApplicationLayerStep.java index 0694d9cc5c..f4853e24d0 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/BuildAndCacheApplicationLayerStep.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/BuildAndCacheApplicationLayerStep.java @@ -88,6 +88,10 @@ public ListenableFuture getFuture() { return listenableFuture; } + public String getLayerType() { + return layerType; + } + @Override public CachedLayer call() throws IOException, CacheCorruptedException { String description = "Building " + layerType + " layer"; diff --git a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/BuildImageStep.java b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/BuildImageStep.java index c2d69bee2c..be9048bd5b 100644 --- a/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/BuildImageStep.java +++ b/jib-core/src/main/java/com/google/cloud/tools/jib/builder/steps/BuildImageStep.java @@ -144,6 +144,7 @@ private Image afterCachedLayerSteps() .setCreationTimestamp(layerCreationTime) .setAuthor("Jib") .setCreatedBy(buildConfiguration.getToolName() + ":" + ProjectInfo.VERSION) + .setComment(buildAndCacheApplicationLayerStep.getLayerType()) .build()); } if (containerConfiguration != null) { diff --git a/jib-core/src/test/java/com/google/cloud/tools/jib/builder/steps/BuildImageStepTest.java b/jib-core/src/test/java/com/google/cloud/tools/jib/builder/steps/BuildImageStepTest.java index 81f9df5638..d1795fd99c 100644 --- a/jib-core/src/test/java/com/google/cloud/tools/jib/builder/steps/BuildImageStepTest.java +++ b/jib-core/src/test/java/com/google/cloud/tools/jib/builder/steps/BuildImageStepTest.java @@ -35,6 +35,7 @@ import java.time.Instant; import java.util.concurrent.ExecutionException; import java.util.concurrent.Executors; +import java.util.stream.Stream; import org.junit.Assert; import org.junit.Before; import org.junit.Test; @@ -53,7 +54,10 @@ public class BuildImageStepTest { @Mock private PullBaseImageStep mockPullBaseImageStep; @Mock private PullAndCacheBaseImageLayersStep mockPullAndCacheBaseImageLayersStep; @Mock private PullAndCacheBaseImageLayerStep mockPullAndCacheBaseImageLayerStep; - @Mock private BuildAndCacheApplicationLayerStep mockBuildAndCacheApplicationLayerStep; + @Mock private BuildAndCacheApplicationLayerStep mockBuildAndCacheApplicationLayerStepDependencies; + @Mock private BuildAndCacheApplicationLayerStep mockBuildAndCacheApplicationLayerStepResources; + @Mock private BuildAndCacheApplicationLayerStep mockBuildAndCacheApplicationLayerStepClasses; + @Mock private BuildAndCacheApplicationLayerStep mockBuildAndCacheApplicationLayerStepExtraFiles; private DescriptorDigest testDescriptorDigest; private HistoryEntry nonEmptyLayerHistory; @@ -141,8 +145,24 @@ public BlobDescriptor getBlobDescriptor() { .thenReturn( Futures.immediateFuture( new PullBaseImageStep.BaseImageWithAuthorization(baseImage, null))); - Mockito.when(mockBuildAndCacheApplicationLayerStep.getFuture()) - .thenReturn(Futures.immediateFuture(testCachedLayer)); + + Stream.of( + mockBuildAndCacheApplicationLayerStepClasses, + mockBuildAndCacheApplicationLayerStepDependencies, + mockBuildAndCacheApplicationLayerStepExtraFiles, + mockBuildAndCacheApplicationLayerStepResources) + .forEach( + layerStep -> + Mockito.when(layerStep.getFuture()) + .thenReturn(Futures.immediateFuture(testCachedLayer))); + + Mockito.when(mockBuildAndCacheApplicationLayerStepClasses.getLayerType()).thenReturn("classes"); + Mockito.when(mockBuildAndCacheApplicationLayerStepDependencies.getLayerType()) + .thenReturn("dependencies"); + Mockito.when(mockBuildAndCacheApplicationLayerStepExtraFiles.getLayerType()) + .thenReturn("extra files"); + Mockito.when(mockBuildAndCacheApplicationLayerStepResources.getLayerType()) + .thenReturn("resources"); } @Test @@ -154,9 +174,9 @@ public void test_validateAsyncDependencies() throws ExecutionException, Interrup mockPullBaseImageStep, mockPullAndCacheBaseImageLayersStep, ImmutableList.of( - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep)); + mockBuildAndCacheApplicationLayerStepDependencies, + mockBuildAndCacheApplicationLayerStepResources, + mockBuildAndCacheApplicationLayerStepClasses)); Image image = buildImageStep.getFuture().get().getFuture().get(); Assert.assertEquals( testDescriptorDigest, image.getLayers().asList().get(0).getBlobDescriptor().getDigest()); @@ -176,9 +196,9 @@ public void test_propagateBaseImageConfiguration() mockPullBaseImageStep, mockPullAndCacheBaseImageLayersStep, ImmutableList.of( - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep)); + mockBuildAndCacheApplicationLayerStepDependencies, + mockBuildAndCacheApplicationLayerStepResources, + mockBuildAndCacheApplicationLayerStepClasses)); Image image = buildImageStep.getFuture().get().getFuture().get(); Assert.assertEquals( ImmutableMap.of("BASE_ENV", "BASE_ENV_VALUE", "MY_ENV", "MY_ENV_VALUE"), @@ -209,9 +229,9 @@ public void test_inheritedEntrypoint() throws ExecutionException, InterruptedExc mockPullBaseImageStep, mockPullAndCacheBaseImageLayersStep, ImmutableList.of( - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep)); + mockBuildAndCacheApplicationLayerStepDependencies, + mockBuildAndCacheApplicationLayerStepResources, + mockBuildAndCacheApplicationLayerStepClasses)); Image image = buildImageStep.getFuture().get().getFuture().get(); Assert.assertEquals(ImmutableList.of("baseImageEntrypoint"), image.getEntrypoint()); @@ -231,9 +251,9 @@ public void test_inheritedEntrypointAndProgramArguments() mockPullBaseImageStep, mockPullAndCacheBaseImageLayersStep, ImmutableList.of( - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep)); + mockBuildAndCacheApplicationLayerStepDependencies, + mockBuildAndCacheApplicationLayerStepResources, + mockBuildAndCacheApplicationLayerStepClasses)); Image image = buildImageStep.getFuture().get().getFuture().get(); Assert.assertEquals(ImmutableList.of("baseImageEntrypoint"), image.getEntrypoint()); @@ -253,9 +273,9 @@ public void test_notInheritedProgramArguments() throws ExecutionException, Inter mockPullBaseImageStep, mockPullAndCacheBaseImageLayersStep, ImmutableList.of( - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep)); + mockBuildAndCacheApplicationLayerStepDependencies, + mockBuildAndCacheApplicationLayerStepResources, + mockBuildAndCacheApplicationLayerStepClasses)); Image image = buildImageStep.getFuture().get().getFuture().get(); Assert.assertEquals(ImmutableList.of("myEntrypoint"), image.getEntrypoint()); @@ -271,9 +291,10 @@ public void test_generateHistoryObjects() throws ExecutionException, Interrupted mockPullBaseImageStep, mockPullAndCacheBaseImageLayersStep, ImmutableList.of( - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep, - mockBuildAndCacheApplicationLayerStep)); + mockBuildAndCacheApplicationLayerStepDependencies, + mockBuildAndCacheApplicationLayerStepResources, + mockBuildAndCacheApplicationLayerStepClasses, + mockBuildAndCacheApplicationLayerStepExtraFiles)); Image image = buildImageStep.getFuture().get().getFuture().get(); // Make sure history is as expected @@ -282,11 +303,37 @@ public void test_generateHistoryObjects() throws ExecutionException, Interrupted .setCreationTimestamp(Instant.EPOCH) .setComment("auto-generated by Jib") .build(); - HistoryEntry expectedApplicationLayerHistory = + + HistoryEntry expectedApplicationLayerHistoryDependencies = + HistoryEntry.builder() + .setCreationTimestamp(Instant.EPOCH) + .setAuthor("Jib") + .setCreatedBy("jib:null") + .setComment("dependencies") + .build(); + + HistoryEntry expectedApplicationLayerHistoryResources = + HistoryEntry.builder() + .setCreationTimestamp(Instant.EPOCH) + .setAuthor("Jib") + .setCreatedBy("jib:null") + .setComment("resources") + .build(); + + HistoryEntry expectedApplicationLayerHistoryClasses = + HistoryEntry.builder() + .setCreationTimestamp(Instant.EPOCH) + .setAuthor("Jib") + .setCreatedBy("jib:null") + .setComment("classes") + .build(); + + HistoryEntry expectedApplicationLayerHistoryExtrafiles = HistoryEntry.builder() .setCreationTimestamp(Instant.EPOCH) .setAuthor("Jib") .setCreatedBy("jib:null") + .setComment("extra files") .build(); // Base layers (1 non-empty propagated, 2 empty propagated, 2 non-empty generated) @@ -296,12 +343,13 @@ public void test_generateHistoryObjects() throws ExecutionException, Interrupted Assert.assertEquals(expectedAddedBaseLayerHistory, image.getHistory().get(3)); Assert.assertEquals(expectedAddedBaseLayerHistory, image.getHistory().get(4)); - // Application layers (3 generated) - Assert.assertEquals(expectedApplicationLayerHistory, image.getHistory().get(5)); - Assert.assertEquals(expectedApplicationLayerHistory, image.getHistory().get(6)); - Assert.assertEquals(expectedApplicationLayerHistory, image.getHistory().get(7)); + // Application layers (4 generated) + Assert.assertEquals(expectedApplicationLayerHistoryDependencies, image.getHistory().get(5)); + Assert.assertEquals(expectedApplicationLayerHistoryResources, image.getHistory().get(6)); + Assert.assertEquals(expectedApplicationLayerHistoryClasses, image.getHistory().get(7)); + Assert.assertEquals(expectedApplicationLayerHistoryExtrafiles, image.getHistory().get(8)); - // Should be exactly 8 total - Assert.assertEquals(8, image.getHistory().size()); + // Should be exactly 9 total + Assert.assertEquals(9, image.getHistory().size()); } } diff --git a/jib-gradle-plugin/CHANGELOG.md b/jib-gradle-plugin/CHANGELOG.md index bb0a70c12c..e3c2461c1b 100644 --- a/jib-gradle-plugin/CHANGELOG.md +++ b/jib-gradle-plugin/CHANGELOG.md @@ -13,7 +13,8 @@ All notable changes to this project will be documented in this file. - `jib.extraDirectory.path` configures the extra layer directory (still also configurable via `jib.extraDirectory = file(...)`) - `jib.extraDirectory.permissions` is a map from absolute path on container to the file's permission bits (represented as an octal string) - Image digest is now written to `build/jib-image.digest` ([#933](https://github.com/GoogleContainerTools/jib/issues/933)) - +- Adds the layer type to the layer history as comments ([#1198](https://github.com/GoogleContainerTools/jib/issues/1198)) + ### Changed - Removed deprecated `jib.jvmFlags`, `jib.mainClass`, `jib.args`, and `jib.format` in favor of the equivalents under `jib.container` ([#461](https://github.com/GoogleContainerTools/jib/issues/461)) diff --git a/jib-maven-plugin/CHANGELOG.md b/jib-maven-plugin/CHANGELOG.md index 4a62b43fb0..35891a5133 100644 --- a/jib-maven-plugin/CHANGELOG.md +++ b/jib-maven-plugin/CHANGELOG.md @@ -13,6 +13,7 @@ All notable changes to this project will be documented in this file. - `` configures the extra layer directory (still also configurable via `...`) - `` is a list of `` objects, each with a `` and `` field, used to map a file on the container to the file's permission bits (represented as an octal string) - Image digest is now written to `build/jib-image.digest` ([#1155](https://github.com/GoogleContainerTools/jib/pull/1155)) +- Adds the layer type to the layer history as comments ([#1198](https://github.com/GoogleContainerTools/jib/issues/1198)) ### Changed