Skip to content

Commit cca61d1

Browse files
committed
build(cli): fix reproducible build failures and add nightly workflow
- Hardcode Unix line endings (&#xA;) and use `<fixcrlf>` in the maven-antrun-plugin to prevent OS-specific line separators in dependencies.properties. - Set `<addMavenDescriptor>false</addMavenDescriptor>` in the maven-jar-plugin to prevent OS-specific pom.properties generation. - Add an explicit execution block for maven-jar-plugin before the maven-assembly-plugin to resolve race conditions, ensuring the fresh JAR is built before it gets zipped. - Create .github/workflows/reproducibility.yml to run artifact:compare nightly (excluding the tests module) with a visual Markdown summary.
1 parent 23e2dad commit cca61d1

File tree

2 files changed

+109
-14
lines changed

2 files changed

+109
-14
lines changed
Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
name: Reproducible Build Check
2+
3+
on:
4+
schedule:
5+
- cron: '0 0 * * *'
6+
workflow_dispatch:
7+
8+
jobs:
9+
check:
10+
name: Verify Deterministic Build
11+
runs-on: ubuntu-latest
12+
13+
steps:
14+
- name: Checkout
15+
uses: actions/checkout@v5
16+
with:
17+
ref: main
18+
19+
- name: Set up JDK 21
20+
uses: actions/setup-java@v5
21+
with:
22+
java-version: 21
23+
distribution: 'temurin'
24+
cache: maven
25+
26+
- name: 📦 Install
27+
run: mvn clean install -pl '!tests' -DskipTests -B --no-transfer-progress
28+
29+
- name: 🔍 Verify Reproducibility
30+
run: mvn clean verify artifact:compare -pl '!tests' -DskipTests -B --no-transfer-progress
31+
32+
- name: 📊 Generate Visual Report
33+
if: always()
34+
run: |
35+
echo "## 🔍 Reproducible Build Report" >> $GITHUB_STEP_SUMMARY
36+
37+
ALL_OK_FILES=""
38+
ALL_KO_FILES=""
39+
ALL_IGNORED_FILES=""
40+
41+
# Find all generated comparison files
42+
COMPARE_FILES=$(find . -type f -name "*.buildcompare")
43+
44+
if [ -n "$COMPARE_FILES" ]; then
45+
for COMPARE_FILE in $COMPARE_FILES; do
46+
# Collect filenames instead of just summing the 'ok=' integers
47+
OK_F=$(grep '^okFiles=' "$COMPARE_FILE" | cut -d'=' -f2 | tr -d '"')
48+
KO_F=$(grep '^koFiles=' "$COMPARE_FILE" | cut -d'=' -f2 | tr -d '"')
49+
IGN_F=$(grep '^ignoredFiles=' "$COMPARE_FILE" | cut -d'=' -f2 | tr -d '"')
50+
51+
ALL_OK_FILES="$ALL_OK_FILES $OK_F"
52+
ALL_KO_FILES="$ALL_KO_FILES $KO_F"
53+
ALL_IGNORED_FILES="$ALL_IGNORED_FILES $IGN_F"
54+
done
55+
56+
# Calculate unique counts by splitting strings and using sort -u
57+
TOTAL_OK=$(echo "$ALL_OK_FILES" | tr ' ' '\n' | grep -v '^$' | sort -u | wc -l)
58+
TOTAL_KO=$(echo "$ALL_KO_FILES" | tr ' ' '\n' | grep -v '^$' | sort -u | wc -l)
59+
TOTAL_IGNORED=$(echo "$ALL_IGNORED_FILES" | tr ' ' '\n' | grep -v '^$' | sort -u | wc -l)
60+
61+
# Identify unique failed files for the detailed report
62+
UNIQUE_KO_FILES=$(echo "$ALL_KO_FILES" | tr ' ' '\n' | grep -v '^$' | sort -u)
63+
64+
# Draw the Markdown Table
65+
echo "| Result | Count |" >> $GITHUB_STEP_SUMMARY
66+
echo "|--------|-------|" >> $GITHUB_STEP_SUMMARY
67+
echo "| ✅ **OK** | **$TOTAL_OK** |" >> $GITHUB_STEP_SUMMARY
68+
echo "| ❌ **Failed (KO)** | **$TOTAL_KO** |" >> $GITHUB_STEP_SUMMARY
69+
echo "| ⚠️ **Ignored** | **$TOTAL_IGNORED** |" >> $GITHUB_STEP_SUMMARY
70+
echo "" >> $GITHUB_STEP_SUMMARY
71+
72+
# Provide specific feedback
73+
if [ "$TOTAL_KO" -gt 0 ]; then
74+
echo "### 🚨 Reproducibility Drift Detected!" >> $GITHUB_STEP_SUMMARY
75+
echo "The following files differ from the reference build:" >> $GITHUB_STEP_SUMMARY
76+
echo "\`\`\`text" >> $GITHUB_STEP_SUMMARY
77+
echo "$UNIQUE_KO_FILES" >> $GITHUB_STEP_SUMMARY
78+
echo "\`\`\`" >> $GITHUB_STEP_SUMMARY
79+
else
80+
echo "### 🎉 100% Reproducible!" >> $GITHUB_STEP_SUMMARY
81+
echo "The build is perfectly deterministic across all $TOTAL_OK artifacts." >> $GITHUB_STEP_SUMMARY
82+
fi
83+
else
84+
echo "⚠️ **Could not find any \`.buildcompare\` files.**" >> $GITHUB_STEP_SUMMARY
85+
fi

modules/jooby-cli/pom.xml

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,8 @@
128128
<sortfilter/>
129129
</filterchain>
130130
</loadfile>
131-
<echo message="# dependencies:${line.separator}${filtered.dependencies}" file="${cli.dependencies}" />
131+
<echo message="# dependencies:&#xA;${filtered.dependencies}" file="${cli.dependencies}" />
132+
<fixcrlf srcdir="${project.build.outputDirectory}" includes="dependencies.properties" eol="lf" />
132133
</target>
133134
</configuration>
134135
</execution>
@@ -165,6 +166,28 @@
165166
</execution>
166167
</executions>
167168
</plugin>
169+
<plugin>
170+
<groupId>org.apache.maven.plugins</groupId>
171+
<artifactId>maven-jar-plugin</artifactId>
172+
<version>${maven-jar-plugin.version}</version>
173+
<executions>
174+
<execution>
175+
<id>default-jar</id>
176+
<phase>package</phase>
177+
<goals>
178+
<goal>jar</goal>
179+
</goals>
180+
</execution>
181+
</executions>
182+
<configuration>
183+
<archive>
184+
<manifestEntries>
185+
<Automatic-Module-Name>${Module-Name}</Automatic-Module-Name>
186+
</manifestEntries>
187+
<addMavenDescriptor>false</addMavenDescriptor>
188+
</archive>
189+
</configuration>
190+
</plugin>
168191
<plugin>
169192
<groupId>org.apache.maven.plugins</groupId>
170193
<artifactId>maven-assembly-plugin</artifactId>
@@ -186,19 +209,6 @@
186209
</execution>
187210
</executions>
188211
</plugin>
189-
190-
<plugin>
191-
<groupId>org.apache.maven.plugins</groupId>
192-
<artifactId>maven-jar-plugin</artifactId>
193-
<version>${maven-jar-plugin.version}</version>
194-
<configuration>
195-
<archive>
196-
<manifestEntries>
197-
<Automatic-Module-Name>${Module-Name}</Automatic-Module-Name>
198-
</manifestEntries>
199-
</archive>
200-
</configuration>
201-
</plugin>
202212
</plugins>
203213
</build>
204214
</project>

0 commit comments

Comments
 (0)