Reproducible Builds¶
By default, JAR files generated by Gradle (with or without Shadow) for a single project with the same source code may not be identical to each other. Sometimes it’s desirable to configure a project to consistently output a byte-for-byte identical JAR on every build. Gradle supports this with the following configuration, and Shadow will correctly respect these settings too.
Besides file timestamps and file order, this configuration also ensures that all files in the JAR are set to have the same permissions, irrespective of the locally configured umask.
More information about reproducible builds can be found at reproducible-builds.org.
import java.nio.file.Files
import java.nio.file.attribute.PosixFilePermission
tasks.withType<AbstractArchiveTask>().configureEach {
isPreserveFileTimestamps = false
isReproducibleFileOrder = true
eachFile {
permissions {
val isExec =
Files.getPosixFilePermissions(file.toPath()).contains(PosixFilePermission.OWNER_EXECUTE)
unix(if (isExec) "755" else "644")
}
}
dirPermissions { unix("755") }
}
import java.nio.file.Files
import java.nio.file.attribute.PosixFilePermission
tasks.withType(AbstractArchiveTask).configureEach {
preserveFileTimestamps = false
reproducibleFileOrder = true
eachFile {
permissions {
def isExec =
Files.getPosixFilePermissions(file.toPath()).contains(PosixFilePermission.OWNER_EXECUTE)
unix(isExec ? '755' : '644')
}
}
dirPermissions { unix('755') }
}
One effect that this configuration will have is that the timestamps of all files in the JAR will be reset to a single consistent value. If your code or any files being included into the JAR depend on the timestamps being set accurately within the JAR, then this may not be the correct choice for you.
See the Reproducible archives section in Gradle’s documentation for more information.