Browse Source

Merge pull request #48792 from HuitaePark

* gh-48792:
  Polish "Support configuring bootBuildImage's environment on the command line"
  Support configuring bootBuildImage's environment on the command line

Closes gh-48792
pull/48804/head
Andy Wilkinson 3 weeks ago
parent
commit
f7559b85f1
  1. 14
      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. 40
      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

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

@ -469,6 +469,20 @@ class BootBuildImageIntegrationTests { @@ -469,6 +469,20 @@ class BootBuildImageIntegrationTests {
removeImages(projectName, builderImage, runImage, buildpackImage);
}
@TestTemplate
void buildsImageWithMultipleCommandLineEnvironments() throws IOException {
writeMainClass();
writeLongNameResource();
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();
assertThat(task.getOutcome()).isEqualTo(TaskOutcome.SUCCESS);
assertThat(result.getOutput()).contains("BP_LIVE_RELOAD_ENABLED=true");
assertThat(result.getOutput()).contains("MY_CUSTOM_VAR=hello_world");
removeImages(this.gradleBuild.getProjectDir().getName());
}
@TestTemplate
@EnabledOnOs(value = { OS.LINUX, OS.MAC }, architectures = "amd64",
disabledReason = "The expected failure condition will not fail on ARM architectures")

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:

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

@ -17,11 +17,14 @@ @@ -17,11 +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.InvalidUserDataException;
import org.gradle.api.Project;
import org.gradle.api.Task;
import org.gradle.api.file.RegularFileProperty;
@ -30,6 +33,7 @@ import org.gradle.api.provider.MapProperty; @@ -30,6 +33,7 @@ import org.gradle.api.provider.MapProperty;
import org.gradle.api.provider.Property;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.InputFile;
import org.gradle.api.tasks.Internal;
import org.gradle.api.tasks.Nested;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.PathSensitive;
@ -102,6 +106,23 @@ public abstract class BootBuildImage extends DefaultTask { @@ -102,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;
}
/**
@ -157,9 +178,22 @@ public abstract class BootBuildImage extends DefaultTask { @@ -157,9 +178,22 @@ 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.
* @return the environment variables from the command line
*/
@Internal
@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();
@Input
abstract MapProperty<String, String> getEffectiveEnvironment();
/**
* Returns whether caches should be cleaned before packaging.
* @return whether caches should be cleaned
@ -413,8 +447,8 @@ public abstract class BootBuildImage extends DefaultTask { @@ -413,8 +447,8 @@ public abstract class BootBuildImage extends DefaultTask {
}
private BuildRequest customizeEnvironment(BuildRequest request) {
Map<String, String> environment = getEnvironment().getOrNull();
if (!CollectionUtils.isEmpty(environment)) {
Map<String, String> environment = getEffectiveEnvironment().getOrElse(Collections.emptyMap());
if (!environment.isEmpty()) {
request = request.withEnv(environment);
}
return request;

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