Skip to content

Commit 16a7e58

Browse files
committed
Add reproducible timestamps in archives
(cherry picked from commit 048e7a1)
1 parent 3a087b4 commit 16a7e58

File tree

15 files changed

+175
-0
lines changed

15 files changed

+175
-0
lines changed

tycho-extras/tycho-custom-bundle-plugin/src/main/java/org/eclipse/tycho/extras/custombundle/CustomBundleMojo.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,16 @@ public class CustomBundleMojo extends AbstractMojo {
8686
@Parameter
8787
private MavenArchiveConfiguration archive = new MavenArchiveConfiguration();
8888

89+
/**
90+
* Timestamp for reproducible output archive entries, either formatted as ISO
91+
* 8601 extended offset date-time (e.g. in UTC such as '2011-12-03T10:15:30Z' or
92+
* with an offset '2019-10-05T20:37:42+06:00'), or as an int representing
93+
* seconds since the epoch (like <a href=
94+
* "https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
95+
*/
96+
@Parameter(defaultValue = "${project.build.outputTimestamp}")
97+
private String outputTimestamp;
98+
8999
@Component(role = Archiver.class, hint = "jar")
90100
private JarArchiver jarArchiver;
91101

@@ -100,6 +110,9 @@ public void execute() throws MojoExecutionException, MojoFailureException {
100110
archiver.setArchiver(jarArchiver);
101111
archiver.setOutputFile(outputJarFile);
102112

113+
// configure for Reproducible Builds based on outputTimestamp value
114+
archiver.configureReproducibleBuild(outputTimestamp);
115+
103116
try {
104117
archiver.getArchiver().setManifest(updateManifest());
105118

tycho-gpg-plugin/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,11 @@
6464
<artifactId>tycho-core</artifactId>
6565
<version>${project.version}</version>
6666
</dependency>
67+
68+
<dependency>
69+
<groupId>org.apache.maven</groupId>
70+
<artifactId>maven-archiver</artifactId>
71+
</dependency>
6772
</dependencies>
6873

6974
<build>

tycho-gpg-plugin/src/main/java/org/eclipse/tycho/gpg/SignRepositoryArtifactsMojo.java

Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,11 @@
1111

1212
import java.io.File;
1313
import java.io.IOException;
14+
import java.nio.file.attribute.FileTime;
1415
import java.util.Arrays;
1516
import java.util.List;
1617

18+
import org.apache.maven.archiver.MavenArchiver;
1719
import org.apache.maven.plugin.MojoExecutionException;
1820
import org.apache.maven.plugin.MojoFailureException;
1921
import org.apache.maven.plugins.annotations.Component;
@@ -137,6 +139,15 @@ enum PGPKeyBehavior {
137139
@Parameter
138140
private List<String> forceSignature;
139141

142+
/**
143+
* Timestamp for reproducible output archive entries, either formatted as ISO 8601 extended
144+
* offset date-time (e.g. in UTC such as '2011-12-03T10:15:30Z' or with an offset
145+
* '2019-10-05T20:37:42+06:00'), or as an int representing seconds since the epoch (like
146+
* <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
147+
*/
148+
@Parameter(defaultValue = "${project.build.outputTimestamp}")
149+
private String outputTimestamp;
150+
140151
@Component(role = UnArchiver.class, hint = "zip")
141152
private ZipUnArchiver zipUnArchiver;
142153

@@ -208,6 +219,10 @@ public void doExecute() throws MojoExecutionException, MojoFailureException {
208219
}
209220
}
210221

222+
// configure for Reproducible Builds based on outputTimestamp value
223+
MavenArchiver.parseBuildOutputTimestamp(outputTimestamp).map(FileTime::from)
224+
.ifPresent(modifiedTime -> xzArchiver.configureReproducibleBuild(modifiedTime));
225+
211226
xzArchiver.setDestFile(artifactsXmlXz);
212227
xzArchiver.addFile(artifactsXml, artifactsXml.getName());
213228
xzArchiver.createArchive();

tycho-p2-director-plugin/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,11 @@
9696
<artifactId>tycho-p2-plugin</artifactId>
9797
<version>${project.version}</version>
9898
</dependency>
99+
100+
<dependency>
101+
<groupId>org.apache.maven</groupId>
102+
<artifactId>maven-archiver</artifactId>
103+
</dependency>
99104
</dependencies>
100105

101106
<build>

tycho-p2-director-plugin/src/main/java/org/eclipse/tycho/plugins/p2/director/ProductArchiverMojo.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,12 +16,14 @@
1616

1717
import java.io.File;
1818
import java.io.IOException;
19+
import java.nio.file.attribute.FileTime;
1920
import java.util.Map;
2021
import java.util.concurrent.ExecutionException;
2122
import java.util.concurrent.ExecutorCompletionService;
2223
import java.util.concurrent.ExecutorService;
2324
import java.util.concurrent.Executors;
2425

26+
import org.apache.maven.archiver.MavenArchiver;
2527
import org.apache.maven.plugin.MojoExecutionException;
2628
import org.apache.maven.plugin.MojoFailureException;
2729
import org.apache.maven.plugins.annotations.Component;
@@ -134,6 +136,15 @@ public final class ProductArchiverMojo extends AbstractProductMojo {
134136
@Parameter(defaultValue = "true")
135137
private boolean storeCreationTime;
136138

139+
/**
140+
* Timestamp for reproducible output archive entries, either formatted as ISO 8601 extended
141+
* offset date-time (e.g. in UTC such as '2011-12-03T10:15:30Z' or with an offset
142+
* '2019-10-05T20:37:42+06:00'), or as an int representing seconds since the epoch (like
143+
* <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
144+
*/
145+
@Parameter(defaultValue = "${project.build.outputTimestamp}")
146+
private String outputTimestamp;
147+
137148
@Component
138149
private MavenProjectHelper helper;
139150

@@ -223,6 +234,9 @@ private void materialize(Product product, TargetEnvironment env) throws MojoExec
223234
createCommonsCompressTarGz(productArchive, sourceDir);
224235
} else {
225236
Archiver archiver = productArchiver.get();
237+
// configure for Reproducible Builds based on outputTimestamp value
238+
MavenArchiver.parseBuildOutputTimestamp(outputTimestamp).map(FileTime::from)
239+
.ifPresent(modifiedTime -> archiver.configureReproducibleBuild(modifiedTime));
226240
archiver.setDestFile(productArchive);
227241
DefaultFileSet fileSet = new DefaultFileSet(sourceDir);
228242
fileSet.setUsingDefaultExcludes(false);

tycho-p2-repository-plugin/pom.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,11 @@
6060
<artifactId>tycho-core</artifactId>
6161
<version>${project.version}</version>
6262
</dependency>
63+
64+
<dependency>
65+
<groupId>org.apache.maven</groupId>
66+
<artifactId>maven-archiver</artifactId>
67+
</dependency>
6368
</dependencies>
6469
<build>
6570
<plugins>

tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/ArchiveRepositoryMojo.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,9 @@
1515

1616
import java.io.File;
1717
import java.io.IOException;
18+
import java.nio.file.attribute.FileTime;
1819

20+
import org.apache.maven.archiver.MavenArchiver;
1921
import org.apache.maven.plugin.MojoExecutionException;
2022
import org.apache.maven.plugin.MojoFailureException;
2123
import org.apache.maven.plugins.annotations.Component;
@@ -52,6 +54,15 @@ public final class ArchiveRepositoryMojo extends AbstractRepositoryMojo {
5254
@Parameter(defaultValue = "false")
5355
private boolean skipArchive;
5456

57+
/**
58+
* Timestamp for reproducible output archive entries, either formatted as ISO 8601 extended
59+
* offset date-time (e.g. in UTC such as '2011-12-03T10:15:30Z' or with an offset
60+
* '2019-10-05T20:37:42+06:00'), or as an int representing seconds since the epoch (like
61+
* <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
62+
*/
63+
@Parameter(defaultValue = "${project.build.outputTimestamp}")
64+
private String outputTimestamp;
65+
5566
@Component
5667
private FileLockService fileLockService;
5768

@@ -64,6 +75,9 @@ public void execute() throws MojoExecutionException, MojoFailureException {
6475
File destFile = getBuildDirectory().getChild(finalName + ".zip");
6576
try (var repoLock = fileLockService.lockVirtually(repositoryLocation);
6677
var destLock = fileLockService.lockVirtually(destFile);) {
78+
// configure for Reproducible Builds based on outputTimestamp value
79+
MavenArchiver.parseBuildOutputTimestamp(outputTimestamp).map(FileTime::from)
80+
.ifPresent(modifiedTime -> inflater.configureReproducibleBuild(modifiedTime));
6781
inflater.addFileSet(DefaultFileSet.fileSet(repositoryLocation).prefixed(""));
6882
inflater.setDestFile(destFile);
6983
inflater.createArchive();

tycho-p2-repository-plugin/src/main/java/org/eclipse/tycho/plugins/p2/repository/MavenP2SiteMojo.java

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -22,6 +22,7 @@
2222
import java.io.PrintWriter;
2323
import java.nio.charset.StandardCharsets;
2424
import java.nio.file.Files;
25+
import java.nio.file.attribute.FileTime;
2526
import java.util.ArrayList;
2627
import java.util.HashMap;
2728
import java.util.HashSet;
@@ -34,6 +35,7 @@
3435
import java.util.stream.Stream.Builder;
3536

3637
import org.apache.commons.io.FileUtils;
38+
import org.apache.maven.archiver.MavenArchiver;
3739
import org.apache.maven.artifact.Artifact;
3840
import org.apache.maven.artifact.handler.DefaultArtifactHandler;
3941
import org.apache.maven.artifact.resolver.ArtifactResolutionRequest;
@@ -175,6 +177,15 @@ public class MavenP2SiteMojo extends AbstractMojo {
175177
@Parameter(defaultValue = "${project.build.directory}/repository")
176178
private File destination;
177179

180+
/**
181+
* Timestamp for reproducible output archive entries, either formatted as ISO 8601 extended
182+
* offset date-time (e.g. in UTC such as '2011-12-03T10:15:30Z' or with an offset
183+
* '2019-10-05T20:37:42+06:00'), or as an int representing seconds since the epoch (like
184+
* <a href="https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
185+
*/
186+
@Parameter(defaultValue = "${project.build.outputTimestamp}")
187+
private String outputTimestamp;
188+
178189
@Component
179190
private Logger logger;
180191
@Component
@@ -399,6 +410,9 @@ public void execute() throws MojoExecutionException, MojoFailureException {
399410
throw new MojoFailureException("P2 publisher return code was " + result);
400411
}
401412
ZipArchiver archiver = new ZipArchiver();
413+
// configure for Reproducible Builds based on outputTimestamp value
414+
MavenArchiver.parseBuildOutputTimestamp(outputTimestamp).map(FileTime::from)
415+
.ifPresent(modifiedTime -> archiver.configureReproducibleBuild(modifiedTime));
402416
File destFile = new File(buildDirectory, "p2-site.zip");
403417
archiver.setDestFile(destFile);
404418
archiver.addFileSet(new DefaultFileSet(destination));

tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/PackageFeatureMojo.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -115,6 +115,16 @@ public class PackageFeatureMojo extends AbstractTychoPackagingMojo {
115115
@Parameter(defaultValue = "${project.build.directory}/site")
116116
private File target;
117117

118+
/**
119+
* Timestamp for reproducible output archive entries, either formatted as ISO
120+
* 8601 extended offset date-time (e.g. in UTC such as '2011-12-03T10:15:30Z' or
121+
* with an offset '2019-10-05T20:37:42+06:00'), or as an int representing
122+
* seconds since the epoch (like <a href=
123+
* "https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
124+
*/
125+
@Parameter(defaultValue = "${project.build.outputTimestamp}")
126+
private String outputTimestamp;
127+
118128
@Component
119129
private FeatureXmlTransformer featureXmlTransformer;
120130

@@ -171,6 +181,8 @@ public void execute() throws MojoExecutionException, MojoFailureException {
171181
MavenArchiver archiver = new MavenArchiver();
172182
JarArchiver jarArchiver = getJarArchiver();
173183
archiver.setArchiver(jarArchiver);
184+
// configure for Reproducible Builds based on outputTimestamp value
185+
archiver.configureReproducibleBuild(outputTimestamp);
174186
archiver.setOutputFile(outputJar);
175187
jarArchiver.setDestFile(outputJar);
176188

tycho-packaging-plugin/src/main/java/org/eclipse/tycho/packaging/PackageIUMojo.java

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,9 @@
1414

1515
import java.io.File;
1616
import java.io.IOException;
17+
import java.nio.file.attribute.FileTime;
1718

19+
import org.apache.maven.archiver.MavenArchiver;
1820
import org.apache.maven.plugin.MojoExecutionException;
1921
import org.apache.maven.plugin.MojoFailureException;
2022
import org.apache.maven.plugins.annotations.Component;
@@ -50,6 +52,16 @@ public class PackageIUMojo extends AbstractTychoPackagingMojo {
5052
@Parameter(property = "project.basedir", required = true, readonly = true)
5153
private File basedir;
5254

55+
/**
56+
* Timestamp for reproducible output archive entries, either formatted as ISO
57+
* 8601 extended offset date-time (e.g. in UTC such as '2011-12-03T10:15:30Z' or
58+
* with an offset '2019-10-05T20:37:42+06:00'), or as an int representing
59+
* seconds since the epoch (like <a href=
60+
* "https://reproducible-builds.org/docs/source-date-epoch/">SOURCE_DATE_EPOCH</a>).
61+
*/
62+
@Parameter(defaultValue = "${project.build.outputTimestamp}")
63+
private String outputTimestamp;
64+
5365
@Component
5466
private IUXmlTransformer iuTransformer;
5567

@@ -65,6 +77,11 @@ public void execute() throws MojoExecutionException, MojoFailureException {
6577
getLog().info("Skip packaging");
6678
return;
6779
}
80+
81+
// configure for Reproducible Builds based on outputTimestamp value
82+
MavenArchiver.parseBuildOutputTimestamp(outputTimestamp).map(FileTime::from)
83+
.ifPresent(modifiedTime -> zipArchiver.configureReproducibleBuild(modifiedTime));
84+
6885
synchronized (LOCK) {
6986
outputDirectory.mkdirs();
7087

0 commit comments

Comments
 (0)