Skip to content

Commit 8d99fba

Browse files
committed
use script instead
1 parent 83a2f39 commit 8d99fba

2 files changed

Lines changed: 163 additions & 60 deletions

File tree

.github/workflows/breaking_changes_detector.yml

Lines changed: 26 additions & 60 deletions
Original file line numberDiff line numberDiff line change
@@ -49,60 +49,34 @@ jobs:
4949
# Explicitly fetch the base branch from the upstream repo so we have
5050
# a valid baseline ref for both diff and semver-checks.
5151
- name: Fetch base branch
52-
run: git fetch https://github.com/${{ github.repository }}.git ${{ github.base_ref }}:refs/remotes/origin/${{ github.base_ref }}
52+
env:
53+
BASE_REF: ${{ github.base_ref }}
54+
REPO: ${{ github.repository }}
55+
run: git fetch "https://github.com/${REPO}.git" "${BASE_REF}:refs/remotes/origin/${BASE_REF}"
5356

5457
- name: Determine changed crates
5558
id: changed_crates
59+
env:
60+
BASE_REF: ${{ github.base_ref }}
5661
run: |
57-
# Parse workspace members from root Cargo.toml, excluding internal crates
58-
# that are not published / not part of the public API.
59-
MEMBERS=$(sed -n '/^members = \[/,/\]/p' Cargo.toml | grep '"' | sed 's/.*"\(.*\)".*/\1/' \
60-
| grep -v -e '^benchmarks$' -e '^test-utils$' -e '^datafusion/sqllogictest$' -e '^datafusion/doc$')
61-
62-
# Diff against the base branch to find which files changed in this PR
63-
CHANGED_FILES=$(git diff --name-only origin/${{ github.base_ref }}...HEAD)
64-
65-
# For each workspace member, check if any of its files were modified.
66-
# If so, extract the crate name from its Cargo.toml.
67-
PACKAGES=""
68-
for member in $MEMBERS; do
69-
if echo "$CHANGED_FILES" | grep -q "^${member}/"; then
70-
pkg=$(grep '^name\s*=' "$member/Cargo.toml" | head -1 | sed 's/.*=\s*"\(.*\)"/\1/')
71-
if [ -n "$pkg" ]; then
72-
PACKAGES="$PACKAGES $pkg"
73-
fi
74-
fi
75-
done
76-
77-
PACKAGES=$(echo "$PACKAGES" | xargs)
62+
PACKAGES=$(ci/scripts/changed_crates.sh changed-crates "origin/${BASE_REF}")
7863
echo "packages=$PACKAGES" >> "$GITHUB_OUTPUT"
7964
echo "Changed crates: $PACKAGES"
8065
81-
# Only install toolchain and cargo-semver-checks if there are crates to check
82-
- name: Install Rust toolchain
83-
if: steps.changed_crates.outputs.packages != ''
84-
uses: dtolnay/rust-toolchain@stable
85-
8666
- name: Install cargo-semver-checks
8767
if: steps.changed_crates.outputs.packages != ''
8868
run: cargo install cargo-semver-checks
8969

