Skip to content

Instantly share code, notes, and snippets.

@jprinet
Last active June 9, 2023 14:30
Show Gist options
  • Save jprinet/1188ee46699e8485f9b002d1888f0fa2 to your computer and use it in GitHub Desktop.
Save jprinet/1188ee46699e8485f9b002d1888f0fa2 to your computer and use it in GitHub Desktop.
Add Docker image IDs as extra inputs to the surefire goal.
package com.gradle;
import com.gradle.maven.extension.api.GradleEnterpriseApi;
import com.gradle.maven.extension.api.cache.BuildCacheApi;
import com.gradle.maven.extension.api.cache.MojoMetadataProvider;
import com.gradle.maven.extension.api.scan.BuildScanApi;
import org.apache.maven.artifact.DependencyResolutionRequiredException;
import org.apache.maven.model.Resource;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import java.io.*;
import java.net.URI;
import java.net.URISyntaxException;
import java.net.URL;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.List;
import java.util.Objects;
import java.util.Properties;
import static com.gradle.Utils.isNotEmpty;
/**
* Provide standardized Gradle Enterprise configuration.
* By applying the extension, these settings will automatically be applied.
*/
final class CustomGradleEnterpriseConfig {
private static final Logger LOGGER = LoggerFactory.getLogger(CustomGradleEnterpriseConfig.class);
void configureGradleEnterprise(GradleEnterpriseApi gradleEnterprise) {
/* Example of Gradle Enterprise configuration
gradleEnterprise.setServer("http://localhost:5086");
gradleEnterprise.setAllowUntrustedServer(true);
gradleEnterprise.setServer("https://enterprise-samples.gradle.com");
gradleEnterprise.setAllowUntrustedServer(false);
*/
}
void configureBuildScanPublishing(BuildScanApi buildScans) {
/* Example of build scan publishing configuration
boolean isCiServer = System.getenv().containsKey("CI");
buildScans.publishAlways();
buildScans.setCaptureGoalInputFiles(true);
buildScans.setUploadInBackground(!isCiServer);
*/
}
void configureBuildCache(BuildCacheApi buildCache) {
configureIntegrationTestCache(buildCache);
}
private void configureIntegrationTestCache(BuildCacheApi buildCache) {
buildCache.registerMojoMetadataProvider(context -> context.withPlugin("maven-failsafe-plugin", () -> addExtraInputs(context)));
}
private void addExtraInputs(MojoMetadataProvider.Context context) {
try {
List<String> dockerImages = getDockerImages(context);
for(String dockerImageName : dockerImages) {
LOGGER.info("Adding input for docker image " + dockerImageName);
context.inputs(inputs -> addExtraInput(inputs, dockerImageName));
}
} catch(IllegalStateException e) {
context.outputs(outputs -> outputs.notCacheableBecause("Unable to find the caching configuration file"));
}
}
private List<String> getDockerImages(MojoMetadataProvider.Context context) {
try {
// iterate over test resource directories and stop on first match if any
for(Resource testResource : context.getProject().getBuild().getTestResources()) {
File configFile = new File(testResource.getDirectory(), "docker-images.txt");
if(configFile.exists()) {
return Files.readAllLines(configFile.toPath(), StandardCharsets.UTF_8);
}
}
} catch (IOException e) {
LOGGER.error("Error reading image names", e);
throw new IllegalStateException(e);
}
LOGGER.error("Unable to find caching configuration file");
throw new IllegalStateException("Unable to find caching configuration file");
}
private void addExtraInput(MojoMetadataProvider.Context.Inputs inputs, String dockerImageName) {
String dockerImageId = getDockerImageId(dockerImageName);
inputs.property("docker-image-id-" + dockerImageName, dockerImageId);
}
private String getDockerImageId(String dockerImageName) {
try {
Process process = new ProcessBuilder("docker", "images", dockerImageName, "--format", "\"{{.ID}}\"").redirectErrorStream(true).start();
process.waitFor();
return new BufferedReader(new InputStreamReader(process.getInputStream(), StandardCharsets.UTF_8)).readLine();
} catch (InterruptedException e) {
LOGGER.error("Error reading image id", e);
Thread.currentThread().interrupt();
throw new IllegalStateException(e);
} catch (Exception e) {
LOGGER.error("Error reading image id", e);
throw new IllegalStateException(e);
}
}
}
@jprinet
Copy link
Author

jprinet commented Jun 9, 2023

Docker image names (without tag) are retrieved from src/test/resources/docker-images.txt, one image name per line.

for instance:

ubuntu
mysql
foo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment