Browse Source

Polish "Support configuring bootBuildImage's environment on the command line"

See gh-48792
pull/48804/head
Andy Wilkinson 3 weeks ago
parent
commit
542ea4f18a
  1. 3
      build-plugin/spring-boot-gradle-plugin/src/dockerTest/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java
  2. 11
      build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/pages/packaging-oci-image.adoc
  3. 67
      build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImage.java
  4. 19
      build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageTests.java

3
build-plugin/spring-boot-gradle-plugin/src/dockerTest/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageIntegrationTests.java

@ -473,8 +473,7 @@ class BootBuildImageIntegrationTests { @@ -473,8 +473,7 @@ class BootBuildImageIntegrationTests {
void buildsImageWithMultipleCommandLineEnvironments() throws IOException {
writeMainClass();
writeLongNameResource();
BuildResult result = this.gradleBuild.build("bootBuildImage",
"--environment", "BP_LIVE_RELOAD_ENABLED=true",
BuildResult result = this.gradleBuild.build("bootBuildImage", "--environment", "BP_LIVE_RELOAD_ENABLED=true",
"--environment", "MY_CUSTOM_VAR=hello_world");
BuildTask task = result.task(":bootBuildImage");
assertThat(task).isNotNull();

11
build-plugin/spring-boot-gradle-plugin/src/docs/antora/modules/gradle-plugin/pages/packaging-oci-image.adoc

@ -162,7 +162,7 @@ Acceptable values are `ALWAYS`, `NEVER`, and `IF_NOT_PRESENT`. @@ -162,7 +162,7 @@ Acceptable values are `ALWAYS`, `NEVER`, and `IF_NOT_PRESENT`.
| `ALWAYS`
| `environment`
|
| `--environment`
| Environment variables that should be passed to the builder.
| Empty.
@ -346,6 +346,15 @@ include::example$packaging/boot-build-image-env.gradle.kts[tags=env] @@ -346,6 +346,15 @@ include::example$packaging/boot-build-image-env.gradle.kts[tags=env]
----
======
Environment variables can also be specified on the command line, as shown in the following example:
[source,shell]
----
$ gradle bootBuildImage --environment BP_JVM_VERSION=17
----
`--environment` can be used multiple times to specify multiple environment variables.
If there is a network proxy between the Docker daemon the builder runs in and network locations that buildpacks download artifacts from, you will need to configure the builder to use the proxy.
When using the Paketo builder, this can be accomplished by setting the `HTTPS_PROXY` and/or `HTTP_PROXY` environment variables as show in the following example:

67
build-plugin/spring-boot-gradle-plugin/src/main/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImage.java

@ -17,12 +17,14 @@ @@ -17,12 +17,14 @@
package org.springframework.boot.gradle.tasks.bundling;
import java.io.IOException;
import java.util.Collections;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Map;
import org.gradle.api.Action;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.InvalidUserDataException;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.RegularFileProperty;
@ -104,6 +106,23 @@ public abstract class BootBuildImage extends DefaultTask { @@ -104,6 +106,23 @@ public abstract class BootBuildImage extends DefaultTask {
this.docker = getProject().getObjects().newInstance(DockerSpec.class);
this.pullPolicy = getProject().getObjects().property(PullPolicy.class);
getSecurityOptions().convention((Iterable<? extends String>) null);
getEffectiveEnvironment().putAll(getEnvironment());
getEffectiveEnvironment().putAll(getEnvironmentFromCommandLine().map(BootBuildImage::asMap));
}
private static Map<String, String> asMap(List<String> variables) {
Map<String, String> environment = new LinkedHashMap<>();
for (String variable : variables) {
int index = variable.indexOf('=');
if (index <= 0) {
throw new InvalidUserDataException(
"Invalid value for option '--environment'. Expected 'NAME=VALUE' but got '" + variable + "'.");
}
String name = variable.substring(0, index);
String value = variable.substring(index + 1);
environment.put(name, value);
}
return environment;
}
/**
@ -159,22 +178,21 @@ public abstract class BootBuildImage extends DefaultTask { @@ -159,22 +178,21 @@ public abstract class BootBuildImage extends DefaultTask {
* Returns the environment that will be used when building the image.
* @return the environment
*/
@Input
@Internal
public abstract MapProperty<String, String> getEnvironment();
/**
* Returns environment variables contributed from the command line.
* Each entry must be in the form NAME=VALUE.
* Returns environment variables contributed from the command line. Each entry must be
* in the form NAME=VALUE.
* @return the environment variables from the command line
*/
@Internal
public abstract ListProperty<String> getEnvironmentFromCommandLine();
@Option(option = "environment", description = "Environment variable that will be used when building the image "
+ "(NAME=VALUE). Can be specified multiple times.")
abstract ListProperty<String> getEnvironmentFromCommandLine();
@Option(option = "environment",
description = "Environment variable to set for the build (NAME=VALUE). Can be specified multiple times.")
public void environment(List<String> environment) {
getEnvironmentFromCommandLine().addAll(environment);
}
@Input
abstract MapProperty<String, String> getEffectiveEnvironment();
/**
* Returns whether caches should be cleaned before packaging.
@ -429,7 +447,7 @@ public abstract class BootBuildImage extends DefaultTask { @@ -429,7 +447,7 @@ public abstract class BootBuildImage extends DefaultTask {
}
private BuildRequest customizeEnvironment(BuildRequest request) {
Map<String, String> environment = getEffectiveEnvironment();
Map<String, String> environment = getEffectiveEnvironment().getOrElse(Collections.emptyMap());
if (!environment.isEmpty()) {
request = request.withEnv(environment);
}
@ -518,31 +536,4 @@ public abstract class BootBuildImage extends DefaultTask { @@ -518,31 +536,4 @@ public abstract class BootBuildImage extends DefaultTask {
return request;
}
private Map<String, String> getEffectiveEnvironment() {
Map<String, String> environment = new java.util.LinkedHashMap<>();
Map<String, String> configured = getEnvironment().getOrNull();
if (!CollectionUtils.isEmpty(configured)) {
environment.putAll(configured);
}
List<String> fromCli = getEnvironmentFromCommandLine().getOrNull();
if (!CollectionUtils.isEmpty(fromCli)) {
for (String entry : fromCli) {
Map.Entry<String, String> parsed = parseEnvironmentEntry(entry);
environment.put(parsed.getKey(), parsed.getValue());
}
}
return environment;
}
private Map.Entry<String, String> parseEnvironmentEntry(String entry) {
int index = entry.indexOf('=');
if (index <= 0) {
throw new GradleException(
"Invalid value for option '--environment'. Expected 'NAME=VALUE' but got '" + entry + "'.");
}
String name = entry.substring(0, index);
String value = entry.substring(index + 1);
return Map.entry(name, value);
}
}

19
build-plugin/spring-boot-gradle-plugin/src/test/java/org/springframework/boot/gradle/tasks/bundling/BootBuildImageTests.java

@ -144,6 +144,25 @@ class BootBuildImageTests { @@ -144,6 +144,25 @@ class BootBuildImageTests {
.hasSize(2);
}
@Test
void whenEnvironmentVariablesAreSetOnTheCommandLineTheyAreIncludedInTheRequest() {
this.buildImage.getEnvironmentFromCommandLine().add("ALPHA=a");
this.buildImage.getEnvironmentFromCommandLine().add("BRAVO=b");
assertThat(this.buildImage.createRequest().getEnv()).containsEntry("ALPHA", "a")
.containsEntry("BRAVO", "b")
.hasSize(2);
}
@Test
void environmentVariablesFromTheCommandLineOverrideThoseInTheBuildScript() {
this.buildImage.getEnvironment().put("ALPHA", "a");
this.buildImage.getEnvironmentFromCommandLine().add("ALPHA=apple");
this.buildImage.getEnvironmentFromCommandLine().add("BRAVO=banana");
assertThat(this.buildImage.createRequest().getEnv()).containsEntry("ALPHA", "apple")
.containsEntry("BRAVO", "banana")
.hasSize(2);
}
@Test
void whenUsingDefaultConfigurationThenRequestHasVerboseLoggingDisabled() {
assertThat(this.buildImage.createRequest().isVerboseLogging()).isFalse();

Loading…
Cancel
Save