Skip to content

Commit 4babe2f

Browse files
committed
Refactor reproducibility check
1 parent 95ef2f5 commit 4babe2f

File tree

1 file changed

+79
-48
lines changed

1 file changed

+79
-48
lines changed

.github/workflows/repro_check.yml

+79-48
Original file line numberDiff line numberDiff line change
@@ -1,79 +1,110 @@
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+
# release 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
16+
runs-on: ubuntu-24.04
17+
18+
strategy:
19+
matrix:
20+
build_dir: [buildA, buildA_extended]
1521

1622
steps:
1723
- 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
24+
uses: actions/checkout@v4
2425

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
26+
- name: Build and store toolchains
4127
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
28+
# Define build function
29+
build_toolchain() {
30+
local dir_name="$1"
31+
echo "Building in $dir_name..."
32+
33+
mkdir "../$dir_name"
34+
cp -r "$(pwd)" "../$dir_name"
35+
pushd "../$dir_name"
36+
37+
# Find source directory
38+
SOURCE_DIR=$(dirname $(find . -maxdepth 2 -name x.py))
39+
40+
# FIXME: Setting channel to nightly because only nightly builds succeed on CI
41+
$SOURCE_DIR/configure --set rust.channel=nightly
42+
43+
# Build rust till stage 2
44+
$SOURCE_DIR/x.py build --stage 2 -j$(($(nproc)*2/3))
45+
46+
# Remove copy of source directory to save space
47+
rm -rf "$SOURCE_DIR"
48+
49+
# Save stage2 directory
50+
STAGE2_DIR=$(find build -name stage2)
51+
cp -r "$STAGE2_DIR" .
52+
echo "Contents of stage2 dir in $dir_name: $(ls stage2)"
53+
54+
# Clean up to save space
55+
rm -rf build
56+
popd
57+
}
58+
59+
# Build both
60+
build_toolchain buildA
61+
build_toolchain buildA_extended
62+
63+
# Compare the two builds
64+
- name: Compare builds
65+
id: compare
5666
run: |
5767
# Ensure the directories exist
5868
if [[ ! -d "../buildA" || ! -d "../buildA_extended" ]]; then
5969
echo "Error: Build directories not found!"
6070
exit 1
6171
fi
6272
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
73+
# Perform a recursive diff between the stage2 directories of both builds
74+
# If there are differences, record the result so we can upload artifacts and then fail later
75+
# The binaries should be identical, so the cause of difference should be analysed and fixed
76+
# appropriately.
77+
if diff -r ../buildA/stage2 ../buildA_extended/stage2; then
78+
echo "No differences found."
79+
echo "has_diff=false" >> $GITHUB_OUTPUT
80+
else
81+
echo "Differences found!"
82+
echo "has_diff=true" >> $GITHUB_OUTPUT
83+
fi
6884
85+
# Upload buildA directory as an artifact (for debugging purposes)
86+
# This artifact contains stage2 folder from buildA. This artifact would
87+
# be helpful to debug reproducibility issue when this test fails.
6988
- name: Upload buildA artifact
89+
if: steps.compare.outputs.has_diff == 'true'
7090
uses: actions/upload-artifact@v4
7191
with:
7292
name: buildA
73-
path: buildA.tar.gz
93+
path: ../buildA
7494

95+
# Upload buildA_extended directory as an artifact (for debugging purposes)
96+
# This artifact contains stage2 folder from buildA_extended. This artifact would
97+
# be helpful to debug reproducibility issue when this test fails.
7598
- name: Upload buildA_extended artifact
99+
if: steps.compare.outputs.has_diff == 'true'
76100
uses: actions/upload-artifact@v4
77101
with:
78102
name: buildA_extended
79-
path: buildA_extended.tar.gz
103+
path: ../buildA_extended
104+
105+
# Fail the job if differences were found between the builds
106+
- name: Fail the job if there are differences
107+
if: steps.compare.outputs.has_diff == 'true'
108+
run: |
109+
echo "Differences found between buildA and buildA_extended, Reproducibility check failed"
110+
exit 1

0 commit comments

Comments
 (0)