diff --git a/build.gradle b/build.gradle index 73cd8434..a40a902a 100644 --- a/build.gradle +++ b/build.gradle @@ -69,6 +69,7 @@ dependencies { compile group: 'com.amazonaws', name: 'aws-java-sdk-ecr', version: '1.11.583' testCompile group: 'junit', name: 'junit', version: '4.12' + testCompile group: 'com.github.stefanbirkner', name: 'system-rules', version: '1.19.0' testCompile group: 'org.assertj', name: 'assertj-core', version: '3.12.2' testCompile group: 'org.mockito', name: 'mockito-core', version: '2.28.2' testCompile group: 'org.skyscreamer', name: 'jsonassert', version: '1.5.0' diff --git a/src/main/java/cd/go/artifact/docker/registry/executors/PublishArtifactExecutor.java b/src/main/java/cd/go/artifact/docker/registry/executors/PublishArtifactExecutor.java index c14f01e1..f8fcc586 100644 --- a/src/main/java/cd/go/artifact/docker/registry/executors/PublishArtifactExecutor.java +++ b/src/main/java/cd/go/artifact/docker/registry/executors/PublishArtifactExecutor.java @@ -25,6 +25,9 @@ import com.thoughtworks.go.plugin.api.response.DefaultGoPluginApiResponse; import com.thoughtworks.go.plugin.api.response.GoPluginApiResponse; +import java.util.HashMap; +import java.util.Map; + import static cd.go.artifact.docker.registry.DockerRegistryArtifactPlugin.LOG; import static java.lang.String.format; @@ -53,8 +56,9 @@ public GoPluginApiResponse execute() { final ArtifactStoreConfig artifactStoreConfig = publishArtifactRequest.getArtifactStore().getArtifactStoreConfig(); try { final DockerClient docker = clientFactory.docker(artifactStoreConfig); - final DockerImage image = artifactPlan.getArtifactPlanConfig().imageToPush(publishArtifactRequest.getAgentWorkingDir(), - publishArtifactRequest.getEnvironmentVariables()); + Map environmentVariables = publishArtifactRequest.getEnvironmentVariables() == null ? new HashMap<>() : publishArtifactRequest.getEnvironmentVariables(); + environmentVariables.putAll(System.getenv()); + final DockerImage image = artifactPlan.getArtifactPlanConfig().imageToPush(publishArtifactRequest.getAgentWorkingDir(), environmentVariables); LOG.info(format("Pushing docker image `%s` to docker registry `%s`.", image, artifactStoreConfig.getRegistryUrl())); consoleLogger.info(format("Pushing docker image `%s` to docker registry `%s`.", image, artifactStoreConfig.getRegistryUrl())); diff --git a/src/main/java/cd/go/artifact/docker/registry/model/PublishArtifactRequest.java b/src/main/java/cd/go/artifact/docker/registry/model/PublishArtifactRequest.java index 5bbc9fe8..6c7e4a00 100644 --- a/src/main/java/cd/go/artifact/docker/registry/model/PublishArtifactRequest.java +++ b/src/main/java/cd/go/artifact/docker/registry/model/PublishArtifactRequest.java @@ -48,6 +48,13 @@ public PublishArtifactRequest(ArtifactStore artifactStore, ArtifactPlan artifact this.artifactPlan = artifactPlan; } + public PublishArtifactRequest(ArtifactStore artifactStore, ArtifactPlan artifactPlan, String agentWorkingDir, Map environmentVariables) { + this.agentWorkingDir = agentWorkingDir; + this.artifactStore = artifactStore; + this.artifactPlan = artifactPlan; + this.environmentVariables = environmentVariables; + } + public String getAgentWorkingDir() { return agentWorkingDir; } diff --git a/src/test/java/cd/go/artifact/docker/registry/executors/PublishArtifactExecutorTest.java b/src/test/java/cd/go/artifact/docker/registry/executors/PublishArtifactExecutorTest.java index 3fa0dff0..c981bd79 100644 --- a/src/test/java/cd/go/artifact/docker/registry/executors/PublishArtifactExecutorTest.java +++ b/src/test/java/cd/go/artifact/docker/registry/executors/PublishArtifactExecutorTest.java @@ -32,6 +32,7 @@ import org.junit.Before; import org.junit.Rule; import org.junit.Test; +import org.junit.contrib.java.lang.system.EnvironmentVariables; import org.junit.rules.ExpectedException; import org.junit.rules.TemporaryFolder; import org.mockito.ArgumentCaptor; @@ -42,6 +43,7 @@ import java.nio.file.Files; import java.nio.file.Path; import java.nio.file.Paths; +import java.util.Collections; import java.util.Optional; import static org.assertj.core.api.Assertions.assertThat; @@ -66,12 +68,15 @@ public class PublishArtifactExecutorTest { private DefaultDockerClient dockerClient; @Mock private DockerClientFactory dockerClientFactory; + @Rule + public final EnvironmentVariables environmentVariables = new EnvironmentVariables(); private File agentWorkingDir; @Before public void setUp() throws IOException, InterruptedException, DockerException, DockerCertificateException { initMocks(this); + environmentVariables.clear(); agentWorkingDir = tmpFolder.newFolder("go-agent"); when(dockerClientFactory.docker(any())).thenReturn(dockerClient); @@ -133,4 +138,39 @@ public void shouldAddErrorToPublishArtifactResponseWhenFailedToPublishImage() th assertThat(response.responseCode()).isEqualTo(500); assertThat(response.responseBody()).contains("Failed to publish Artifact[id=id, storeId=storeId, artifactPlanConfig={\"BuildFile\":\"build.json\"}]: Some error"); } + + @Test + public void shouldReadEnvironmentVariablesPassedFromServer() throws IOException, DockerException, InterruptedException { + final ArtifactPlan artifactPlan = new ArtifactPlan("id", "storeId", "${IMAGE_NAME}", Optional.of("3.6")); + final ArtifactStoreConfig storeConfig = new ArtifactStoreConfig("localhost:5000", "other", "admin", "admin123"); + final ArtifactStore artifactStore = new ArtifactStore(artifactPlan.getId(), storeConfig); + final PublishArtifactRequest publishArtifactRequest = new PublishArtifactRequest(artifactStore, artifactPlan, agentWorkingDir.getAbsolutePath(), Collections.singletonMap("IMAGE_NAME", "alpine")); + + when(request.requestBody()).thenReturn(publishArtifactRequest.toJSON()); + when(dockerProgressHandler.getDigest()).thenReturn("foo"); + + final GoPluginApiResponse response = new PublishArtifactExecutor(request, consoleLogger, dockerProgressHandler, dockerClientFactory).execute(); + + verify(dockerClient).push(eq("alpine:3.6"), any(ProgressHandler.class)); + assertThat(response.responseCode()).isEqualTo(200); + assertThat(response.responseBody()).isEqualTo("{\"metadata\":{\"image\":\"alpine:3.6\",\"digest\":\"foo\"}}"); + } + + @Test + public void shouldReadEnvironmentVariablesFromTheSystem() throws IOException, DockerException, InterruptedException { + environmentVariables.set("IMAGE_NAME", "alpine"); + final ArtifactPlan artifactPlan = new ArtifactPlan("id", "storeId", "${IMAGE_NAME}", Optional.of("3.6")); + final ArtifactStoreConfig storeConfig = new ArtifactStoreConfig("localhost:5000", "other", "admin", "admin123"); + final ArtifactStore artifactStore = new ArtifactStore(artifactPlan.getId(), storeConfig); + final PublishArtifactRequest publishArtifactRequest = new PublishArtifactRequest(artifactStore, artifactPlan, agentWorkingDir.getAbsolutePath()); + + when(request.requestBody()).thenReturn(publishArtifactRequest.toJSON()); + when(dockerProgressHandler.getDigest()).thenReturn("foo"); + + final GoPluginApiResponse response = new PublishArtifactExecutor(request, consoleLogger, dockerProgressHandler, dockerClientFactory).execute(); + + verify(dockerClient).push(eq("alpine:3.6"), any(ProgressHandler.class)); + assertThat(response.responseCode()).isEqualTo(200); + assertThat(response.responseBody()).isEqualTo("{\"metadata\":{\"image\":\"alpine:3.6\",\"digest\":\"foo\"}}"); + } }