diff --git a/tycho-its/projects/reproducible-archive-timestamps/pom.xml b/tycho-its/projects/reproducible-build/pom.xml
similarity index 94%
rename from tycho-its/projects/reproducible-archive-timestamps/pom.xml
rename to tycho-its/projects/reproducible-build/pom.xml
index 258f4e8b20..304b9143d9 100644
--- a/tycho-its/projects/reproducible-archive-timestamps/pom.xml
+++ b/tycho-its/projects/reproducible-build/pom.xml
@@ -3,12 +3,13 @@
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/maven-v4_0_0.xsd">
4.0.0
- reproducible.archive.timestamps
- reproducible.archive.timestamps.parent
+ reproducible.build
+ reproducible.build.parent
1.0.0
pom
+ reproducible.buildqualifier
reproducible.bundle
reproducible.bundle.feature
reproducible.iu
diff --git a/tycho-its/projects/reproducible-build/reproducible.buildqualifier/META-INF/MANIFEST.MF b/tycho-its/projects/reproducible-build/reproducible.buildqualifier/META-INF/MANIFEST.MF
new file mode 100644
index 0000000000..620aed7dff
--- /dev/null
+++ b/tycho-its/projects/reproducible-build/reproducible.buildqualifier/META-INF/MANIFEST.MF
@@ -0,0 +1,5 @@
+Manifest-Version: 1.0
+Bundle-ManifestVersion: 2
+Bundle-Name: Reproducible-buildqualifier
+Bundle-SymbolicName: reproducible.buildqualifier
+Bundle-Version: 1.0.0.qualifier
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/build.properties b/tycho-its/projects/reproducible-build/reproducible.buildqualifier/build.properties
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/build.properties
rename to tycho-its/projects/reproducible-build/reproducible.buildqualifier/build.properties
diff --git a/tycho-its/projects/reproducible-build/reproducible.buildqualifier/pom.xml b/tycho-its/projects/reproducible-build/reproducible.buildqualifier/pom.xml
new file mode 100644
index 0000000000..fd47e0eed7
--- /dev/null
+++ b/tycho-its/projects/reproducible-build/reproducible.buildqualifier/pom.xml
@@ -0,0 +1,14 @@
+
+
+ 4.0.0
+
+
+ reproducible.build
+ reproducible.build.parent
+ 1.0.0
+
+
+ reproducible.buildqualifier
+ 1.0.0-SNAPSHOT
+ eclipse-plugin
+
diff --git a/tycho-its/projects/reproducible-build/reproducible.buildqualifier/src/reproducible/buildqualifier/PublicClass.java b/tycho-its/projects/reproducible-build/reproducible.buildqualifier/src/reproducible/buildqualifier/PublicClass.java
new file mode 100644
index 0000000000..c91c5a8cf0
--- /dev/null
+++ b/tycho-its/projects/reproducible-build/reproducible.buildqualifier/src/reproducible/buildqualifier/PublicClass.java
@@ -0,0 +1,6 @@
+package reproducible.buildqualifier;
+
+public class PublicClass
+{
+
+}
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle.feature/build.properties b/tycho-its/projects/reproducible-build/reproducible.bundle.feature/build.properties
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle.feature/build.properties
rename to tycho-its/projects/reproducible-build/reproducible.bundle.feature/build.properties
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle.feature/feature.xml b/tycho-its/projects/reproducible-build/reproducible.bundle.feature/feature.xml
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle.feature/feature.xml
rename to tycho-its/projects/reproducible-build/reproducible.bundle.feature/feature.xml
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle.feature/pom.xml b/tycho-its/projects/reproducible-build/reproducible.bundle.feature/pom.xml
similarity index 66%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle.feature/pom.xml
rename to tycho-its/projects/reproducible-build/reproducible.bundle.feature/pom.xml
index c56f2de8d5..49814f1186 100644
--- a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle.feature/pom.xml
+++ b/tycho-its/projects/reproducible-build/reproducible.bundle.feature/pom.xml
@@ -3,8 +3,8 @@
4.0.0
- reproducible.archive.timestamps
- reproducible.archive.timestamps.parent
+ reproducible.build
+ reproducible.build.parent
1.0.0
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/META-INF/MANIFEST.MF b/tycho-its/projects/reproducible-build/reproducible.bundle/META-INF/MANIFEST.MF
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/META-INF/MANIFEST.MF
rename to tycho-its/projects/reproducible-build/reproducible.bundle/META-INF/MANIFEST.MF
diff --git a/tycho-its/projects/reproducible-build/reproducible.bundle/build.properties b/tycho-its/projects/reproducible-build/reproducible.bundle/build.properties
new file mode 100644
index 0000000000..34d2e4d2da
--- /dev/null
+++ b/tycho-its/projects/reproducible-build/reproducible.bundle/build.properties
@@ -0,0 +1,4 @@
+source.. = src/
+output.. = bin/
+bin.includes = META-INF/,\
+ .
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/custom/META-INF/MANIFEST.MF b/tycho-its/projects/reproducible-build/reproducible.bundle/custom/META-INF/MANIFEST.MF
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/custom/META-INF/MANIFEST.MF
rename to tycho-its/projects/reproducible-build/reproducible.bundle/custom/META-INF/MANIFEST.MF
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/custom/META-INF/meta-test.txt b/tycho-its/projects/reproducible-build/reproducible.bundle/custom/META-INF/meta-test.txt
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/custom/META-INF/meta-test.txt
rename to tycho-its/projects/reproducible-build/reproducible.bundle/custom/META-INF/meta-test.txt
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/custom/test.txt b/tycho-its/projects/reproducible-build/reproducible.bundle/custom/test.txt
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/custom/test.txt
rename to tycho-its/projects/reproducible-build/reproducible.bundle/custom/test.txt
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/pom.xml b/tycho-its/projects/reproducible-build/reproducible.bundle/pom.xml
similarity index 89%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/pom.xml
rename to tycho-its/projects/reproducible-build/reproducible.bundle/pom.xml
index 4adfcab7fb..c553d2b733 100644
--- a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/pom.xml
+++ b/tycho-its/projects/reproducible-build/reproducible.bundle/pom.xml
@@ -3,8 +3,8 @@
4.0.0
- reproducible.archive.timestamps
- reproducible.archive.timestamps.parent
+ reproducible.build
+ reproducible.build.parent
1.0.0
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/src/reproducible/bundle/PublicClass.java b/tycho-its/projects/reproducible-build/reproducible.bundle/src/reproducible/bundle/PublicClass.java
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.bundle/src/reproducible/bundle/PublicClass.java
rename to tycho-its/projects/reproducible-build/reproducible.bundle/src/reproducible/bundle/PublicClass.java
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.iu/p2iu.xml b/tycho-its/projects/reproducible-build/reproducible.iu/p2iu.xml
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.iu/p2iu.xml
rename to tycho-its/projects/reproducible-build/reproducible.iu/p2iu.xml
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.iu/pom.xml b/tycho-its/projects/reproducible-build/reproducible.iu/pom.xml
similarity index 66%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.iu/pom.xml
rename to tycho-its/projects/reproducible-build/reproducible.iu/pom.xml
index bbeb688b88..6cd09a0b66 100644
--- a/tycho-its/projects/reproducible-archive-timestamps/reproducible.iu/pom.xml
+++ b/tycho-its/projects/reproducible-build/reproducible.iu/pom.xml
@@ -3,8 +3,8 @@
4.0.0
- reproducible.archive.timestamps
- reproducible.archive.timestamps.parent
+ reproducible.build
+ reproducible.build.parent
1.0.0
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.iu/src/main/resources/myFile.txt b/tycho-its/projects/reproducible-build/reproducible.iu/src/main/resources/myFile.txt
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.iu/src/main/resources/myFile.txt
rename to tycho-its/projects/reproducible-build/reproducible.iu/src/main/resources/myFile.txt
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.repository/main.p2.inf b/tycho-its/projects/reproducible-build/reproducible.repository/main.p2.inf
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.repository/main.p2.inf
rename to tycho-its/projects/reproducible-build/reproducible.repository/main.p2.inf
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.repository/main.product b/tycho-its/projects/reproducible-build/reproducible.repository/main.product
similarity index 100%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.repository/main.product
rename to tycho-its/projects/reproducible-build/reproducible.repository/main.product
diff --git a/tycho-its/projects/reproducible-archive-timestamps/reproducible.repository/pom.xml b/tycho-its/projects/reproducible-build/reproducible.repository/pom.xml
similarity index 92%
rename from tycho-its/projects/reproducible-archive-timestamps/reproducible.repository/pom.xml
rename to tycho-its/projects/reproducible-build/reproducible.repository/pom.xml
index cfcadb0953..69e288d708 100644
--- a/tycho-its/projects/reproducible-archive-timestamps/reproducible.repository/pom.xml
+++ b/tycho-its/projects/reproducible-build/reproducible.repository/pom.xml
@@ -4,8 +4,8 @@
4.0.0
- reproducible.archive.timestamps
- reproducible.archive.timestamps.parent
+ reproducible.build
+ reproducible.build.parent
1.0.0
diff --git a/tycho-its/src/test/java/org/eclipse/tycho/test/reproducible/ReproducibleArchiveTimestampsTest.java b/tycho-its/src/test/java/org/eclipse/tycho/test/reproducible/ReproducibleBuildTest.java
similarity index 70%
rename from tycho-its/src/test/java/org/eclipse/tycho/test/reproducible/ReproducibleArchiveTimestampsTest.java
rename to tycho-its/src/test/java/org/eclipse/tycho/test/reproducible/ReproducibleBuildTest.java
index e870382c64..81563aa4cd 100644
--- a/tycho-its/src/test/java/org/eclipse/tycho/test/reproducible/ReproducibleArchiveTimestampsTest.java
+++ b/tycho-its/src/test/java/org/eclipse/tycho/test/reproducible/ReproducibleBuildTest.java
@@ -9,6 +9,10 @@
package org.eclipse.tycho.test.reproducible;
import java.io.IOException;
+import java.nio.file.FileSystem;
+import java.nio.file.FileSystems;
+import java.nio.file.Files;
+import java.nio.file.Path;
import java.time.Instant;
import java.time.LocalDateTime;
import java.time.OffsetDateTime;
@@ -21,7 +25,7 @@
import org.junit.Assert;
import org.junit.Test;
-public class ReproducibleArchiveTimestampsTest extends AbstractTychoIntegrationTest {
+public class ReproducibleBuildTest extends AbstractTychoIntegrationTest {
// The ZipEntry.getLastModifiedTime() method uses the default timezone to
// convert date and time fields to Instant, so we also use the default timezone
// for the expected timestamp here.
@@ -30,17 +34,17 @@ public class ReproducibleArchiveTimestampsTest extends AbstractTychoIntegrationT
.toInstant(OffsetDateTime.now().getOffset());
/**
- * Check that the timestamp of the files inside the produced archives is equal
- * to the one specified in the "project.build.outputTimestamp" property of the
- * pom file.
+ * Check that the build is reproducible.
*/
@Test
public void test() throws Exception {
- Verifier verifier = getVerifier("reproducible-archive-timestamps");
+ Verifier verifier = getVerifier("reproducible-build");
verifier.executeGoals(List.of("clean", "verify"));
verifier.verifyErrorFreeLog();
- // Check timestamps of files in archives
+ // Check that the timestamp of the files inside the produced archives is equal
+ // to the one specified in the "project.build.outputTimestamp" property of the
+ // pom file.
checkTimestamps(verifier.getBasedir() + "/reproducible.bundle/target/reproducible.bundle-1.0.0.jar");
checkTimestamps(verifier.getBasedir() + "/reproducible.bundle/target/reproducible.bundle-1.0.0-attached.jar");
checkTimestamps(verifier.getBasedir() + "/reproducible.bundle/target/reproducible.bundle-1.0.0-sources.jar");
@@ -51,6 +55,11 @@ public void test() throws Exception {
checkTimestamps(verifier.getBasedir() + "/reproducible.iu/target/reproducible.iu-1.0.0.zip");
checkTimestamps(verifier.getBasedir() + "/reproducible.repository/target/reproducible.repository-1.0.0.zip");
checkTimestamps(verifier.getBasedir() + "/reproducible.repository/target/p2-site.zip");
+
+ // Check that the build qualifier uses the timestamp specified in the
+ // "project.build.outputTimestamp" property of the pom file.
+ checkBuildQualifier(verifier.getBasedir()
+ + "/reproducible.buildqualifier/target/reproducible.buildqualifier-1.0.0-SNAPSHOT.jar");
}
private void checkTimestamps(String file) throws IOException {
@@ -62,4 +71,12 @@ private void checkTimestamps(String file) throws IOException {
}
}
}
+
+ private void checkBuildQualifier(String file) throws IOException {
+ try (FileSystem fileSystem = FileSystems.newFileSystem(Path.of(file))) {
+ Path manifest = fileSystem.getPath("META-INF/MANIFEST.MF");
+ List lines = Files.readAllLines(manifest);
+ Assert.assertTrue(lines.stream().anyMatch(l -> l.equals("Bundle-Version: 1.0.0.202301010000")));
+ }
+ }
}
diff --git a/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/buildversion/DefaultBuildTimestampProvider.java b/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/buildversion/DefaultBuildTimestampProvider.java
index 34b18d8afc..5428792a55 100644
--- a/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/buildversion/DefaultBuildTimestampProvider.java
+++ b/tycho-packaging-plugin/src/main/java/org/eclipse/tycho/buildversion/DefaultBuildTimestampProvider.java
@@ -12,8 +12,11 @@
*******************************************************************************/
package org.eclipse.tycho.buildversion;
+import java.time.Instant;
import java.util.Date;
+import java.util.Optional;
+import org.apache.maven.archiver.MavenArchiver;
import org.apache.maven.execution.MavenSession;
import org.apache.maven.plugin.MojoExecution;
import org.apache.maven.project.MavenProject;
@@ -21,8 +24,10 @@
import org.eclipse.tycho.build.BuildTimestampProvider;
/**
- * Build timestamp provider that returns the same timestamp for all projects, the
- * ${maven.build.timestamp}.
+ * Build timestamp provider that returns the same timestamp for all projects. If
+ * the standard Maven property ${project.build.outputTimestamp} exists, its
+ * value is used for the timestamp. If it does not exist (or cannot be parsed),
+ * the ${maven.build.timestamp} timestamp is used instead.
*/
@Component(role = BuildTimestampProvider.class, hint = DefaultBuildTimestampProvider.ROLE_HINT)
public class DefaultBuildTimestampProvider implements BuildTimestampProvider {
@@ -31,7 +36,14 @@ public class DefaultBuildTimestampProvider implements BuildTimestampProvider {
@Override
public Date getTimestamp(MavenSession session, MavenProject project, MojoExecution execution) {
- return session.getStartTime();
+ // Use the outputTimestamp property value if available for reproducible builds
+ final String outputTimestamp = (String) project.getProperties().get("project.build.outputTimestamp");
+ Optional reproducibleTimestamp = MavenArchiver.parseBuildOutputTimestamp(outputTimestamp);
+ if (reproducibleTimestamp.isPresent()) {
+ return Date.from(reproducibleTimestamp.get());
+ } else {
+ return session.getStartTime();
+ }
}
@Override