9070
- name: Run cargo-semver-checks
9171
id: check_semver
9272
if: steps.changed_crates.outputs.packages != ''
73+
env:
74+
BASE_REF: ${{ github.base_ref }}
75+
PACKAGES: ${{ steps.changed_crates.outputs.packages }}
9376
run: |
9477
set +e
95-
ARGS=""
96-
for pkg in ${{ steps.changed_crates.outputs.packages }}; do
97-
ARGS="$ARGS --package $pkg"
98-
done
99-
100-
# Compare the PR's code against the base branch to detect breaking changes.
101-
# Use tee to show output in the Actions log while also capturing it.
102-
# Strip ANSI escape codes from the captured output for the PR comment.
103-
cargo semver-checks --baseline-rev origin/${{ github.base_ref }} $ARGS 2>&1 | tee /tmp/semver-output.txt
104-
EXIT_CODE=${PIPESTATUS[0]}
105-
OUTPUT=$(sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt)
78+
OUTPUT=$(ci/scripts/changed_crates.sh semver-check "origin/${BASE_REF}" $PACKAGES)
79+
EXIT_CODE=$?
10680
echo "logs<<EOF" >> "$GITHUB_OUTPUT"
10781
echo "$OUTPUT" >> "$GITHUB_OUTPUT"
10882
echo "EOF" >> "$GITHUB_OUTPUT"
@@ -118,26 +92,18 @@ jobs:
11892
contents: read
11993
pull-requests: write
12094
steps:
121-
- name: Comment
122-
if: ${{ needs.check-semver.result != 'success' }}
123-
uses: marocchino/sticky-pull-request-comment@v2
124-
with:
125-
header: pr-semver-check-error
126-
message: |
127-
Thank you for opening this pull request!
128-
129-
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.
130-
131-
Details:
132-
133-
```
134-
${{ needs.check-semver.outputs.logs }}
135-
```
136-
137-
# Remove the comment if the check passes (e.g. after the PR is updated)
138-
- name: Delete comment
139-
if: ${{ needs.check-semver.result == 'success' }}
140-
uses: marocchino/sticky-pull-request-comment@v2
95+
- name: Checkout
96+
uses: actions/checkout@v4
14197
with:
142-
header: pr-semver-check-error
143-
delete: true
98+
sparse-checkout: ci/scripts
99+
100+
- name: Update PR comment
101+
env:
102+
GH_TOKEN: ${{ github.token }}
103+
REPO: ${{ github.repository }}
104+
PR_NUMBER: ${{ github.event.pull_request.number }}
105+
CHECK_RESULT: ${{ needs.check-semver.result }}
106+
SEMVER_LOGS: ${{ needs.check-semver.outputs.logs }}
107+
run: |
108+
ci/scripts/changed_crates.sh comment \
109+
"$REPO" "$PR_NUMBER" "$CHECK_RESULT" "$SEMVER_LOGS"

ci/scripts/changed_crates.sh

