@@ -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