From 77ae644f3e2541a31a2e3d906af161bd9e4d6481 Mon Sep 17 00:00:00 2001 From: Basil Crow Date: Fri, 12 Apr 2024 10:42:47 -0700 Subject: [PATCH] JAR and JPI creation is nondeterministic (#599) --- .../hpi/AbstractJenkinsManifestMojo.java | 24 +++++++++++++++++++ .../jenkinsci/maven/plugins/hpi/HpiMojo.java | 9 ++----- .../jenkinsci/maven/plugins/hpi/JarMojo.java | 4 +--- 3 files changed, 27 insertions(+), 10 deletions(-) diff --git a/src/main/java/org/jenkinsci/maven/plugins/hpi/AbstractJenkinsManifestMojo.java b/src/main/java/org/jenkinsci/maven/plugins/hpi/AbstractJenkinsManifestMojo.java index d7a63c3469..f9575a9827 100644 --- a/src/main/java/org/jenkinsci/maven/plugins/hpi/AbstractJenkinsManifestMojo.java +++ b/src/main/java/org/jenkinsci/maven/plugins/hpi/AbstractJenkinsManifestMojo.java @@ -42,6 +42,7 @@ import org.apache.maven.plugin.MojoExecutionException; import org.apache.maven.plugins.annotations.Parameter; import org.apache.maven.project.MavenProject; +import org.codehaus.plexus.archiver.jar.JarArchiver; import org.codehaus.plexus.archiver.jar.Manifest; import org.codehaus.plexus.archiver.jar.ManifestException; @@ -64,6 +65,16 @@ public abstract class AbstractJenkinsManifestMojo extends AbstractHpiMojo { @Parameter(property = "hpi.compatibleSinceVersion") private String compatibleSinceVersion; + /** + * Timestamp for reproducible output archive entries, either formatted as ISO 8601 + * yyyy-MM-dd'T'HH:mm:ssXXX or as an int representing seconds since the epoch (like + * SOURCE_DATE_EPOCH). + * + * @since TODO + */ + @Parameter(defaultValue = "${project.build.outputTimestamp}") + private String outputTimestamp; + /** * Optional - sandbox status of this plugin. */ @@ -79,6 +90,19 @@ public abstract class AbstractJenkinsManifestMojo extends AbstractHpiMojo { @Parameter protected String minimumJavaVersion; + /** + * @return an instance of {@link MavenArchiver} preconfigured for reproducible builds + * + * @since TODO + */ + protected MavenArchiver newMavenArchiver(JarArchiver jarArchiver, File outputFile) { + MavenArchiver mavenArchiver = new MavenArchiver(); + mavenArchiver.setArchiver(jarArchiver); + mavenArchiver.setOutputFile(outputFile); + mavenArchiver.configureReproducibleBuild(outputTimestamp); + return mavenArchiver; + } + /** * Generates a manifest file to be included in the .hpi file */ diff --git a/src/main/java/org/jenkinsci/maven/plugins/hpi/HpiMojo.java b/src/main/java/org/jenkinsci/maven/plugins/hpi/HpiMojo.java index 5876ebaed7..34c2ae9627 100644 --- a/src/main/java/org/jenkinsci/maven/plugins/hpi/HpiMojo.java +++ b/src/main/java/org/jenkinsci/maven/plugins/hpi/HpiMojo.java @@ -134,9 +134,7 @@ private void performPackaging() // create a jar file to be used when other plugins depend on this plugin. jarFile = getOutputFile(".jar"); getLog().info("Generating jar " + jarFile.getAbsolutePath()); - MavenArchiver archiver = new MavenArchiver(); - archiver.setArchiver(jarArchiver); - archiver.setOutputFile(jarFile); + MavenArchiver archiver = newMavenArchiver(jarArchiver, jarFile); jarArchiver.addConfiguredManifest(manifest); File indexJelly = new File(getClassesDirectory(), "index.jelly"); if (!indexJelly.isFile()) { @@ -165,10 +163,7 @@ private void performPackaging() File hpiFile = getOutputFile(".hpi"); getLog().info("Generating hpi " + hpiFile.getAbsolutePath()); - MavenArchiver archiver = new MavenArchiver(); - - archiver.setArchiver(hpiArchiver); - archiver.setOutputFile(hpiFile); + MavenArchiver archiver = newMavenArchiver(hpiArchiver, hpiFile); hpiArchiver.addConfiguredManifest(manifest); hpiArchiver.addDirectory(getWebappDirectory(), getIncludes(), getExcludes()); diff --git a/src/main/java/org/jenkinsci/maven/plugins/hpi/JarMojo.java b/src/main/java/org/jenkinsci/maven/plugins/hpi/JarMojo.java index 818c2893f4..5278ef593e 100644 --- a/src/main/java/org/jenkinsci/maven/plugins/hpi/JarMojo.java +++ b/src/main/java/org/jenkinsci/maven/plugins/hpi/JarMojo.java @@ -106,9 +106,7 @@ private void performPackaging() // create a jar file to be used when other plugins depend on this plugin. File jarFile = getOutputFile(".jar"); - MavenArchiver archiver = new MavenArchiver(); - archiver.setArchiver(jarArchiver); - archiver.setOutputFile(jarFile); + MavenArchiver archiver = newMavenArchiver(jarArchiver, jarFile); jarArchiver.addConfiguredManifest(manifest); jarArchiver.addDirectory(getClassesDirectory()); archiver.createArchive(session, project, archive);