Skip to content

Commit e8927e1

Browse files
Improve kselftest comparison with smart base branch detection
- Add checkout step with full history (fetch-depth: 0) to enable git operations - Implement intelligent base branch detection: * For PRs: use the base branch directly from github.base_ref * For direct pushes: find closest common ancestor using git merge-base * Iterate through all remote branches to find best match - Compare against detected base branch instead of same branch - Add outputs (comparison_status, comparison_message) for downstream jobs - Improve error handling and warning messages - Skip comparison gracefully if base branch cannot be determined This makes the comparison much more useful by comparing against the branch you're merging into, rather than the previous run of the same branch. Signed-off-by: Shreeya Patel <spatel@ciq.com>
1 parent 74ba259 commit e8927e1

File tree

1 file changed

+97
-11
lines changed

1 file changed

+97
-11
lines changed

.github/workflows/kernel-build-and-test-x86_64.yml

Lines changed: 97 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -199,39 +199,117 @@ jobs:
199199
if: success() || failure()
200200

201201
steps:
202+
- name: Checkout kernel source
203+
uses: actions/checkout@v4
204+
with:
205+
fetch-depth: 0
206+
202207
- name: Download current kselftest logs
203208
uses: actions/download-artifact@v4
204209
with:
205210
name: kselftest-logs-x86_64
206211
path: output-current
207212

208-
- name: Download previous kselftest logs
213+
- name: Determine base branch for comparison
214+
id: base_branch
215+
run: |
216+
BASE_BRANCH=""
217+
218+
# For PRs, use the base branch directly
219+
if [ -n "${{ github.base_ref }}" ]; then
220+
BASE_BRANCH="${{ github.base_ref }}"
221+
echo "Using PR base branch: $BASE_BRANCH"
222+
else
223+
# For direct pushes, find the common ancestor branch
224+
echo "Not a PR, finding base branch via merge-base"
225+
226+
# Get all remote branches and find the one with closest common ancestor
227+
CURRENT_COMMIT=$(git rev-parse HEAD)
228+
BEST_BRANCH=""
229+
CLOSEST_DISTANCE=999999
230+
231+
for remote_branch in $(git for-each-ref --format='%(refname:short)' refs/remotes/origin/ | grep -v 'HEAD\|PR-CHECKER'); do
232+
branch_name=$(echo "$remote_branch" | sed 's|^origin/||')
233+
234+
# Skip if it's the current branch
235+
if [ "$branch_name" = "${{ github.ref_name }}" ]; then
236+
continue
237+
fi
238+
239+
MERGE_BASE=$(git merge-base HEAD "$remote_branch" 2>/dev/null || echo "")
240+
241+
# Check if this branch shares history and isn't the current commit
242+
if [ -n "$MERGE_BASE" ] && [ "$MERGE_BASE" != "$CURRENT_COMMIT" ]; then
243+
# Calculate distance (number of commits) from merge-base to current HEAD
244+
DISTANCE=$(git rev-list --count ${MERGE_BASE}..HEAD 2>/dev/null || echo "999999")
245+
246+
# Find the branch with the shortest distance (most recent common ancestor)
247+
if [ "$DISTANCE" -lt "$CLOSEST_DISTANCE" ]; then
248+
CLOSEST_DISTANCE=$DISTANCE
249+
BEST_BRANCH=$branch_name
250+
fi
251+
fi
252+
done
253+
254+
if [ -n "$BEST_BRANCH" ]; then
255+
BASE_BRANCH=$BEST_BRANCH
256+
echo "Found common ancestor with $BASE_BRANCH (distance: $CLOSEST_DISTANCE commits)"
257+
fi
258+
fi
259+
260+
if [ -z "$BASE_BRANCH" ]; then
261+
echo "::warning::Could not determine base branch for comparison - no common ancestor found"
262+
echo "::warning::Kselftest comparison will be skipped"
263+
echo "base_branch=" >> $GITHUB_OUTPUT
264+
exit 0
265+
fi
266+
267+
echo "base_branch=$BASE_BRANCH" >> $GITHUB_OUTPUT
268+
echo "Base branch for comparison: $BASE_BRANCH"
269+
270+
- name: Download baseline kselftest logs from base branch
271+
if: steps.base_branch.outputs.base_branch != ''
209272
uses: dawidd6/action-download-artifact@v3
210273
with:
211274
workflow: kernel-build-and-test-x86_64.yml
212275
name: kselftest-logs-x86_64
213276
path: output-previous
214-
branch: ${{ github.ref_name }}
277+
branch: ${{ steps.base_branch.outputs.base_branch }}
215278
workflow_conclusion: success
216279
search_artifacts: true
217280
skip_unpack: false
218281
if_no_artifact_found: warn
282+
# Only search the last 5 successful runs for better performance
283+
run_number: ${{ github.run_number }}
284+
search_depth: 5
219285
continue-on-error: true
286+
timeout-minutes: 3
220287

