Feat/001 reproducible build timestamp - #2
Open
hendrikebbers wants to merge 10 commits into
Open
Conversation
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Add a fixed, date-granular timestamp literal to the parent properties. It is inherited by every child project, so a third party can rebuild a release byte-identically from the tag with a plain `./mvnw -Pfull-build clean verify` and no build flags. The value describes the java-parent release an artifact was built against, not the time the build ran; Git-Commit-Time remains the deterministic answer to "when did this source state come into being". Refs docs/specs/001-reproducible-build-timestamp Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Both workflows computed the timestamp from the tag commit and passed it as -Dproject.build.outputTimestamp. That flag is invisible outside this organisation, so a third party checking out a release tag could never arrive at the published bytes — the reproducibility claim failed on first contact with an external verifier. The value now comes from the parent POM, so CI runs the same command the README documents, apart from deployment arguments. Refs docs/specs/001-reproducible-build-timestamp Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
release.sh now rewrites project.build.outputTimestamp to the release date before the verification build, so the bytes verified locally are the bytes CI publishes, and the release commit carries version and timestamp together. versions:set-property performs no sanity checks — measured: it exits 0 and changes nothing when the property is absent, so `set -e` would not catch it. An explicit guard re-reads the value and aborts on mismatch, which prevents tagging a release whose published artifacts no rebuild could ever match. The next-snapshot bump deliberately leaves the timestamp alone. Refs docs/specs/001-reproducible-build-timestamp Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Describe how a third party verifies a release with no build flags, warn that a -D flag or a child-POM override silently defeats that, and record Git-Commit-Time as the deterministic replacement for any buildTime field. The promise is deliberately narrow: same source plus same toolchain. Behaviour across differing JDK patch versions has not been measured, so it is not claimed. Known limitations point at docs/TODO.md. Refs docs/specs/001-reproducible-build-timestamp Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
14 checks on a throwaway fixture inheriting the modified parent, all passing: five artifacts byte-identical across two flagless builds, inherited stamp confirmed, override precedence confirmed as CLI > child POM > parent POM, and a build without .git succeeding with an identical stamp. Also note in the README that Git-* manifest entries are present but empty when building outside a Git checkout — deterministic, but only meaningful for builds from a checkout. Refs docs/specs/001-reproducible-build-timestamp Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The README claimed the verification command is "exactly what CI runs", but CI runs `clean deploy` with deployment arguments. In a document whose entire purpose is external verifiability, an imprecise claim is the wrong thing to wave through. The steps.md coverage table marked "a child pinning an older parent is unaffected" as documented in the README, which it was not. Added it to the known limitations — it is the current state of both downstream consumers. Also record the measured timezone/locale result, which moves that scenario from inspection to execution. Refs docs/specs/001-reproducible-build-timestamp Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
The guard compares help:evaluate output against an expected string. Without -B, Maven may emit progress or colour output into that stream and the comparison would fail a release for no reason. Batch mode makes the value deterministic. Refs docs/specs/001-reproducible-build-timestamp Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
This pull request implements and documents reproducible builds for all Java projects inheriting from this parent POM. The main change is to fix the
project.build.outputTimestampproperty as a literal in the parentpom.xml, maintained byrelease.shfor each release. This ensures that any third party can rebuild artifacts from a release tag and obtain byte-identical results, without needing insider knowledge or special build flags. The release and snapshot workflows are updated to remove timestamp overrides, and comprehensive documentation is added to the README and specs.Reproducible Build Infrastructure:
<project.build.outputTimestamp>as a fixed property in the parentpom.xml, with detailed comments explaining its purpose, inheritance, and maintenance byrelease.sh(pom.xml).release.shto automatically set and verify the timestamp property to the release date before building artifacts, aborting if the property is not correctly set. Also clarified that the timestamp is not updated for snapshot bumps, and added comments for clarity (release.sh). [1] [2]CI Workflow Updates:
project.build.outputTimestampfrom both the release and snapshot GitHub Actions workflows, ensuring the build process matches what is documented for external users (.github/workflows/release.yml,.github/workflows/snapshot.yml). [1] [2]Documentation Improvements:
README.md, describing the guarantees, verification process, limitations, and the distinction between the timestamp property and actual build time. Updated the build conventions section and clarified the release process to include timestamp pinning (README.md). [1] [2]docs/specs/INDEX.md).docs/specs/001-reproducible-build-timestamp/steps.md).