build: introduce support for reproducible builds (#1995)

Reproducible builds is an initiative to create an independently-verifiable path from source to binary code [1]. This can be done by:
- Make all archive tasks in gradle reproducible by ignoring timestamp on files [2]
- Preserve the order in side the archives [2]
- Ensure GlobalBuildInfoPlugin.java use [SOURCE_DATE_EPOCH] when available

[SOURCE_DATE_EPOCH]: https://reproducible-builds.org/docs/source-date-epoch/
[1]: https://reproducible-builds.org/
[2]: https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives

Signed-off-by: Leonidas Spyropoulos <artafinde@gmail.com>
This commit is contained in:
Leonidas Spyropoulos 2022-02-02 15:13:54 +00:00 committed by GitHub
parent 1f9517c4ca
commit 6da253b8ff
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 25 additions and 1 deletions

View File

@ -274,6 +274,14 @@ allprojects {
javadoc.options.addStringOption('Xdoclint:all,-missing', '-quiet')
}
// support for reproducible builds
tasks.withType(AbstractArchiveTask).configureEach {
// ignore file timestamps
// be consistent in archive file order
preserveFileTimestamps = false
reproducibleFileOrder = true
}
project.afterEvaluate {
// Handle javadoc dependencies across projects. Order matters: the linksOffline for
// org.opensearch:opensearch must be the last one or all the links for the

View File

@ -121,7 +121,7 @@ public class GlobalBuildInfoPlugin implements Plugin<Project> {
params.setGradleJavaVersion(Jvm.current().getJavaVersion());
params.setGitRevision(gitInfo.getRevision());
params.setGitOrigin(gitInfo.getOrigin());
params.setBuildDate(ZonedDateTime.now(ZoneOffset.UTC));
params.setBuildDate(Util.getBuildDate(ZonedDateTime.now(ZoneOffset.UTC)));
params.setTestSeed(getTestSeed());
params.setIsCi(System.getenv("JENKINS_URL") != null);
params.setIsInternal(isInternal);

View File

@ -48,6 +48,9 @@ import java.io.InputStreamReader;
import java.io.UncheckedIOException;
import java.net.URI;
import java.net.URISyntaxException;
import java.time.Instant;
import java.time.ZoneOffset;
import java.time.ZonedDateTime;
import java.util.Locale;
import java.util.Optional;
import java.util.function.Supplier;
@ -187,4 +190,17 @@ public class Util {
}
};
}
public static ZonedDateTime getBuildDate(ZonedDateTime defaultValue) {
final String sourceDateEpoch = System.getenv("SOURCE_DATE_EPOCH");
if (sourceDateEpoch != null) {
try {
return ZonedDateTime.ofInstant(Instant.ofEpochSecond(Long.parseLong(sourceDateEpoch)), ZoneOffset.UTC);
} catch (NumberFormatException e) {
throw new GradleException("Sysprop [SOURCE_DATE_EPOCH] must be of type [long]", e);
}
} else {
return defaultValue;
}
}
}