From d128c07b5302b20ef56785c6a3703d64e4b183de Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 12:00:11 +0300 Subject: [PATCH 01/22] ci: add breaking change detector --- .../workflows/breaking_changes_detector.yml | 52 +++++++++++++++++++ 1 file changed, 52 insertions(+) create mode 100644 .github/workflows/breaking_changes_detector.yml diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml new file mode 100644 index 0000000000000..7f9ae616be235 --- /dev/null +++ b/.github/workflows/breaking_changes_detector.yml @@ -0,0 +1,52 @@ +name: "Detect breaking changes" + +on: + pull_request: + branches: + - main + +jobs: + check-semver: + name: Check semver + runs-on: ubuntu-latest + outputs: + logs: ${{ steps.check_semver.outputs.logs }} + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Run cargo-semver-checks + id: check_semver + # Fork https://github.com/obi1kenobi/cargo-semver-checks-action/pull/65 + uses: orhun/cargo-semver-checks-action@cc19b888f2062f8cc964c1d52f7f29d910becb31 + + comment-on-pr: + name: Comment on pull request + runs-on: ubuntu-latest + needs: check-semver + if: always() + permissions: + pull-requests: write + steps: + - name: Comment + if: ${{ needs.check-semver.result != 'success' }} + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: pr-semver-check-error + message: | + Thank you for opening this pull request! + + Reviewer note: [cargo-semver-checks](https://github.com/obi1kenobi/cargo-semver-checks) reported the current version number is not SemVer-compatible with the changes made since the last release. + + Details: + + ``` + ${{ needs.check-semver.outputs.logs }} + ``` + + - name: Delete comment + if: ${{ needs.check-semver.result == 'success' }} + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: pr-semver-check-error + delete: true From 968fc570ebae30d0ac9ba7b1048dd43e3a53bf88 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 12:04:53 +0300 Subject: [PATCH 02/22] ci: run manually for now --- .../workflows/breaking_changes_detector.yml | 19 +++++++++++++++++-- 1 file changed, 17 insertions(+), 2 deletions(-) diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index 7f9ae616be235..755e1f1a257ad 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -14,11 +14,26 @@ jobs: steps: - name: Checkout uses: actions/checkout@v4 + with: + fetch-depth: 0 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Install cargo-semver-checks + run: cargo install cargo-semver-checks - name: Run cargo-semver-checks id: check_semver - # Fork https://github.com/obi1kenobi/cargo-semver-checks-action/pull/65 - uses: orhun/cargo-semver-checks-action@cc19b888f2062f8cc964c1d52f7f29d910becb31 + run: | + set +e + cargo semver-checks --baseline-rev origin/main 2>&1 | tee /tmp/semver-output.txt + EXIT_CODE=${PIPESTATUS[0]} + OUTPUT=$(sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt) + echo "logs<> "$GITHUB_OUTPUT" + echo "$OUTPUT" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + exit $EXIT_CODE comment-on-pr: name: Comment on pull request From 3500fee66ac5d4590e27dccc312ad51698c7630f Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 12:12:56 +0300 Subject: [PATCH 03/22] add to existing ci job so i can test the workflow --- .github/workflows/large_files.yml | 61 +++++++++++++++++++++++++++++++ 1 file changed, 61 insertions(+) diff --git a/.github/workflows/large_files.yml b/.github/workflows/large_files.yml index 12a5599189216..41c2d35defdb2 100644 --- a/.github/workflows/large_files.yml +++ b/.github/workflows/large_files.yml @@ -26,6 +26,67 @@ on: merge_group: jobs: + + check-semver: + name: Check semver + runs-on: ubuntu-latest + outputs: + logs: ${{ steps.check_semver.outputs.logs }} + steps: + - name: Checkout + uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 + with: + fetch-depth: 0 + + - name: Install Rust toolchain + uses: dtolnay/rust-toolchain@stable + + - name: Install cargo-semver-checks + run: cargo install cargo-semver-checks + + - name: Run cargo-semver-checks + id: check_semver + run: | + set +e + cargo semver-checks --baseline-rev origin/main 2>&1 | tee /tmp/semver-output.txt + EXIT_CODE=${PIPESTATUS[0]} + OUTPUT=$(sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt) + echo "logs<> "$GITHUB_OUTPUT" + echo "$OUTPUT" >> "$GITHUB_OUTPUT" + echo "EOF" >> "$GITHUB_OUTPUT" + exit $EXIT_CODE + + comment-on-pr: + name: Comment on pull request + runs-on: ubuntu-latest + needs: check-semver + if: always() + permissions: + pull-requests: write + steps: + - name: Comment + if: ${{ needs.check-semver.result != 'success' }} + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: pr-semver-check-error + message: | + Thank you for opening this pull request! + + Reviewer note: [cargo-semver-checks](https://github.com/obi1kenobi/cargo-semver-checks) reported the current version number is not SemVer-compatible with the changes made since the last release. + + Details: + + ``` + ${{ needs.check-semver.outputs.logs }} + ``` + + - name: Delete comment + if: ${{ needs.check-semver.result == 'success' }} + uses: marocchino/sticky-pull-request-comment@v2 + with: + header: pr-semver-check-error + delete: true + check-files: runs-on: ubuntu-slim steps: From b0f7cdfe926736cc733b985986ed69d81e6f6807 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 12:19:31 +0300 Subject: [PATCH 04/22] add permission --- .github/workflows/breaking_changes_detector.yml | 4 ++++ .github/workflows/large_files.yml | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index 755e1f1a257ad..96dd56a8379b4 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -5,6 +5,9 @@ on: branches: - main +permissions: + contents: read + jobs: check-semver: name: Check semver @@ -41,6 +44,7 @@ jobs: needs: check-semver if: always() permissions: + contents: read pull-requests: write steps: - name: Comment diff --git a/.github/workflows/large_files.yml b/.github/workflows/large_files.yml index 41c2d35defdb2..cbb93405f2305 100644 --- a/.github/workflows/large_files.yml +++ b/.github/workflows/large_files.yml @@ -25,6 +25,9 @@ on: pull_request: merge_group: +permissions: + contents: read + jobs: check-semver: @@ -62,6 +65,7 @@ jobs: needs: check-semver if: always() permissions: + contents: read pull-requests: write steps: - name: Comment From dcb3cfcc9125b726b9b4c167d524bc798533a796 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 12:34:03 +0300 Subject: [PATCH 05/22] try running --- .github/workflows/large_files.yml | 65 ------------------------------- ci/scripts/rust_clippy.sh | 11 ++++++ 2 files changed, 11 insertions(+), 65 deletions(-) diff --git a/.github/workflows/large_files.yml b/.github/workflows/large_files.yml index cbb93405f2305..12a5599189216 100644 --- a/.github/workflows/large_files.yml +++ b/.github/workflows/large_files.yml @@ -25,72 +25,7 @@ on: pull_request: merge_group: -permissions: - contents: read - jobs: - - check-semver: - name: Check semver - runs-on: ubuntu-latest - outputs: - logs: ${{ steps.check_semver.outputs.logs }} - steps: - - name: Checkout - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2 - with: - fetch-depth: 0 - - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@stable - - - name: Install cargo-semver-checks - run: cargo install cargo-semver-checks - - - name: Run cargo-semver-checks - id: check_semver - run: | - set +e - cargo semver-checks --baseline-rev origin/main 2>&1 | tee /tmp/semver-output.txt - EXIT_CODE=${PIPESTATUS[0]} - OUTPUT=$(sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt) - echo "logs<> "$GITHUB_OUTPUT" - echo "$OUTPUT" >> "$GITHUB_OUTPUT" - echo "EOF" >> "$GITHUB_OUTPUT" - exit $EXIT_CODE - - comment-on-pr: - name: Comment on pull request - runs-on: ubuntu-latest - needs: check-semver - if: always() - permissions: - contents: read - pull-requests: write - steps: - - name: Comment - if: ${{ needs.check-semver.result != 'success' }} - uses: marocchino/sticky-pull-request-comment@v2 - with: - header: pr-semver-check-error - message: | - Thank you for opening this pull request! - - Reviewer note: [cargo-semver-checks](https://github.com/obi1kenobi/cargo-semver-checks) reported the current version number is not SemVer-compatible with the changes made since the last release. - - Details: - - ``` - ${{ needs.check-semver.outputs.logs }} - ``` - - - name: Delete comment - if: ${{ needs.check-semver.result == 'success' }} - uses: marocchino/sticky-pull-request-comment@v2 - with: - header: pr-semver-check-error - delete: true - check-files: runs-on: ubuntu-slim steps: diff --git a/ci/scripts/rust_clippy.sh b/ci/scripts/rust_clippy.sh index f8b5c0852fa30..2b41d2561ac5f 100755 --- a/ci/scripts/rust_clippy.sh +++ b/ci/scripts/rust_clippy.sh @@ -25,6 +25,16 @@ CLIPPY_FEATURES="avro,integration-tests,extended_tests" CLIPPY_ARGS=(--all-targets --workspace --features "$CLIPPY_FEATURES") CLIPPY_LINT_ARGS=(-- -D warnings) +CURRENT=$(pwd) + +cd "$SCRIPT_DIR/../.." || exit 1 + +set +e +cargo install cargo-semver-checks +cargo semver-checks --baseline-rev origin/main + +cd ${CURRENT} || exit 1 + source "${SCRIPT_DIR}/utils/git.sh" MODE="check" @@ -74,3 +84,4 @@ CLIPPY_CMD+=("${CLIPPY_ARGS[@]}" "${CLIPPY_LINT_ARGS[@]}") echo "[${SCRIPT_NAME}] \`${CLIPPY_CMD[*]}\`" "${CLIPPY_CMD[@]}" + From 8ec278a5a0177c18ae32e53c8426fa66968edc18 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 12:49:33 +0300 Subject: [PATCH 06/22] fetch main --- .github/workflows/breaking_changes_detector.yml | 3 +++ ci/scripts/rust_clippy.sh | 8 ++++++++ 2 files changed, 11 insertions(+) diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index 96dd56a8379b4..2f1a3ea73636c 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -20,6 +20,9 @@ jobs: with: fetch-depth: 0 + - name: Fetch main branch + run: git fetch https://github.com/${{ github.repository }}.git main:refs/remotes/origin/main + - name: Install Rust toolchain uses: dtolnay/rust-toolchain@stable diff --git a/ci/scripts/rust_clippy.sh b/ci/scripts/rust_clippy.sh index 2b41d2561ac5f..a80e076cc33f2 100755 --- a/ci/scripts/rust_clippy.sh +++ b/ci/scripts/rust_clippy.sh @@ -30,9 +30,17 @@ CURRENT=$(pwd) cd "$SCRIPT_DIR/../.." || exit 1 set +e +echo "Fetching main branch for semver checks..." +git fetch https://github.com/apache/datafusion.git main:refs/remotes/origin/main +echo "installing cargo-semver-checks..." cargo install cargo-semver-checks + +echo "Running cargo-semver-checks against origin/main..." cargo semver-checks --baseline-rev origin/main + +echo "Running cargo clippy..." + cd ${CURRENT} || exit 1 source "${SCRIPT_DIR}/utils/git.sh" From e15d6a7a582c91626d272286d40bf5f2e2e86cc4 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:02:03 +0300 Subject: [PATCH 07/22] run on all branches --- .github/workflows/breaking_changes_detector.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index 2f1a3ea73636c..ea2e1ac3d4e60 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -2,8 +2,8 @@ name: "Detect breaking changes" on: pull_request: - branches: - - main +# branches: +# - main permissions: contents: read From 129e18025d675f7c6f2d660a6a2ef785f9073670 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:02:29 +0300 Subject: [PATCH 08/22] run on changed crates --- .../workflows/breaking_changes_detector.yml | 33 ++++++++++++++++++- 1 file changed, 32 insertions(+), 1 deletion(-) diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index ea2e1ac3d4e60..010d12dba6fad 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -29,11 +29,42 @@ jobs: - name: Install cargo-semver-checks run: cargo install cargo-semver-checks + - name: Determine changed crates + id: changed_crates + run: | + # Get workspace members from root Cargo.toml, excluding non-public crates + MEMBERS=$(sed -n '/^members = \[/,/\]/p' Cargo.toml | grep '"' | sed 's/.*"\(.*\)".*/\1/' \ + | grep -v -e '^benchmarks$' -e '^test-utils$' -e '^datafusion/sqllogictest$' -e '^datafusion/doc$') + + # Get changed files compared to main + CHANGED_FILES=$(git diff --name-only origin/main...HEAD) + + # Check which workspace members have changes + PACKAGES="" + for member in $MEMBERS; do + if echo "$CHANGED_FILES" | grep -q "^${member}/"; then + pkg=$(grep '^name\s*=' "$member/Cargo.toml" | head -1 | sed 's/.*=\s*"\(.*\)"/\1/') + if [ -n "$pkg" ]; then + PACKAGES="$PACKAGES $pkg" + fi + fi + done + + PACKAGES=$(echo "$PACKAGES" | xargs) + echo "packages=$PACKAGES" >> "$GITHUB_OUTPUT" + echo "Changed crates: $PACKAGES" + - name: Run cargo-semver-checks id: check_semver + if: steps.changed_crates.outputs.packages != '' run: | set +e - cargo semver-checks --baseline-rev origin/main 2>&1 | tee /tmp/semver-output.txt + ARGS="" + for pkg in ${{ steps.changed_crates.outputs.packages }}; do + ARGS="$ARGS --package $pkg" + done + + cargo semver-checks --baseline-rev origin/main $ARGS 2>&1 | tee /tmp/semver-output.txt EXIT_CODE=${PIPESTATUS[0]} OUTPUT=$(sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt) echo "logs<> "$GITHUB_OUTPUT" From 0a863bdf2a80dd5d0354ba3add71e2fe6be3e719 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:04:29 +0300 Subject: [PATCH 09/22] only if changed --- .github/workflows/breaking_changes_detector.yml | 14 ++++++++------ 1 file changed, 8 insertions(+), 6 deletions(-) diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index 010d12dba6fad..a88f7fc173650 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -23,12 +23,6 @@ jobs: - name: Fetch main branch run: git fetch https://github.com/${{ github.repository }}.git main:refs/remotes/origin/main - - name: Install Rust toolchain - uses: dtolnay/rust-toolchain@stable - - - name: Install cargo-semver-checks - run: cargo install cargo-semver-checks - - name: Determine changed crates id: changed_crates run: | @@ -54,6 +48,14 @@ jobs: echo "packages=$PACKAGES" >> "$GITHUB_OUTPUT" echo "Changed crates: $PACKAGES" + - name: Install Rust toolchain + if: steps.changed_crates.outputs.packages != '' + uses: dtolnay/rust-toolchain@stable + + - name: Install cargo-semver-checks + if: steps.changed_crates.outputs.packages != '' + run: cargo install cargo-semver-checks + - name: Run cargo-semver-checks id: check_semver if: steps.changed_crates.outputs.packages != '' From b3b6dde617b7635a29086efdb9084a599d114613 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:14:51 +0300 Subject: [PATCH 10/22] compare against last commit --- .../workflows/breaking_changes_detector.yml | 10 ++--- ci/scripts/rust_clippy.sh | 40 ++++++++++++++++--- 2 files changed, 39 insertions(+), 11 deletions(-) diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index a88f7fc173650..65830e19877d0 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -20,8 +20,8 @@ jobs: with: fetch-depth: 0 - - name: Fetch main branch - run: git fetch https://github.com/${{ github.repository }}.git main:refs/remotes/origin/main + - name: Fetch base branch + run: git fetch https://github.com/${{ github.repository }}.git ${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }} - name: Determine changed crates id: changed_crates @@ -30,8 +30,8 @@ jobs: MEMBERS=$(sed -n '/^members = \[/,/\]/p' Cargo.toml | grep '"' | sed 's/.*"\(.*\)".*/\1/' \ | grep -v -e '^benchmarks$' -e '^test-utils$' -e '^datafusion/sqllogictest$' -e '^datafusion/doc$') - # Get changed files compared to main - CHANGED_FILES=$(git diff --name-only origin/main...HEAD) + # Get changed files compared to base + CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) # Check which workspace members have changes PACKAGES="" @@ -66,7 +66,7 @@ jobs: ARGS="$ARGS --package $pkg" done - cargo semver-checks --baseline-rev origin/main $ARGS 2>&1 | tee /tmp/semver-output.txt + cargo semver-checks --baseline-rev origin/${{ github.base_ref }} $ARGS 2>&1 | tee /tmp/semver-output.txt EXIT_CODE=${PIPESTATUS[0]} OUTPUT=$(sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt) echo "logs<> "$GITHUB_OUTPUT" diff --git a/ci/scripts/rust_clippy.sh b/ci/scripts/rust_clippy.sh index a80e076cc33f2..0f588ee5e1d3e 100755 --- a/ci/scripts/rust_clippy.sh +++ b/ci/scripts/rust_clippy.sh @@ -30,13 +30,41 @@ CURRENT=$(pwd) cd "$SCRIPT_DIR/../.." || exit 1 set +e -echo "Fetching main branch for semver checks..." -git fetch https://github.com/apache/datafusion.git main:refs/remotes/origin/main -echo "installing cargo-semver-checks..." -cargo install cargo-semver-checks -echo "Running cargo-semver-checks against origin/main..." -cargo semver-checks --baseline-rev origin/main +# Get workspace members from root Cargo.toml, excluding non-public crates +MEMBERS=$(sed -n '/^members = \[/,/\]/p' Cargo.toml | grep '"' | sed 's/.*"\(.*\)".*/\1/' \ + | grep -v -e '^benchmarks$' -e '^test-utils$' -e '^datafusion/sqllogictest$' -e '^datafusion/doc$') + +# Get changed files compared to main +CHANGED_FILES=$(git diff --name-only HEAD~1...HEAD) + +# Check which workspace members have changes +PACKAGES="" +for member in $MEMBERS; do + if echo "$CHANGED_FILES" | grep -q "^${member}/"; then + pkg=$(grep '^name\s*=' "$member/Cargo.toml" | head -1 | sed 's/.*=\s*"\(.*\)"/\1/') + if [ -n "$pkg" ]; then + PACKAGES="$PACKAGES $pkg" + fi + fi +done +PACKAGES=$(echo "$PACKAGES" | xargs) +echo "Changed crates: $PACKAGES" + +if [ -n "$PACKAGES" ]; then + echo "Installing cargo-semver-checks..." + cargo install cargo-semver-checks + + ARGS="" + for pkg in $PACKAGES; do + ARGS="$ARGS --package $pkg" + done + + echo "Running cargo-semver-checks against origin/main..." + cargo semver-checks --baseline-rev HEAD~1 $ARGS +else + echo "No public crates changed, skipping semver checks." +fi echo "Running cargo clippy..." From 95189dee9ad1951474e7e2e72a6d97d7a20f0183 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:18:08 +0300 Subject: [PATCH 11/22] test: add temporary public function for semver breaking change testing Co-Authored-By: Claude Opus 4.6 (1M context) --- datafusion/common-runtime/src/lib.rs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/datafusion/common-runtime/src/lib.rs b/datafusion/common-runtime/src/lib.rs index cf45ccf3ef63a..021bed525a857 100644 --- a/datafusion/common-runtime/src/lib.rs +++ b/datafusion/common-runtime/src/lib.rs @@ -34,3 +34,9 @@ pub use join_set::JoinSet; pub use trace_utils::{ JoinSetTracer, JoinSetTracerError, set_join_set_tracer, trace_block, trace_future, }; + +/// Temporary public function to test semver breaking change detection. +/// TODO: Remove this before merging. +pub fn semver_test_function() -> &'static str { + "this will be removed to trigger a breaking change" +} From 97ee5b58ea0ed8a6f90ee6c01c0ee3fcaf2d8918 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:18:18 +0300 Subject: [PATCH 12/22] test: remove public function to trigger semver breaking change Co-Authored-By: Claude Opus 4.6 (1M context) --- datafusion/common-runtime/src/lib.rs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/datafusion/common-runtime/src/lib.rs b/datafusion/common-runtime/src/lib.rs index 021bed525a857..bb354d0288578 100644 --- a/datafusion/common-runtime/src/lib.rs +++ b/datafusion/common-runtime/src/lib.rs @@ -33,10 +33,4 @@ pub use common::SpawnedTask; pub use join_set::JoinSet; pub use trace_utils::{ JoinSetTracer, JoinSetTracerError, set_join_set_tracer, trace_block, trace_future, -}; - -/// Temporary public function to test semver breaking change detection. -/// TODO: Remove this before merging. -pub fn semver_test_function() -> &'static str { - "this will be removed to trigger a breaking change" -} +}; \ No newline at end of file From d5b19855f84cef878a231259b5db80306096f364 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:27:46 +0300 Subject: [PATCH 13/22] fix --- ci/scripts/rust_clippy.sh | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/ci/scripts/rust_clippy.sh b/ci/scripts/rust_clippy.sh index 0f588ee5e1d3e..32bf52ef36165 100755 --- a/ci/scripts/rust_clippy.sh +++ b/ci/scripts/rust_clippy.sh @@ -31,12 +31,15 @@ cd "$SCRIPT_DIR/../.." || exit 1 set +e +BASELINE_REV=$(git rev-parse HEAD~1) +echo "Baseline revision: $BASELINE_REV" + # Get workspace members from root Cargo.toml, excluding non-public crates MEMBERS=$(sed -n '/^members = \[/,/\]/p' Cargo.toml | grep '"' | sed 's/.*"\(.*\)".*/\1/' \ | grep -v -e '^benchmarks$' -e '^test-utils$' -e '^datafusion/sqllogictest$' -e '^datafusion/doc$') -# Get changed files compared to main -CHANGED_FILES=$(git diff --name-only HEAD~1...HEAD) +# Get changed files compared to baseline +CHANGED_FILES=$(git diff --name-only "$BASELINE_REV"..HEAD) # Check which workspace members have changes PACKAGES="" @@ -61,7 +64,7 @@ if [ -n "$PACKAGES" ]; then done echo "Running cargo-semver-checks against origin/main..." - cargo semver-checks --baseline-rev HEAD~1 $ARGS + cargo semver-checks --baseline-rev "$BASELINE_REV" $ARGS else echo "No public crates changed, skipping semver checks." fi From 910501cfb87d80ecc57db3024d027b75ef4098ac Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:28:49 +0300 Subject: [PATCH 14/22] test: re-add temporary public function for semver testing Co-Authored-By: Claude Opus 4.6 (1M context) --- datafusion/common-runtime/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/datafusion/common-runtime/src/lib.rs b/datafusion/common-runtime/src/lib.rs index bb354d0288578..982a836d2eb74 100644 --- a/datafusion/common-runtime/src/lib.rs +++ b/datafusion/common-runtime/src/lib.rs @@ -33,4 +33,9 @@ pub use common::SpawnedTask; pub use join_set::JoinSet; pub use trace_utils::{ JoinSetTracer, JoinSetTracerError, set_join_set_tracer, trace_block, trace_future, -}; \ No newline at end of file +}; + +/// Temporary public function to test semver breaking change detection. +pub fn semver_test_function() -> &'static str { + "this will be removed to trigger a breaking change" +} \ No newline at end of file From f40c07a862feeb261ba1ad5b3e5d533d46b94e08 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:29:40 +0300 Subject: [PATCH 15/22] test: remove public function to trigger semver breaking change Co-Authored-By: Claude Opus 4.6 (1M context) --- datafusion/common-runtime/src/lib.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/datafusion/common-runtime/src/lib.rs b/datafusion/common-runtime/src/lib.rs index 982a836d2eb74..bb354d0288578 100644 --- a/datafusion/common-runtime/src/lib.rs +++ b/datafusion/common-runtime/src/lib.rs @@ -33,9 +33,4 @@ pub use common::SpawnedTask; pub use join_set::JoinSet; pub use trace_utils::{ JoinSetTracer, JoinSetTracerError, set_join_set_tracer, trace_block, trace_future, -}; - -/// Temporary public function to test semver breaking change detection. -pub fn semver_test_function() -> &'static str { - "this will be removed to trigger a breaking change" -} \ No newline at end of file +}; \ No newline at end of file From 65779f4f0a3772e393498d70f9c170e45d886473 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:44:44 +0300 Subject: [PATCH 16/22] fix --- ci/scripts/rust_clippy.sh | 2 ++ 1 file changed, 2 insertions(+) diff --git a/ci/scripts/rust_clippy.sh b/ci/scripts/rust_clippy.sh index 32bf52ef36165..fd0b756397141 100755 --- a/ci/scripts/rust_clippy.sh +++ b/ci/scripts/rust_clippy.sh @@ -31,6 +31,8 @@ cd "$SCRIPT_DIR/../.." || exit 1 set +e +# Fetch one more commit so HEAD~1 is available (CI uses fetch-depth: 1) +git fetch --deepen=1 2>/dev/null || true BASELINE_REV=$(git rev-parse HEAD~1) echo "Baseline revision: $BASELINE_REV" From 6de3a14ce3dbd249f58289730c66c8b161e3e1ee Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:45:16 +0300 Subject: [PATCH 17/22] test: re-add temporary public function for semver testing Co-Authored-By: Claude Opus 4.6 (1M context) --- datafusion/common-runtime/src/lib.rs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/datafusion/common-runtime/src/lib.rs b/datafusion/common-runtime/src/lib.rs index bb354d0288578..982a836d2eb74 100644 --- a/datafusion/common-runtime/src/lib.rs +++ b/datafusion/common-runtime/src/lib.rs @@ -33,4 +33,9 @@ pub use common::SpawnedTask; pub use join_set::JoinSet; pub use trace_utils::{ JoinSetTracer, JoinSetTracerError, set_join_set_tracer, trace_block, trace_future, -}; \ No newline at end of file +}; + +/// Temporary public function to test semver breaking change detection. +pub fn semver_test_function() -> &'static str { + "this will be removed to trigger a breaking change" +} \ No newline at end of file From 1bd00c274576a86b34066b8ede1a2069e11a827e Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 14:45:26 +0300 Subject: [PATCH 18/22] test: remove public function to trigger semver breaking change Co-Authored-By: Claude Opus 4.6 (1M context) --- datafusion/common-runtime/src/lib.rs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/datafusion/common-runtime/src/lib.rs b/datafusion/common-runtime/src/lib.rs index 982a836d2eb74..bb354d0288578 100644 --- a/datafusion/common-runtime/src/lib.rs +++ b/datafusion/common-runtime/src/lib.rs @@ -33,9 +33,4 @@ pub use common::SpawnedTask; pub use join_set::JoinSet; pub use trace_utils::{ JoinSetTracer, JoinSetTracerError, set_join_set_tracer, trace_block, trace_future, -}; - -/// Temporary public function to test semver breaking change detection. -pub fn semver_test_function() -> &'static str { - "this will be removed to trigger a breaking change" -} \ No newline at end of file +}; \ No newline at end of file From b3bf24408d90cbbb4952d78d34e49b5fec27c8b4 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 15:40:42 +0300 Subject: [PATCH 19/22] revert --- .../workflows/breaking_changes_detector.yml | 4 +- ci/scripts/rust_clippy.sh | 52 ------------------- datafusion/common-runtime/src/lib.rs | 2 +- 3 files changed, 3 insertions(+), 55 deletions(-) diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index 65830e19877d0..84174482e452e 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -2,8 +2,8 @@ name: "Detect breaking changes" on: pull_request: -# branches: -# - main + branches: + - main permissions: contents: read diff --git a/ci/scripts/rust_clippy.sh b/ci/scripts/rust_clippy.sh index fd0b756397141..f8b5c0852fa30 100755 --- a/ci/scripts/rust_clippy.sh +++ b/ci/scripts/rust_clippy.sh @@ -25,57 +25,6 @@ CLIPPY_FEATURES="avro,integration-tests,extended_tests" CLIPPY_ARGS=(--all-targets --workspace --features "$CLIPPY_FEATURES") CLIPPY_LINT_ARGS=(-- -D warnings) -CURRENT=$(pwd) - -cd "$SCRIPT_DIR/../.." || exit 1 - -set +e - -# Fetch one more commit so HEAD~1 is available (CI uses fetch-depth: 1) -git fetch --deepen=1 2>/dev/null || true -BASELINE_REV=$(git rev-parse HEAD~1) -echo "Baseline revision: $BASELINE_REV" - -# Get workspace members from root Cargo.toml, excluding non-public crates -MEMBERS=$(sed -n '/^members = \[/,/\]/p' Cargo.toml | grep '"' | sed 's/.*"\(.*\)".*/\1/' \ - | grep -v -e '^benchmarks$' -e '^test-utils$' -e '^datafusion/sqllogictest$' -e '^datafusion/doc$') - -# Get changed files compared to baseline -CHANGED_FILES=$(git diff --name-only "$BASELINE_REV"..HEAD) - -# Check which workspace members have changes -PACKAGES="" -for member in $MEMBERS; do - if echo "$CHANGED_FILES" | grep -q "^${member}/"; then - pkg=$(grep '^name\s*=' "$member/Cargo.toml" | head -1 | sed 's/.*=\s*"\(.*\)"/\1/') - if [ -n "$pkg" ]; then - PACKAGES="$PACKAGES $pkg" - fi - fi -done -PACKAGES=$(echo "$PACKAGES" | xargs) -echo "Changed crates: $PACKAGES" - -if [ -n "$PACKAGES" ]; then - echo "Installing cargo-semver-checks..." - cargo install cargo-semver-checks - - ARGS="" - for pkg in $PACKAGES; do - ARGS="$ARGS --package $pkg" - done - - echo "Running cargo-semver-checks against origin/main..." - cargo semver-checks --baseline-rev "$BASELINE_REV" $ARGS -else - echo "No public crates changed, skipping semver checks." -fi - - -echo "Running cargo clippy..." - -cd ${CURRENT} || exit 1 - source "${SCRIPT_DIR}/utils/git.sh" MODE="check" @@ -125,4 +74,3 @@ CLIPPY_CMD+=("${CLIPPY_ARGS[@]}" "${CLIPPY_LINT_ARGS[@]}") echo "[${SCRIPT_NAME}] \`${CLIPPY_CMD[*]}\`" "${CLIPPY_CMD[@]}" - diff --git a/datafusion/common-runtime/src/lib.rs b/datafusion/common-runtime/src/lib.rs index bb354d0288578..cf45ccf3ef63a 100644 --- a/datafusion/common-runtime/src/lib.rs +++ b/datafusion/common-runtime/src/lib.rs @@ -33,4 +33,4 @@ pub use common::SpawnedTask; pub use join_set::JoinSet; pub use trace_utils::{ JoinSetTracer, JoinSetTracerError, set_join_set_tracer, trace_block, trace_future, -}; \ No newline at end of file +}; From 10847a08e140ad394e221382e803bc98bd44ae98 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 15:46:14 +0300 Subject: [PATCH 20/22] add coments --- .../workflows/breaking_changes_detector.yml | 25 ++++++++++++++++--- 1 file changed, 22 insertions(+), 3 deletions(-) diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index 84174482e452e..3b8725e263458 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -1,3 +1,11 @@ +# Detect semver-incompatible (breaking) API changes in crates modified by a PR. +# +# Only public workspace crates that have file changes are checked. +# Internal crates (benchmarks, test-utils, sqllogictest, doc) are excluded. +# +# If breaking changes are found, a sticky comment is posted on the PR. +# The comment is removed automatically once the issues are resolved. + name: "Detect breaking changes" on: @@ -20,20 +28,25 @@ jobs: with: fetch-depth: 0 + # For fork PRs, `origin` points to the fork, not the upstream repo. + # Explicitly fetch the base branch from the upstream repo so we have + # a valid baseline ref for both diff and semver-checks. - name: Fetch base branch run: git fetch https://github.com/${{ github.repository }}.git ${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }} - name: Determine changed crates id: changed_crates run: | - # Get workspace members from root Cargo.toml, excluding non-public crates + # Parse workspace members from root Cargo.toml, excluding internal crates + # that are not published / not part of the public API. MEMBERS=$(sed -n '/^members = \[/,/\]/p' Cargo.toml | grep '"' | sed 's/.*"\(.*\)".*/\1/' \ | grep -v -e '^benchmarks$' -e '^test-utils$' -e '^datafusion/sqllogictest$' -e '^datafusion/doc$') - # Get changed files compared to base + # Diff against the base branch to find which files changed in this PR CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) - # Check which workspace members have changes + # For each workspace member, check if any of its files were modified. + # If so, extract the crate name from its Cargo.toml. PACKAGES="" for member in $MEMBERS; do if echo "$CHANGED_FILES" | grep -q "^${member}/"; then @@ -48,6 +61,7 @@ jobs: echo "packages=$PACKAGES" >> "$GITHUB_OUTPUT" echo "Changed crates: $PACKAGES" + # Only install toolchain and cargo-semver-checks if there are crates to check - name: Install Rust toolchain if: steps.changed_crates.outputs.packages != '' uses: dtolnay/rust-toolchain@stable @@ -66,6 +80,9 @@ jobs: ARGS="$ARGS --package $pkg" done + # Compare the PR's code against the base branch to detect breaking changes. + # Use tee to show output in the Actions log while also capturing it. + # Strip ANSI escape codes from the captured output for the PR comment. cargo semver-checks --baseline-rev origin/${{ github.base_ref }} $ARGS 2>&1 | tee /tmp/semver-output.txt EXIT_CODE=${PIPESTATUS[0]} OUTPUT=$(sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt) @@ -74,6 +91,7 @@ jobs: echo "EOF" >> "$GITHUB_OUTPUT" exit $EXIT_CODE + # Post or remove a sticky comment on the PR based on the semver check result. comment-on-pr: name: Comment on pull request runs-on: ubuntu-latest @@ -99,6 +117,7 @@ jobs: ${{ needs.check-semver.outputs.logs }} ``` + # Remove the comment if the check passes (e.g. after the PR is updated) - name: Delete comment if: ${{ needs.check-semver.result == 'success' }} uses: marocchino/sticky-pull-request-comment@v2 From a903caeaac110fbdcf11f577d5b8d7af8e8948e6 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 15:47:14 +0300 Subject: [PATCH 21/22] add license --- .github/workflows/breaking_changes_detector.yml | 17 +++++++++++++++++ 1 file changed, 17 insertions(+) diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index 3b8725e263458..afe5f9dc515a0 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -1,3 +1,20 @@ +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + # Detect semver-incompatible (breaking) API changes in crates modified by a PR. # # Only public workspace crates that have file changes are checked. From 8d99fbaad8a55be5b71287f9fd4021657518a3c5 Mon Sep 17 00:00:00 2001 From: Raz Luvaton <16746759+rluvaton@users.noreply.github.com> Date: Thu, 9 Apr 2026 23:51:46 +0300 Subject: [PATCH 22/22] use script instead --- .../workflows/breaking_changes_detector.yml | 86 ++++------- ci/scripts/changed_crates.sh | 137 ++++++++++++++++++ 2 files changed, 163 insertions(+), 60 deletions(-) create mode 100755 ci/scripts/changed_crates.sh diff --git a/.github/workflows/breaking_changes_detector.yml b/.github/workflows/breaking_changes_detector.yml index afe5f9dc515a0..ebe33edcbe6a5 100644 --- a/.github/workflows/breaking_changes_detector.yml +++ b/.github/workflows/breaking_changes_detector.yml @@ -49,40 +49,20 @@ jobs: # Explicitly fetch the base branch from the upstream repo so we have # a valid baseline ref for both diff and semver-checks. - name: Fetch base branch - run: git fetch https://github.com/${{ github.repository }}.git ${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }} + env: + BASE_REF: ${{ github.base_ref }} + REPO: ${{ github.repository }} + run: git fetch "https://github.com/${REPO}.git" "${BASE_REF}:refs/remotes/origin/${BASE_REF}" - name: Determine changed crates id: changed_crates + env: + BASE_REF: ${{ github.base_ref }} run: | - # Parse workspace members from root Cargo.toml, excluding internal crates - # that are not published / not part of the public API. - MEMBERS=$(sed -n '/^members = \[/,/\]/p' Cargo.toml | grep '"' | sed 's/.*"\(.*\)".*/\1/' \ - | grep -v -e '^benchmarks$' -e '^test-utils$' -e '^datafusion/sqllogictest$' -e '^datafusion/doc$') - - # Diff against the base branch to find which files changed in this PR - CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD) - - # For each workspace member, check if any of its files were modified. - # If so, extract the crate name from its Cargo.toml. - PACKAGES="" - for member in $MEMBERS; do - if echo "$CHANGED_FILES" | grep -q "^${member}/"; then - pkg=$(grep '^name\s*=' "$member/Cargo.toml" | head -1 | sed 's/.*=\s*"\(.*\)"/\1/') - if [ -n "$pkg" ]; then - PACKAGES="$PACKAGES $pkg" - fi - fi - done - - PACKAGES=$(echo "$PACKAGES" | xargs) + PACKAGES=$(ci/scripts/changed_crates.sh changed-crates "origin/${BASE_REF}") echo "packages=$PACKAGES" >> "$GITHUB_OUTPUT" echo "Changed crates: $PACKAGES" - # Only install toolchain and cargo-semver-checks if there are crates to check - - name: Install Rust toolchain - if: steps.changed_crates.outputs.packages != '' - uses: dtolnay/rust-toolchain@stable - - name: Install cargo-semver-checks if: steps.changed_crates.outputs.packages != '' run: cargo install cargo-semver-checks @@ -90,19 +70,13 @@ jobs: - name: Run cargo-semver-checks id: check_semver if: steps.changed_crates.outputs.packages != '' + env: + BASE_REF: ${{ github.base_ref }} + PACKAGES: ${{ steps.changed_crates.outputs.packages }} run: | set +e - ARGS="" - for pkg in ${{ steps.changed_crates.outputs.packages }}; do - ARGS="$ARGS --package $pkg" - done - - # Compare the PR's code against the base branch to detect breaking changes. - # Use tee to show output in the Actions log while also capturing it. - # Strip ANSI escape codes from the captured output for the PR comment. - cargo semver-checks --baseline-rev origin/${{ github.base_ref }} $ARGS 2>&1 | tee /tmp/semver-output.txt - EXIT_CODE=${PIPESTATUS[0]} - OUTPUT=$(sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt) + OUTPUT=$(ci/scripts/changed_crates.sh semver-check "origin/${BASE_REF}" $PACKAGES) + EXIT_CODE=$? echo "logs<> "$GITHUB_OUTPUT" echo "$OUTPUT" >> "$GITHUB_OUTPUT" echo "EOF" >> "$GITHUB_OUTPUT" @@ -118,26 +92,18 @@ jobs: contents: read pull-requests: write steps: - - name: Comment - if: ${{ needs.check-semver.result != 'success' }} - uses: marocchino/sticky-pull-request-comment@v2 - with: - header: pr-semver-check-error - message: | - Thank you for opening this pull request! - - Reviewer note: [cargo-semver-checks](https://github.com/obi1kenobi/cargo-semver-checks) reported the current version number is not SemVer-compatible with the changes made since the last release. - - Details: - - ``` - ${{ needs.check-semver.outputs.logs }} - ``` - - # Remove the comment if the check passes (e.g. after the PR is updated) - - name: Delete comment - if: ${{ needs.check-semver.result == 'success' }} - uses: marocchino/sticky-pull-request-comment@v2 + - name: Checkout + uses: actions/checkout@v4 with: - header: pr-semver-check-error - delete: true + sparse-checkout: ci/scripts + + - name: Update PR comment + env: + GH_TOKEN: ${{ github.token }} + REPO: ${{ github.repository }} + PR_NUMBER: ${{ github.event.pull_request.number }} + CHECK_RESULT: ${{ needs.check-semver.result }} + SEMVER_LOGS: ${{ needs.check-semver.outputs.logs }} + run: | + ci/scripts/changed_crates.sh comment \ + "$REPO" "$PR_NUMBER" "$CHECK_RESULT" "$SEMVER_LOGS" diff --git a/ci/scripts/changed_crates.sh b/ci/scripts/changed_crates.sh new file mode 100755 index 0000000000000..50fb68601dcdd --- /dev/null +++ b/ci/scripts/changed_crates.sh @@ -0,0 +1,137 @@ +#!/usr/bin/env bash +# Licensed to the Apache Software Foundation (ASF) under one +# or more contributor license agreements. See the NOTICE file +# distributed with this work for additional information +# regarding copyright ownership. The ASF licenses this file +# to you under the Apache License, Version 2.0 (the +# "License"); you may not use this file except in compliance +# with the License. You may obtain a copy of the License at +# +# http://www.apache.org/licenses/LICENSE-2.0 +# +# Unless required by applicable law or agreed to in writing, +# software distributed under the License is distributed on an +# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY +# KIND, either express or implied. See the License for the +# specific language governing permissions and limitations +# under the License. + +# Helper script for the breaking-changes-detector workflow. +# +# Subcommands: +# changed-crates +# Print space-separated list of crate names whose files changed vs base_ref. +# +# semver-check +# Run cargo-semver-checks for the given packages against base_ref. +# Prints the (ANSI-stripped) log output to stdout. +# Exit code matches cargo-semver-checks (0 = pass, non-zero = breaking). +# +# comment [logs] +# Upsert or delete a sticky PR comment based on check_result. +# check_result: "success" deletes any existing comment, +# anything else upserts the comment with the provided logs. +# Requires GH_TOKEN to be set. + +set -euo pipefail + +MARKER="" + +# ── changed-crates ────────────────────────────────────────────────── +cmd_changed_crates() { + local base_ref="${1:?Usage: changed_crates.sh changed-crates }" + + # Parse workspace members from root Cargo.toml, excluding internal crates + # that are not published / not part of the public API. + local members + members=$(sed -n '/^members = \[/,/\]/p' Cargo.toml | grep '"' | sed 's/.*"\(.*\)".*/\1/' \ + | grep -v -e '^benchmarks$' -e '^test-utils$' -e '^datafusion/sqllogictest$' -e '^datafusion/doc$') + + local changed_files + changed_files=$(git diff --name-only "${base_ref}...HEAD") + + local packages="" + for member in $members; do + if echo "$changed_files" | grep -q "^${member}/"; then + local pkg + pkg=$(grep '^name\s*=' "$member/Cargo.toml" | head -1 | sed 's/.*=\s*"\(.*\)"/\1/') + if [ -n "$pkg" ]; then + packages="$packages $pkg" + fi + fi + done + + echo "$packages" | xargs +} + +# ── semver-check ──────────────────────────────────────────────────── +cmd_semver_check() { + local base_ref="${1:?Usage: changed_crates.sh semver-check }" + shift + + local args="" + for pkg in "$@"; do + args="$args --package $pkg" + done + + set +e + # Compare the PR's code against the base branch to detect breaking changes. + # Use tee to show output in the Actions log while also capturing it. + cargo semver-checks --baseline-rev "$base_ref" $args 2>&1 | tee /tmp/semver-output.txt + local exit_code=${PIPESTATUS[0]} + set -e + + # Strip ANSI escape codes from the captured output for the PR comment. + sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt + return "$exit_code" +} + +# ── comment ───────────────────────────────────────────────────────── +cmd_comment() { + local repo="${1:?Usage: changed_crates.sh comment [logs]}" + local pr_number="${2:?}" + local check_result="${3:?}" + local logs="${4:-}" + + # Find existing comment with our marker + local comment_id + comment_id=$(gh api "repos/${repo}/issues/${pr_number}/comments" \ + --jq ".[] | select(.body | contains(\"${MARKER}\")) | .id" | head -1) + + if [ "$check_result" = "success" ]; then + # Delete the comment if one exists + if [ -n "$comment_id" ]; then + gh api "repos/${repo}/issues/comments/${comment_id}" --method DELETE + fi + else + local body="${MARKER} +Thank you for opening this pull request! + +Reviewer note: [cargo-semver-checks](https://github.com/obi1kenobi/cargo-semver-checks) reported the current version number is not SemVer-compatible with the changes made since the last release. + +Details: + +\`\`\` +${logs} +\`\`\`" + + if [ -n "$comment_id" ]; then + gh api "repos/${repo}/issues/comments/${comment_id}" \ + --method PATCH --field body="$body" + else + gh api "repos/${repo}/issues/${pr_number}/comments" \ + --method POST --field body="$body" + fi + fi +} + +# ── main ──────────────────────────────────────────────────────────── +cmd="${1:?Usage: changed_crates.sh [args...]}" +shift + +case "$cmd" in + changed-crates) cmd_changed_crates "$@" ;; + semver-check) cmd_semver_check "$@" ;; + comment) cmd_comment "$@" ;; + *) echo "Unknown command: $cmd" >&2; exit 1 ;; +esac