Follow-up to #8391
The _build-info.properties_ file contains a timestamp in the header comment, this leads to non-reproducible builds.
https://docs.spring.io/spring-boot/docs/2.0.5.RELEASE/gradle-plugin/reference/html/#integrating-with-actuator-build-info
springBoot {
buildInfo {
properties {
time = null
}
}
}
Will remove the _build.time_ property, but the timestamp in the header comment will be changed on every build:
#Properties
#Mon Sep 17 17:34:11 CEST 2018
build.artifact=example-artifact
build.group=example-group
build.name=example-name
build.version=1.0.0
Thanks for the report. Nulling out the time is aimed at up-to-date checking rather than repeatability. It works fine for up-to-date checks as Gradle compares the property key-value pairs and doesn't care about any comments. Unfortunately, the writing of the date is baked into java.util.Properties
and can't be disabled. Short of implementing our own class for writing the properties to disk, or using a custom Writer
that suppresses the output of the comment, there's not a lot we can do about this.
Also, the order of the keys could be sorted to be independent of their hash values.
https://docs.gradle.org/current/dsl/org.gradle.api.tasks.WriteProperties.html
- no timestamp comment is generated at the beginning of the file
- the lines in the resulting files are separated by a pre-set separator (defaults to 'n') instead of the system default line separator
- the properties are sorted alphabetically
Thanks for the pointer to WriteProperties
. I wasn't aware of that Gradle task. Unfortunately, the code in question here is shared between our Gradle plugin and our Maven plugin so changing it to depend on something that's Gradle-specific isn't an option. It does, however, open up the option of reworking things to no longer use the shared code and use WriteProperties
in the Gradle case. We've done something similar in other places in the plugin where the shared code didn't work well with Gradle.
This is what I do in the meantime:
springBoot {
mainClassName = 'com.sample.sample.SampleApplication'
buildInfo {
properties {
time = null
}
// Watch https://github.com/spring-projects/spring-boot/issues/14494
doLast {
File f = new File(destinationDir, 'build-info.properties')
f.text = f.filterLine { !it.startsWith('#') }
}
}
}
And I get the same md5 for each jar
In my projects using the gradle plugin v2.0.6.RELEASE, the bootBuildInfo
task always fails the up-to-date check. This has the adverse effect of always triggering the test
task which fires off unit tests.
springBoot {
buildInfo()
}
When following the workaround @pgilad suggested, the up-to-date checks work correctly, and the test
task is not always run.
springBoot {
buildInfo {
properties {
time = null
}
}
}
@merusso This is already discussed above and noted in the documentation that's linked to in the description of the issue:
The default value for
build.time
is the instant at which the project is being built. A side-effect of this is that the task will never be up-to-date. As a result, builds will take longer as more tasks, including the project鈥檚 tests, will have to be executed. Another side-effect is that the task鈥檚 output will always change and, therefore, the build will not be truly repeatable. If you value build performance or repeatability more highly than the accuracy of the build.time property, settime
tonull
or a fixed value.
With thanks to @sbrannen for the new sorted properties support in Framework, this one is now straightforward.
How to make multiple properties null?
@mbarve31 Please ask questions on stackoverflow.com or join us on gitter.im. We prefer to keep the issue tracker for bugs and enhancements.
Most helpful comment
With thanks to @sbrannen for the new sorted properties support in Framework, this one is now straightforward.