Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Make the build reproducible and add a check #102

Merged
merged 1 commit into from
Oct 15, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
38 changes: 38 additions & 0 deletions .github/workflows/reproducible-build-check.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a Java project with Gradle and cache/restore any dependencies to improve the workflow execution time
# For more information see: https://docs.github.com/en/actions/automating-builds-and-tests/building-and-testing-java-with-gradle

name: Java CI Reproducible build check

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]

permissions:
contents: read

jobs:
build:

runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v3
- name: Set up JDK 17
uses: actions/setup-java@v3
with:
java-version: '17'
distribution: 'temurin'
- name: Setup Gradle
uses: gradle/actions/setup-gradle@af1da67850ed9a4cedd57bfd976089dd991e2582 # v4.0.0
- name: Check artifacts
shell: bash
run: |
./gradlew --no-daemon clean publishToMavenLocal --no-build-cache -Dmaven.repo.local=${GITHUB_WORKSPACE}/build1
./gradlew --no-daemon clean publishToMavenLocal --no-build-cache -Dmaven.repo.local=${GITHUB_WORKSPACE}/build2
./ci/compare-build-results.sh ${GITHUB_WORKSPACE}/build1 ${GITHUB_WORKSPACE}/build2
8 changes: 7 additions & 1 deletion buildSrc/src/main/groovy/java-module.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,12 @@ tasks.withType( JavaCompile ).configureEach {javaCompile->
options.warnings false
}

// To force the build produce the same byte-for-byte archives and hence make Hibernate Models build reproducible.
// See also https://docs.gradle.org/current/userguide/working_with_files.html#sec:reproducible_archives
tasks.withType( AbstractArchiveTask ).configureEach {
preserveFileTimestamps = false
reproducibleFileOrder = true
}

// ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
// Javadoc
Expand Down Expand Up @@ -150,4 +156,4 @@ tasks.named( "check" ) {
dependsOn enforceRulesTask
dependsOn tasks.named( "spotlessCheck" )
dependsOn jacocoReportTask
}
}
54 changes: 54 additions & 0 deletions ci/compare-build-results.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
#!/usr/bin/env bash

# This is a simple script to check if builds are reproducible. The steps are:
# 1. Build Hibernate Models with `./gradlew --no-daemon clean publishToMavenLocal --no-build-cache -Dmaven.repo.local=some-path/out/build1`
# 2. Build Hibernate Models with `./gradlew --no-daemon clean publishToMavenLocal --no-build-cache -Dmaven.repo.local=some-path/out/build2` second time pointing to a different local maven repository to publish
# 3. Compare the build results with sh ./ci/compare-build-results.sh some-path/out/build1 some-path/out/build2
# 4. The generated .buildcompare file will also contain the diffscope commands to see/compare the problematic build artifacts
set -xv

outputDir1=$1
outputDir2=$2
outputDir1=${outputDir1%/}
outputDir2=${outputDir2%/}

ok=()
okFiles=()
ko=()
koFiles=()

for f in `find ${outputDir1} -type f | grep -v "javadoc.jar$" | grep -v "maven-metadata-local.xml$" | sort`
do
flocal=${f#$outputDir1}
# echo "comparing ${flocal}"
sha1=`shasum -a 512 $f | cut -f 1 -d ' '`
sha2=`shasum -a 512 $outputDir2$flocal | cut -f 1 -d ' '`
# echo "$sha1"
# echo "$sha2"
if [ "$sha1" = "$sha2" ]; then
ok+=($flocal)
okFiles+=(${flocal##*/})
else
ko+=($flocal)
koFiles+=(${flocal##*/})
fi
done

# generate .buildcompare
buildcompare=".buildcompare"
echo "ok=${#ok[@]}" >> ${buildcompare}
echo "ko=${#ko[@]}" >> ${buildcompare}
echo "okFiles=\"${okFiles[@]}\"" >> ${buildcompare}
echo "koFiles=\"${koFiles[@]}\"" >> ${buildcompare}
echo "" >> ${buildcompare}
echo "# see what caused the mismatch in the checksum by executing the following diffscope commands" >> ${buildcompare}
for f in ${ko[@]}
do
echo "# diffoscope $outputDir1$f $outputDir2$f" >> ${buildcompare}
done

if [ ${#ko[@]} -eq 0 ]; then
exit 0
else
exit 1
fi
Loading