Lines changed: 137 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,137 @@
1+
#!/usr/bin/env bash
2+
# Licensed to the Apache Software Foundation (ASF) under one
3+
# or more contributor license agreements. See the NOTICE file
4+
# distributed with this work for additional information
5+
# regarding copyright ownership. The ASF licenses this file
6+
# to you under the Apache License, Version 2.0 (the
7+
# "License"); you may not use this file except in compliance
8+
# with the License. You may obtain a copy of the License at
9+
#
10+
# http://www.apache.org/licenses/LICENSE-2.0
11+
#
12+
# Unless required by applicable law or agreed to in writing,
13+
# software distributed under the License is distributed on an
14+
# "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY
15+
# KIND, either express or implied. See the License for the
16+
# specific language governing permissions and limitations
17+
# under the License.
18+
19+
# Helper script for the breaking-changes-detector workflow.
20+
#
21+
# Subcommands:
22+
# changed-crates <base_ref>
23+
# Print space-separated list of crate names whose files changed vs base_ref.
24+
#
25+
# semver-check <base_ref> <packages...>
26+
# Run cargo-semver-checks for the given packages against base_ref.
27+
# Prints the (ANSI-stripped) log output to stdout.
28+
# Exit code matches cargo-semver-checks (0 = pass, non-zero = breaking).
29+
#
30+
# comment <repo> <pr_number> <check_result> [logs]
31+
# Upsert or delete a sticky PR comment based on check_result.
32+
# check_result: "success" deletes any existing comment,
33+
# anything else upserts the comment with the provided logs.
34+
# Requires GH_TOKEN to be set.
35+
36+
set -euo pipefail
37+
38+
MARKER="<!-- semver-check-comment -->"
39+
40+
# ── changed-crates ──────────────────────────────────────────────────
41+
cmd_changed_crates() {
42+
local base_ref="${1:?Usage: changed_crates.sh changed-crates <base_ref>}"
43+
44+
# Parse workspace members from root Cargo.toml, excluding internal crates
45+
# that are not published / not part of the public API.
46+
local members
47+
members=$(sed -n '/^members = \[/,/\]/p' Cargo.toml | grep '"' | sed 's/.*"\(.*\)".*/\1/' \
48+
| grep -v -e '^benchmarks$' -e '^test-utils$' -e '^datafusion/sqllogictest$' -e '^datafusion/doc$')
49+
50+
local changed_files
51+
changed_files=$(git diff --name-only "${base_ref}...HEAD")
52+
53+
local packages=""
54+
for member in $members; do
55+
if echo "$changed_files" | grep -q "^${member}/"; then
56+
local pkg
57+
pkg=$(grep '^name\s*=' "$member/Cargo.toml" | head -1 | sed 's/.*=\s*"\(.*\)"/\1/')
58+
if [ -n "$pkg" ]; then
59+
packages="$packages $pkg"
60+
fi
61+
fi
62+
done
63+
64+
echo "$packages" | xargs
65+
}
66+
67+
# ── semver-check ────────────────────────────────────────────────────
68+
cmd_semver_check() {
69+
local base_ref="${1:?Usage: changed_crates.sh semver-check <base_ref> <packages...>}"
70+
shift
71+
72+
local args=""
73+
for pkg in "$@"; do
74+
args="$args --package $pkg"
75+
done
76+
77+
set +e
78+
# Compare the PR's code against the base branch to detect breaking changes.
79+
# Use tee to show output in the Actions log while also capturing it.
80+
cargo semver-checks --baseline-rev "$base_ref" $args 2>&1 | tee /tmp/semver-output.txt
81+
local exit_code=${PIPESTATUS[0]}
82+
set -e
83+
84+
# Strip ANSI escape codes from the captured output for the PR comment.
85+
sed 's/\x1b\[[0-9;]*m//g' /tmp/semver-output.txt
86+
return "$exit_code"
87+
}
88+
89+
# ── comment ─────────────────────────────────────────────────────────
90+
cmd_comment() {
91+
local repo="${1:?Usage: changed_crates.sh comment <repo> <pr_number> <check_result> [logs]}"
92+
local pr_number="${2:?}"
93+
local check_result="${3:?}"
94+
local logs="${4:-}"
95+
96+
# Find existing comment with our marker
97+
local comment_id
98+
comment_id=$(gh api "repos/${repo}/issues/${pr_number}/comments" \
99+
--jq ".[] | select(.body | contains(\"${MARKER}\")) | .id" | head -1)
100+
101+
if [ "$check_result" = "success" ]; then
102+
# Delete the comment if one exists
103+
if [ -n "$comment_id" ]; then
104+
gh api "repos/${repo}/issues/comments/${comment_id}" --method DELETE
105+
fi
106+
else
107+
local body="${MARKER}
108+
Thank you for opening this pull request!
109+
110+
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.
111+
112+
Details:
113+
114+
\`\`\`
115+
${logs}
116+
\`\`\`"
117+
118+
if [ -n "$comment_id" ]; then
119+
gh api "repos/${repo}/issues/comments/${comment_id}" \
120+
--method PATCH --field body="$body"
121+
else
122+
gh api "repos/${repo}/issues/${pr_number}/comments" \
123+
--method POST --field body="$body"
124+
fi
125+
fi
126+
}
127+
128+
# ── main ────────────────────────────────────────────────────────────
129+
cmd="${1:?Usage: changed_crates.sh <changed-crates|semver-check|comment> [args...]}"
130+
shift
131+
132+
case "$cmd" in
133+
changed-crates) cmd_changed_crates "$@" ;;
134+
semver-check) cmd_semver_check "$@" ;;
135+
comment) cmd_comment "$@" ;;
136+
*) echo "Unknown command: $cmd" >&2; exit 1 ;;
137+
esac

0 commit comments

Comments
 (0)