blob: 394a4573208390e3e7be03f3876a8cbdd82881f3 [file] [log] [blame]
------
Guide to Configuring for Reproducible Builds
------
Hervé Boutemy
------
2019-11-03
------
~~ Licensed to the Apache Software Foundation (ASF) under one
~~ or more contributor license agreements. See the NOTICE file
~~ distributed with this work for additional information
~~ regarding copyright ownership. The ASF licenses this file
~~ to you under the Apache License, Version 2.0 (the
~~ "License"); you may not use this file except in compliance
~~ with the License. You may obtain a copy of the License at
~~
~~ http://www.apache.org/licenses/LICENSE-2.0
~~
~~ Unless required by applicable law or agreed to in writing,
~~ software distributed under the License is distributed on an
~~ "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
~~ KIND, either express or implied. See the License for the
~~ specific language governing permissions and limitations
~~ under the License.
~~ NOTE: For help with the syntax of this file, see:
~~ http://maven.apache.org/doxia/references/apt-format.html
Configuring for Reproducible Builds
* What are Reproducible Builds?
{{{https://reproducible-builds.org/}Reproducible builds}} are a set of software development practices that create an
independently-verifiable path from source to binary code. A build is <<reproducible>> if given the same source code,
build environment and build instructions, any party can recreate <<bit-by-bit>> identical copies of all specified artifacts.
* How do I configure my Maven build?
There is no Maven version prerequisite. Everything happens at plugin level:
[[1]] Upgrade your plugins to reproducible versions, particularly <<<maven-jar-plugin>>>, <<<maven-source-plugin>>> and <<<maven-assembly-plugin>>> to version 3.2.0 minimum.
[[2]] Add a <<<project.build.outputTimestamp>>> property to the project's pom.xml with the timestamp value that will be used in zip/jar/tar archives:
+--------+
<properties>
<project.build.outputTimestamp>2019-10-02T08:04:00Z</project.build.outputTimestamp>
</properties>
+--------+
[]
You have the basics configured. The output should be reproducible now.
* How to test and fix my Maven build reproducibility?
Using {{{https://github.com/apache/maven-studies/tree/maven-buildinfo-plugin}<<<maven-buildinfo-plugin>>>}},
you can check that two builds give the same output:
[[1]] build and install: <<<mvn clean install -e -DskipTests buildinfo:buildinfo>>>
[[2]] rebuild and check against the previous install: <<<mvn clean verify -e -DskipTests buildinfo:buildinfo -Dreference.repo=central>>>
[]
If something is still not reproducible:
[[1]] Use {{{https://diffoscope.org/}diffoscope}} to find the unstable output. The maven-buildinfo-plugin proposes a command to launch.
[[2]] Find the plugin that generated this output.
[[3]] Check if a reproducible version of the plugin is available.
If not, please open an issue to help plugin maintainers improving Reproducible Builds support at every plugin level.
[]
<<Notice>>: Reproducible Builds for Maven:
* Require <<no version ranges>> in dependencies,
* Generally give <<different results on Windows and Unix>> because of different newlines. (carriage return linefeed on Windows, linefeed on Unixes)
* Generally depend on the <<major version of the JDK>> used to compile. (Even with source/target defined, each major JDK version changes the generated bytecode.)
[]
For detailed explanations, see {{{https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=74682318}Maven "Reproducible/Verifiable Builds" Wiki page}}.
* How Many Projects are Reproducible?
You can have a look at {{{https://github.com/jvm-repo-rebuild/reproducible-central}Reproducible Central}} to see which projects
have been checked as reproducible by rebuilding independently from the reference build published in Central Repository.
You can also check for yourself that you can rebuild locally and get the same result.
* FAQ
* Q. Can the <<<project.build.outputTimestamp>>> property be updated automatically at release time?
A. Yes, you'll need the maven-release-plugin version 3.0.0-M1 or later: see {{{https://issues.apache.org/jira/browse/MRELEASE-1029}MRELEASE-1029}}
* Q. Which additional plugins need to be updated for Reproducible Builds?
A. Here is a simplified list:
*----------------------------------------------------------------------------+-------+--------------+
| <<plugin>> | <<minimum version>> | <<comments>>
*----------------------------------------------------------------------------+-------+--------------+
| {{{/plugins/maven-assembly-plugin/}maven-assembly-plugin}} | 3.2.0 |
*----------------------------------------------------------------------------+-------+--------------+
| {{{/plugins/maven-jar-plugin/}maven-jar-plugin}} | 3.2.0 |
*----------------------------------------------------------------------------+-------+--------------+
| {{{/plugins/maven-javadoc-plugin/}maven-javadoc-plugin}} | 3.2.0 |
*----------------------------------------------------------------------------+-------+--------------+
| {{{/plugin-tools/maven-plugin-plugin/}maven-plugin-plugin}} | 3.5.1 |
*----------------------------------------------------------------------------+-------+--------------+
| {{{/plugins/maven-remote-resources-plugin/}maven-remote-resources-plugin}} | 1.7.0 |
*----------------------------------------------------------------------------+-------+--------------+
| {{{/plugins/maven-shade-plugin/}maven-shade-plugin}} | 3.2.3 |
*----------------------------------------------------------------------------+-------+--------------+
| {{{/plugins/maven-site-plugin/}maven-site-plugin}} | 3.9.0 |
*----------------------------------------------------------------------------+-------+--------------+
| {{{/plugins/maven-source-plugin/}maven-source-plugin}} | 3.2.1 |
*----------------------------------------------------------------------------+-------+--------------+
| {{{/plugins/maven-war-plugin/}maven-war-plugin}} | 3.3.0 |
*----------------------------------------------------------------------------+-------+--------------+
| {{{https://codehaus-plexus.github.io/plexus-containers/plexus-component-metadata/}plexus-component-metadata}} | 2.1.0 |
*----------------------------------------------------------------------------+-------+--------------+
| {{{https://github.com/bndtools/bnd/tree/master/maven/bnd-maven-plugin}bnd-maven-plugin}} | | see {{{https://github.com/bndtools/bnd/tree/master/maven/bnd-maven-plugin#reproducible-builds}configuration instructions}}
*----------------------------------------------------------------------------+-------+--------------+
| Apache Felix {{{https://felix.apache.org/documentation/subprojects/apache-felix-maven-bundle-plugin-bnd.html}maven-bundle-plugin}} | | <<<manifest>>> goal requires <<<\<_removeheaders\>Bnd-LastModified\</_removeheaders\>>>> as configuration <<<instructions>>>
*----------------------------------------------------------------------------+-------+--------------+
| {{{https://docs.spring.io/spring-boot/docs/current/maven-plugin/}springboot-maven-plugin}} | 2.3.0-M4 | not yet for war (because maven-war-plugin not yet ok)
*----------------------------------------------------------------------------+-------+--------------+
For more details, see {{{https://cwiki.apache.org/confluence/pages/viewpage.action?pageId=74682318#Reproducible/VerifiableBuilds-Whataretheissuestosolve?}Maven "Reproducible/Verifiable Builds" Wiki page}}