Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions renovate.json
Original file line number Diff line number Diff line change
Expand Up @@ -25,6 +25,12 @@
"com.google.protobuf{/,}**",
"com.google.api.grpc{/,}**"
]
},
{
"groupName": "org.apache.maven",
"matchPackageNames": [
"org.apache.maven{.,:}**"
]
}
]
}
32 changes: 31 additions & 1 deletion sigstore-maven-plugin/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,13 @@ plugins {

description = "A Maven plugin for signing with Sigstore"

val mavenDistribution =
configurations.create("mavenDistribution") {
isCanBeConsumed = false
isCanBeResolved = true
isTransitive = false
}

dependencies {
compileOnly("org.apache.maven:maven-plugin-api:3.10.0")
compileOnly("org.apache.maven:maven-core:3.10.0")
Expand All @@ -17,14 +24,37 @@ dependencies {
implementation("org.bouncycastle:bcutil-jdk18on:1.86")
implementation("org.apache.maven.plugins:maven-gpg-plugin:3.2.8")

testImplementation("org.apache.maven.shared:maven-verifier:1.8.0")
testImplementation("org.apache.maven.executor:maven-executor:1.0.0")

testImplementation(project(":sigstore-testkit"))

mavenDistribution("org.apache.maven:apache-maven:3.10.0:bin@zip")

sigstoreJavaRuntime(project(":sigstore-java")) {
because("Test code needs access locally-built sigstore-java as a Maven repository")
}
sigstoreMavenPluginRuntime(project(":sigstore-maven-plugin")) {
because("Test code needs access locally-built sigstore-java as a Maven repository")
}
}

val unpackMavenDistribution =
tasks.register<Sync>("unpackMavenDistribution") {
from(mavenDistribution.elements.map { zipTree(it.single()) })
into(layout.buildDirectory.dir("maven-distro"))
}

tasks.test {
dependsOn(unpackMavenDistribution)
jvmArgumentProviders.add(
CommandLineArgumentProvider {
val mavenHome =
unpackMavenDistribution
.get()
.destinationDir
.listFiles()!!
.single()
listOf("-Dmaven.home=${mavenHome.absolutePath}")
},
)
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,8 @@
import dev.sigstore.bundle.Bundle;
import dev.sigstore.encryption.certificates.Certificates;
import java.io.File;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.security.cert.X509Certificate;
import java.time.temporal.ChronoUnit;
import java.util.List;
Expand All @@ -32,7 +34,6 @@
import org.apache.maven.plugins.gpg.FilesCollector;
import org.apache.maven.project.MavenProject;
import org.apache.maven.project.MavenProjectHelper;
import org.codehaus.plexus.util.FileUtils;

/** Sign project artifact, the POM, and attached artifacts with sigstore for deployment. */
@Mojo(name = "sign", defaultPhase = LifecyclePhase.VERIFY, threadSafe = true)
Expand Down Expand Up @@ -115,7 +116,7 @@ public void execute() throws MojoExecutionException, MojoFailureException {
}

File bundleFile = new File(fileToSign + BUNDLE_EXTENSION);
FileUtils.fileWrite(bundleFile, "UTF-8", bundle.toJson());
Files.writeString(bundleFile.toPath(), bundle.toJson(), StandardCharsets.UTF_8);

long duration = System.currentTimeMillis() - start;
getLog()
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,15 @@
*/
package dev.sigstore.plugin;

import static org.assertj.core.api.Assertions.assertThat;
import static org.junit.jupiter.api.Assertions.assertFalse;
import static org.junit.jupiter.api.Assertions.assertTrue;

import dev.sigstore.plugin.test.MavenTestProject;
import dev.sigstore.testkit.annotations.EnabledIfOidcExists;
import dev.sigstore.testkit.annotations.OidcProviderType;
import java.io.IOException;
import java.nio.file.Path;
import org.apache.maven.it.VerificationException;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.io.TempDir;

Expand All @@ -30,13 +33,21 @@ public class SigningTest {

@Test
@EnabledIfOidcExists(provider = OidcProviderType.ANY)
public void test_simpleProject() throws IOException, VerificationException {
public void test_simpleProject() throws IOException {
var testProject = new MavenTestProject(testRoot, "simple");
var verifier = testProject.newVerifier();
var result = testProject.execute("package");

verifier.executeGoal("package");
verifier.verifyErrorFreeLog();
verifier.verifyFilePresent("target/simple-it-1.0-SNAPSHOT.jar.sigstore.json");
verifier.verifyFilePresent("target/simple-it-1.0-SNAPSHOT.pom.sigstore.json");
String stdOut = result.stdOutString().orElse("");
String stdErr = result.stdErrString().orElse("");
String logs = "stdout:\n" + stdOut + "\nstderr:\n" + stdErr;
assertTrue(result.success(), "Maven execution failed:\n" + logs);
assertFalse(stdOut.contains("[ERROR]"), "Maven stdout contained [ERROR]:\n" + logs);
assertFalse(stdErr.contains("[ERROR]"), "Maven stderr contained [ERROR]:\n" + logs);
assertThat(
testProject.getProjectRoot().resolve("target/simple-it-1.0-SNAPSHOT.jar.sigstore.json"))
.exists();
assertThat(
testProject.getProjectRoot().resolve("target/simple-it-1.0-SNAPSHOT.pom.sigstore.json"))
.exists();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,19 +15,20 @@
*/
package dev.sigstore.plugin.test;

import java.io.File;
import java.io.IOException;
import java.net.URISyntaxException;
import java.nio.charset.StandardCharsets;
import java.nio.file.Files;
import java.nio.file.Path;
import java.nio.file.Paths;
import java.util.Arrays;
import java.util.stream.Collectors;
import org.apache.maven.it.VerificationException;
import org.apache.maven.it.Verifier;
import org.apache.maven.it.util.ResourceExtractor;
import org.apache.maven.executor.ExecutorRequest;
import org.apache.maven.executor.ExecutorResult;
import org.apache.maven.executor.forked.ForkedMavenExecutor;

/**
* Initialize a test project verifier. You should use this to inject the right local repository into
* Initialize a test project executor. You should use this to inject the right local repository into
* settings.xml and the project version into pom.xml. Works with the test Maven projects in the
* {@code resources/maven/projects} directory.
*/
Expand All @@ -44,16 +45,37 @@ public MavenTestProject(Path testDir, String testProjectName) {
this.testProjectName = testProjectName;
}

public Verifier newVerifier() throws IOException, VerificationException {
ResourceExtractor.extractResourcePath(
MavenTestProject.class,
PROJECTS_PATH_IN_RESOURCES + testProjectName,
testDir.toFile(),
true);
public Path getProjectRoot() {
return Paths.get(testDir.toString(), PROJECTS_PATH_IN_RESOURCES, testProjectName);
}

File settingsXml =
ResourceExtractor.extractResourceToDestination(
MavenTestProject.class, SETTINGS_XML, testDir.resolve("settings.xml").toFile(), true);
public ExecutorResult execute(String... arguments) throws IOException {
Path sourceDir;
try {
sourceDir =
Paths.get(
MavenTestProject.class
.getResource(PROJECTS_PATH_IN_RESOURCES + testProjectName)
.toURI());
} catch (URISyntaxException e) {
throw new IOException(e);
}
Path projectRoot = getProjectRoot();
try (var stream = Files.walk(sourceDir)) {
for (Path source : (Iterable<Path>) stream::iterator) {
Path dest = projectRoot.resolve(sourceDir.relativize(source));
if (Files.isDirectory(source)) {
Files.createDirectories(dest);
} else {
Files.copy(source, dest);
}
}
}

Path settingsXml = testDir.resolve("settings.xml");
try (var in = MavenTestProject.class.getResourceAsStream(SETTINGS_XML)) {
Files.copy(in, settingsXml);
}

// properties are injected into the test task by the build (see
// build-logic.depends-on-local-sigstore-java-repo.gradle.kts,
Expand All @@ -68,7 +90,7 @@ public Verifier newVerifier() throws IOException, VerificationException {
for (var pomXml : pomXmls) {
Files.write(
pomXml,
Files.readString(pomXml)
Files.readString(pomXml, StandardCharsets.UTF_8)
.replace("@PluginVersion@", pluginVersion)
.getBytes(StandardCharsets.UTF_8));
}
Expand All @@ -85,15 +107,26 @@ public Verifier newVerifier() throws IOException, VerificationException {
}
var localMavenPluginRepo = "file:///" + Paths.get(localMavenRepoPluginProp).toRealPath();
Files.write(
settingsXml.toPath(),
Files.readString(settingsXml.toPath())
settingsXml,
Files.readString(settingsXml, StandardCharsets.UTF_8)
.replace("@localRepositoryUrl@", localMavenRepo)
.replace("@localPluginRepositoryUrl@", localMavenPluginRepo)
.getBytes(StandardCharsets.UTF_8));

Path projectRoot = Paths.get(testDir.toString(), PROJECTS_PATH_IN_RESOURCES, testProjectName);
var verifier = new Verifier(projectRoot.toAbsolutePath().toString());
verifier.addCliOption("--settings=" + settingsXml.getCanonicalPath());
return verifier;
try (var executor = new ForkedMavenExecutor(ExecutorRequest.discoverInstallationDirectory())) {
var requestBuilder =
ExecutorRequest.mavenBuilder()
.cwd(getProjectRoot())
.environmentVariable(
"JAVA_HOME",
System.getProperty(
"sigstore-java.test.JAVA_HOME", System.getProperty("java.home")))
.argument("-e")
.argument("--batch-mode")
.argument("--settings=" + settingsXml.toRealPath())
.grabOutputAsString(true);
Arrays.stream(arguments).forEach(requestBuilder::argument);
return executor.execute(requestBuilder.build());
}
}
}
Loading