Considering moving to producing 100% reproducible builds for all of my packages.
It seems fairly easy. The following changes are required for the primogenitor:
Stop using maven.build.timestamp. The commit ID is enough!
Use the reproducible-build-maven-plugin
to strip manifest headers such as Built-By
, Build-JDK
, etc, and
repack jar files such that the timestamps of entries are set to known
constant values and the entries are placed into the jar in a
deterministic order.
Strip Bnd-LastModified
and Tool
headers from bundle manifests using
the <_removeheaders>
instruction in the maven-bundle-plugin
configuration.
Stop using version ranges. This may be too painful.
Some early experiments show that this yields byte-for-byte identical jar files on each compile. This is pretty impressive.
The one open issue: Oracle (or OpenJDK's) javac
appears to produce
completely deterministic output; there aren't any embedded timestamps
or other nonsense. However, someone building the packages from
source isn't guaranteed to be using an Oracle JDK. I could use the
Enforcer
plugin to check that the user is using a known-deterministic JDK,
but it would be pretty obnoxious to break builds if they aren't. Perhaps
a warning message ("JDK is not known to produce deterministic output: Build may not be reproducible!")
is enough.