From 49f5da84c1b03f4fbbbea685085ae5d90308ca04 Mon Sep 17 00:00:00 2001
From: B I Mohammed Abbas <bimohammadabbas@gmail.com>
Date: Tue, 15 Apr 2025 13:41:23 +0530
Subject: [PATCH 1/3] Add reproducibility check

---
 .github/workflows/repro_check.yml | 101 ++++++++++++++++++++++++++++++
 1 file changed, 101 insertions(+)
 create mode 100644 .github/workflows/repro_check.yml

diff --git a/.github/workflows/repro_check.yml b/.github/workflows/repro_check.yml
new file mode 100644
index 0000000000000..9a05331fd18fd
--- /dev/null
+++ b/.github/workflows/repro_check.yml
@@ -0,0 +1,101 @@
+# Workflow that runs after a merge to master, builds toolchain in 2 different
+# directories to check for reproducible builds. This check helps track which
+# commits cause reproducibility issues. This check should pass before stable
+# releases are made.
+
+name: Reproducibility check
+
+on:
+  push:
+    branches:
+      - master
+
+jobs:
+  build_and_compare:
+    runs-on: ubuntu-24.04
+    steps:
+      - name: Checkout repository
+        uses: actions/checkout@v4
+
+      - name: Build and store toolchains
+        run: |
+          # Define build function
+          build_toolchain() {
+            local dir_name="$1"
+            echo "Building in $dir_name..."
+
+            mkdir "../$dir_name"
+            cp -r . "../$dir_name/rust"
+            pushd "../$dir_name"
+
+            # Find source directory
+            SOURCE_DIR="./rust"
+
+            # FIXME: Setting channel to nightly because only nightly builds succeed on CI
+            $SOURCE_DIR/configure --set rust.channel=nightly
+
+            # Build rust till stage 2
+            $SOURCE_DIR/x.py build --stage 2
+
+            # Remove copy of source directory to save space
+            rm -rf "$SOURCE_DIR"
+
+            # Save stage2 directory
+            STAGE2_DIR=$(find build -name stage2)
+            cp -r "$STAGE2_DIR" .
+            echo "Contents of stage2 dir in $dir_name: $(ls stage2)"
+
+            # Clean up to save space
+            rm -rf build
+            popd
+          }
+
+          # Build both
+          build_toolchain buildA
+          build_toolchain buildA_extended
+
+# Compare the two builds
+      - name: Compare builds
+        id: compare
+        run: |
+          # Ensure the directories exist
+          if [[ ! -d "../buildA" || ! -d "../buildA_extended" ]]; then
+            echo "Error: Build directories not found!"
+            exit 1
+          fi
+          mv ../buildA ../buildA_extended .
+          # Perform a recursive diff between the stage2 directories of both builds
+          # If there are differences, record the result so we can upload artifacts and then fail later
+          # The binaries should be identical, so the cause of difference should be analysed and fixed
+          # appropriately.
+          if diff -r buildA/stage2 buildA_extended/stage2; then
+            echo "No differences found."
+            echo "has_diff=false" >> $GITHUB_OUTPUT
+          else
+            echo "Differences found!"
+            echo "has_diff=true" >> $GITHUB_OUTPUT
+          fi
+
+# Upload buildA and buildA_extended directories as an artifact (for debugging purposes)
+# The artifacts contain the stage2 folder from both builds. The artifact are
+# helpful to debug the reproducibility issue when this test fails.
+      - name: Upload buildA artifact
+        if: steps.compare.outputs.has_diff == 'true'
+        uses: actions/upload-artifact@v4
+        with:
+          name: buildA
+          path: buildA
+
+      - name: Upload buildA_extended artifact
+        if: steps.compare.outputs.has_diff == 'true'
+        uses: actions/upload-artifact@v4
+        with:
+          name: buildA_extended
+          path: buildA_extended
+
+# Fail the job if differences were found between the builds
+      - name: Fail the job if there are differences
+        if: steps.compare.outputs.has_diff == 'true'
+        run: |
+          echo "Differences found between buildA and buildA_extended, Reproducibility check failed"
+          exit 1

From 4657ddea91a6eb54066c7dabc4f1a659a79891d4 Mon Sep 17 00:00:00 2001
From: B I Mohammed Abbas <bimohammadabbas@gmail.com>
Date: Thu, 8 May 2025 14:19:31 +0530
Subject: [PATCH 2/3] Run reproducibility check for each pr

---
 .github/workflows/repro_check.yml | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/.github/workflows/repro_check.yml b/.github/workflows/repro_check.yml
index 9a05331fd18fd..e70ccb7ba54e1 100644
--- a/.github/workflows/repro_check.yml
+++ b/.github/workflows/repro_check.yml
@@ -6,7 +6,7 @@
 name: Reproducibility check
 
 on:
-  push:
+  pull_request:
     branches:
       - master
 

From a87203191545d8aa1d1cdf9b9b5ee25f51fc0de4 Mon Sep 17 00:00:00 2001
From: B I Mohammed Abbas <bimohammadabbas@gmail.com>
Date: Thu, 8 May 2025 14:21:04 +0530
Subject: [PATCH 3/3] remove nightly build from reproducibility check

---
 .github/workflows/repro_check.yml | 3 ---
 1 file changed, 3 deletions(-)

diff --git a/.github/workflows/repro_check.yml b/.github/workflows/repro_check.yml
index e70ccb7ba54e1..99ef614990d2b 100644
--- a/.github/workflows/repro_check.yml
+++ b/.github/workflows/repro_check.yml
@@ -31,9 +31,6 @@ jobs:
             # Find source directory
             SOURCE_DIR="./rust"
 
-            # FIXME: Setting channel to nightly because only nightly builds succeed on CI
-            $SOURCE_DIR/configure --set rust.channel=nightly
-
             # Build rust till stage 2
             $SOURCE_DIR/x.py build --stage 2