Skip to content

Commit 67f7590

Browse files
committed
Refactor reproducibility check
1 parent 95ef2f5 commit 67f7590

File tree

1 file changed

+72
-49
lines changed

1 file changed

+72
-49
lines changed

.github/workflows/repro_check.yml

+72-49
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,102 @@
1-
name: Build and Diff Projects
1+
# Workflow that runs after a merge to master, builds toolchain in 2 different
2+
# directories to check for reproducible builds. This check helps track which
3+
# commits cause reproducibility issues. This check should pass before stable
4+
# releases are made.
5+
6+
name: Reproducibility check
27

38
on:
49
push:
5-
branches:
6-
- master
7-
pull_request:
810
branches:
911
- master
1012
- reproducible
1113

1214
jobs:
1315
build_and_compare:
14-
runs-on: ubuntu-latest
15-
16+
runs-on: ubuntu-24.04
1617
steps:
1718
- name: Checkout repository
18-
uses: actions/checkout@v2
19-
20-
- name: Set up Python
21-
uses: actions/setup-python@v2
22-
with:
23-
python-version: '3.x' # Adjust to the version you need
19+
uses: actions/checkout@v4
2420

25-
- name: Build and store buildA binaries
26-
run: |
27-
mkdir ../buildA
28-
cp -r "$(pwd)" ../buildA
29-
pushd ../buildA
30-
SOURCE_DIR=$(dirname $(find . -maxdepth 2 -name x.py))
31-
$SOURCE_DIR/configure --set rust.channel=nightly
32-
$SOURCE_DIR/x.py build --stage 2 -j$(($(nproc)*2/3))
33-
rm -rf $SOURCE_DIR
34-
STAGE2_DIR=`find build -name stage2`
35-
cp -r "$STAGE2_DIR" .
36-
echo "Contents stage 2 dir : `ls stage2`"
37-
rm -rf build
38-
popd
39-
40-
- name: Build and store buildA_extended binaries
21+
- name: Build and store toolchains
4122
run: |
42-
mkdir ../buildA_extended
43-
cp -r "$(pwd)" ../buildA_extended
44-
pushd ../buildA_extended
45-
SOURCE_DIR=$(dirname $(find . -maxdepth 2 -name x.py))
46-
$SOURCE_DIR/configure --set rust.channel=nightly
47-
$SOURCE_DIR/x.py build --stage 2 -j$(($(nproc)*2/3))
48-
rm -rf $SOURCE_DIR
49-
STAGE2_DIR=`find build -name stage2`
50-
cp -r "$STAGE2_DIR" .
51-
echo "Contents stage 2 dir : `ls stage2`"
52-
rm -rf build
53-
popd
54-
55-
- name: Compare builds and archive artifacts
23+
# Define build function
24+
build_toolchain() {
25+
local dir_name="$1"
26+
echo "Building in $dir_name..."
27+
28+
mkdir "../$dir_name"
29+
cp -r . "../$dir_name/rust"
30+
pushd "../$dir_name"
31+
32+
# Find source directory
33+
SOURCE_DIR="./rust"
34+
35+
# FIXME: Setting channel to nightly because only nightly builds succeed on CI
36+
$SOURCE_DIR/configure --set rust.channel=nightly
37+
38+
# Build rust till stage 2
39+
$SOURCE_DIR/x.py build --stage 2 -j$(($(nproc)*2/3))
40+
41+
# Remove copy of source directory to save space
42+
rm -rf "$SOURCE_DIR"
43+
44+
# Save stage2 directory
45+
STAGE2_DIR=$(find build -name stage2)
46+
cp -r "$STAGE2_DIR" .
47+
echo "Contents of stage2 dir in $dir_name: $(ls stage2)"
48+
49+
# Clean up to save space
50+
rm -rf build
51+
popd
52+
}
53+
54+
# Build both
55+
build_toolchain buildA
56+
build_toolchain buildA_extended
57+
58+
# Compare the two builds
59+
- name: Compare builds
60+
id: compare
5661
run: |
5762
# Ensure the directories exist
5863
if [[ ! -d "../buildA" || ! -d "../buildA_extended" ]]; then
5964
echo "Error: Build directories not found!"
6065
exit 1
6166
fi
6267
63-
# Perform a diff between the two builds
64-
diff -r ../buildA/stage2 ../buildA_extended/stage2 || echo "Differences found!"
65-
66-
tar -czf buildA.tar.gz ../buildA
67-
tar -czf buildA_extended.tar.gz ../buildA_extended
68+
# Perform a recursive diff between the stage2 directories of both builds
69+
# If there are differences, record the result so we can upload artifacts and then fail later
70+
# The binaries should be identical, so the cause of difference should be analysed and fixed
71+
# appropriately.
72+
if diff -r ../buildA/stage2 ../buildA_extended/stage2; then
73+
echo "No differences found."
74+
echo "has_diff=false" >> $GITHUB_OUTPUT
75+
else
76+
echo "Differences found!"
77+
echo "has_diff=true" >> $GITHUB_OUTPUT
78+
fi
6879
80+
# Upload buildA and buildA_extended directories as an artifact (for debugging purposes)
81+
# The artifacts contain the stage2 folder from both builds. The artifact are
82+
# helpful to debug the reproducibility issue when this test fails.
6983
- name: Upload buildA artifact
84+
if: steps.compare.outputs.has_diff == 'true'
7085
uses: actions/upload-artifact@v4
7186
with:
7287
name: buildA
73-
path: buildA.tar.gz
88+
path: ../buildA
7489

7590
- name: Upload buildA_extended artifact
91+
if: steps.compare.outputs.has_diff == 'true'
7692
uses: actions/upload-artifact@v4
7793
with:
7894
name: buildA_extended
79-
path: buildA_extended.tar.gz
95+
path: ../buildA_extended
96+
97+
# Fail the job if differences were found between the builds
98+
- name: Fail the job if there are differences
99+
if: steps.compare.outputs.has_diff == 'true'
100+
run: |
101+
echo "Differences found between buildA and buildA_extended, Reproducibility check failed"
102+
exit 1

0 commit comments

Comments
 (0)