Collaborative Working Sessions - Born reproducible III
Follow up of Born Reproducible II
In this session, we were more concrete. We came up with how each step in the framework in part II could be implemented for Java (especially maven) ecosystem.
Reference Implementation
https://github.com/jvm-repo-rebuild/reproducible-central.
Step 0
Assume that the clean environment is the GitHub action runner. Although you have more control on your system, the information you care about (like java
version, mvn
version) is know in GitHub action runner as well.
Step 1
- Inputs:
- Java source code
- Build configuration (
pom.xml
): Try to have a minimal working version of that. Remove all the unecessary boilerplate code.
- Outputs:
- all the
jar
s and the SBOMs produced as the build output.
.buildspec
in the reference implementation documents all of this. - all the
Step 2
Build metadata for Java could mean to know all the transitive dependencies and system dependencies (for example, the compression tool for classfiles could be a system dependency)
maybe not too relevant for Java, but it was for C/android
Step 3
- Compare the artifacts listed in
output
with the ones on maven central (rebuild.sh <buildspec>
does that in reference implementation). mvn package
for the first build andmvn package
without snapshot lookup for the second build (rebuild).
Step 4
The differences could be
- order of classfiles in archives
- absolute and relative paths of resources
- differences in classfiles
- difference in manifest files
Reference implementation uses diffoscope
Step 5
A different environment could be Jenkins, CircleCI, a separate GitHub action runner with a different architecture.
In theory, architecture should not matter as jars are supposed to be independent of this.
Step 6
- Let user’s reproduce the CI based on the build step _ Provide tooling for reproducing it. Example: gorebuild is a tool to reproduce go toolchain.
From here on, it gets abstract
Step 7
Document why the artifacts generated are not reproducible and give reasons why they are not. For example, the signature difference. In Step 6, users could be told to strip signature before comparing.
Step 8,9,10 are release related so we did not discuss them in depth.
Step 8
Project README should tell how to verify build attestation.
Step 9
Have your CI sign the artifacts.
Step 10
Implementing deploy policy is a responsibilty taken by the artifact hosting service (maven central) in Java ecosystem. For example, it checks your manifest (pom.xml
) for certain requirements before deploying.
Last takeaway of this session was that the framework was supported by people working in C and android ecosystems. However, commercial code is a hard problem.