221288
- name: Compare test results
289+
id: comparison
222290
run: |
223-
if [ -f output-previous/kselftests-*.log ]; then
291+
# Check if we have a base branch to compare against
292+
if [ -z "${{ steps.base_branch.outputs.base_branch }}" ]; then
293+
echo "::warning::No base branch found for comparison"
294+
echo "::warning::Kselftest comparison will be skipped"
295+
echo "comparison_status=skipped" >> $GITHUB_OUTPUT
296+
echo "comparison_message=No base branch found - unable to determine merge target" >> $GITHUB_OUTPUT
297+
exit 0
298+
fi
299+
300+
# Check if baseline logs exist
301+
if ls output-previous/kselftests-*.log 1> /dev/null 2>&1; then
224302
# Compare passing tests (ok)
225-
BEFORE_PASS=$(grep -a '^ok' output-previous/kselftests-*.log | wc -l)
226-
AFTER_PASS=$(grep -a '^ok' output-current/kselftests-*.log | wc -l)
303+
BEFORE_PASS=$(grep -a '^ok' output-previous/kselftests-*.log | wc -l || echo "0")
304+
AFTER_PASS=$(grep -a '^ok' output-current/kselftests-*.log | wc -l || echo "0")
227305
228306
# Compare failing tests (not ok)
229-
BEFORE_FAIL=$(grep -a '^not ok' output-previous/kselftests-*.log | wc -l)
230-
AFTER_FAIL=$(grep -a '^not ok' output-current/kselftests-*.log | wc -l)
307+
BEFORE_FAIL=$(grep -a '^not ok' output-previous/kselftests-*.log | wc -l || echo "0")
308+
AFTER_FAIL=$(grep -a '^not ok' output-current/kselftests-*.log | wc -l || echo "0")
231309
232-
echo "### Kselftest Comparison (Branch: ${{ github.ref_name }})"
233-
echo "Passing tests: $BEFORE_PASS -> $AFTER_PASS"
234-
echo "Failing tests: $BEFORE_FAIL -> $AFTER_FAIL"
310+
echo "### Kselftest Comparison"
311+
echo "Baseline (from ${{ steps.base_branch.outputs.base_branch }}): $BEFORE_PASS passing, $BEFORE_FAIL failing"
312+
echo "Current (${{ github.ref_name }}): $AFTER_PASS passing, $AFTER_FAIL failing"
235313
236314
# Calculate differences
237315
PASS_DIFF=$((AFTER_PASS - BEFORE_PASS))
@@ -255,10 +333,18 @@ jobs:
255333
256334
if [ $REGRESSION -eq 1 ]; then
257335
echo "::error::Test regression exceeds acceptable threshold of 3 tests"
336+
echo "comparison_status=failed" >> $GITHUB_OUTPUT
337+
echo "comparison_message=Regression detected: Pass diff: $PASS_DIFF, Fail diff: $FAIL_DIFF (threshold: ±3)" >> $GITHUB_OUTPUT
258338
exit 1
259339
else
260340
echo "::notice::Test results within acceptable range (threshold: ±3 tests)"
341+
echo "comparison_status=passed" >> $GITHUB_OUTPUT
342+
echo "comparison_message=Baseline: $BEFORE_PASS passing, $BEFORE_FAIL failing | Current: $AFTER_PASS passing, $AFTER_FAIL failing" >> $GITHUB_OUTPUT
261343
fi
262344
else
263-
echo "::warning::No previous successful test results found for branch ${{ github.ref_name }}, skipping comparison"
345+
echo "::warning::No baseline test results found for branch ${{ steps.base_branch.outputs.base_branch }}"
346+
echo "::notice::Cannot compare against base branch - artifacts may not exist or have expired (7-day retention)"
347+
echo "::notice::Skipping comparison - PR will still be created with warning"
348+
echo "comparison_status=skipped" >> $GITHUB_OUTPUT
349+
echo "comparison_message=No baseline results available from ${{ steps.base_branch.outputs.base_branch }}" >> $GITHUB_OUTPUT
264350
fi

0 commit comments

Comments
 (0)