3434 description : ' GTest run number (e.g., 65, leave empty for latest)'
3535 required : false
3636 type : string
37+ baseline_pytest_run_number :
38+ description : ' Baseline pytest run number for regression comparison (leave empty to skip)'
39+ required : false
40+ type : string
41+ baseline_gtest_run_number :
42+ description : ' Baseline gtest run number for regression comparison (leave empty to skip)'
43+ required : false
44+ type : string
3745
3846permissions :
3947 contents : read
4553 outputs :
4654 gtest_run_id : ${{ steps.get-runs.outputs.gtest_run_id }}
4755 pytest_run_id : ${{ steps.get-runs.outputs.pytest_run_id }}
56+ baseline_pytest_run_id : ${{ steps.get-runs.outputs.baseline_pytest_run_id }}
57+ baseline_gtest_run_id : ${{ steps.get-runs.outputs.baseline_gtest_run_id }}
4858 both_completed : ${{ steps.check-status.outputs.both_completed }}
4959 steps :
5060 - name : ' preparation: Harden Runner'
@@ -138,6 +148,39 @@ jobs:
138148 core.setOutput('gtest_run_id', runIds['gtest'] || '');
139149 core.setOutput('pytest_run_id', runIds['pytest'] || '');
140150
151+ // Find baseline runs for regression comparison
152+ const baselinePytestRunNumber = '${{ github.event.inputs.baseline_pytest_run_number }}' || '';
153+ const baselineGtestRunNumber = '${{ github.event.inputs.baseline_gtest_run_number }}' || '';
154+
155+ // If no explicit baseline is given and this is an automatic trigger,
156+ // find the second-most-recent completed run as baseline
157+ async function findBaselineRun(workflow, explicitRunNumber, currentRunId) {
158+ if (explicitRunNumber) {
159+ const run = await findRun(workflow, '', explicitRunNumber);
160+ return run ? run.id : '';
161+ }
162+ // Auto-detect: find the latest completed run that is NOT the current one
163+ const runs = await github.rest.actions.listWorkflowRuns({
164+ owner: context.repo.owner,
165+ repo: context.repo.repo,
166+ workflow_id: `${workflow}.yml`,
167+ per_page: 5,
168+ status: 'completed'
169+ });
170+ const prev = runs.data.workflow_runs.find(r => r.id != currentRunId);
171+ if (prev) {
172+ console.log(` Baseline for ${workflow}: run #${prev.run_number}`);
173+ return prev.id;
174+ }
175+ return '';
176+ }
177+
178+ const baselinePytestId = await findBaselineRun('nightly-pytest', baselinePytestRunNumber, runIds['pytest'] || '');
179+ const baselineGtestId = await findBaselineRun('nightly-gtest', baselineGtestRunNumber, runIds['gtest'] || '');
180+
181+ core.setOutput('baseline_pytest_run_id', baselinePytestId ? String(baselinePytestId) : '');
182+ core.setOutput('baseline_gtest_run_id', baselineGtestId ? String(baselineGtestId) : '');
183+
141184 return runIds;
142185
143186 - name : Check if both workflows completed
@@ -270,6 +313,94 @@ jobs:
270313 echo "No system info reports found (this is optional)"
271314 fi
272315
316+ - name : Download baseline pytest artifacts
317+ if : needs.wait-for-both-workflows.outputs.baseline_pytest_run_id != ''
318+ uses : actions/download-artifact@f093f21ca4cfa7c75ccbbc2be54da76a0c7e1f05 # v4.4.3
319+ continue-on-error : true
320+ with :
321+ pattern : nightly-test-report-*
322+ path : baseline-pytest-reports
323+ merge-multiple : false
324+ run-id : ${{ needs.wait-for-both-workflows.outputs.baseline_pytest_run_id }}
325+ github-token : ${{ secrets.GITHUB_TOKEN }}
326+
327+ - name : Download baseline gtest artifacts
328+ if : needs.wait-for-both-workflows.outputs.baseline_gtest_run_id != ''
329+ uses : actions/download-artifact@f093f21ca4cfa7c75ccbbc2be54da76a0c7e1f05 # v4.4.3
330+ continue-on-error : true
331+ with :
332+ pattern : nightly-gtest-report-*
333+ path : baseline-gtest-reports
334+ merge-multiple : false
335+ run-id : ${{ needs.wait-for-both-workflows.outputs.baseline_gtest_run_id }}
336+ github-token : ${{ secrets.GITHUB_TOKEN }}
337+
338+ - name : Flatten baseline pytest report structure
339+ if : needs.wait-for-both-workflows.outputs.baseline_pytest_run_id != ''
340+ run : |
341+ if [ -d "baseline-pytest-reports" ]; then
342+ cd baseline-pytest-reports
343+ for dir in ./nightly-test-report-*; do
344+ if [ -d "$dir" ] && [ -f "$dir/report.html" ]; then
345+ mv "$dir/report.html" "${dir}.html"
346+ rm -rf "$dir"
347+ fi
348+ done
349+ ls -lh ./*.html || echo "No baseline pytest HTML reports found"
350+ fi
351+
352+ - name : Flatten baseline gtest report structure
353+ if : needs.wait-for-both-workflows.outputs.baseline_gtest_run_id != ''
354+ run : |
355+ if [ -d "baseline-gtest-reports" ]; then
356+ cd baseline-gtest-reports
357+ for dir in ./nightly-gtest-report-*; do
358+ if [ -d "$dir" ] && [ -f "$dir/gtest.log" ]; then
359+ mv "$dir/gtest.log" "${dir}.log"
360+ rm -rf "$dir"
361+ fi
362+ done
363+ ls -lh ./*.log || echo "No baseline gtest logs found"
364+ fi
365+
366+ - name : Get baseline pytest run metadata
367+ id : baseline-pytest-metadata
368+ if : needs.wait-for-both-workflows.outputs.baseline_pytest_run_id != ''
369+ uses : actions/github-script@v7
370+ with :
371+ script : |
372+ const runId = ${{ needs.wait-for-both-workflows.outputs.baseline_pytest_run_id }};
373+ const run = await github.rest.actions.getWorkflowRun({
374+ owner: context.repo.owner,
375+ repo: context.repo.repo,
376+ run_id: runId
377+ });
378+ core.setOutput('run_date', run.data.created_at);
379+ core.setOutput('run_id', runId);
380+ core.setOutput('run_number', run.data.run_number);
381+ core.setOutput('branch', run.data.head_branch);
382+ core.setOutput('run_url', run.data.html_url);
383+ console.log(`Baseline Pytest Run #${run.data.run_number}, Branch: ${run.data.head_branch}`);
384+
385+ - name : Get baseline gtest run metadata
386+ id : baseline-gtest-metadata
387+ if : needs.wait-for-both-workflows.outputs.baseline_gtest_run_id != ''
388+ uses : actions/github-script@v7
389+ with :
390+ script : |
391+ const runId = ${{ needs.wait-for-both-workflows.outputs.baseline_gtest_run_id }};
392+ const run = await github.rest.actions.getWorkflowRun({
393+ owner: context.repo.owner,
394+ repo: context.repo.repo,
395+ run_id: runId
396+ });
397+ core.setOutput('run_date', run.data.created_at);
398+ core.setOutput('run_id', runId);
399+ core.setOutput('run_number', run.data.run_number);
400+ core.setOutput('branch', run.data.head_branch);
401+ core.setOutput('run_url', run.data.html_url);
402+ console.log(`Baseline GTest Run #${run.data.run_number}, Branch: ${run.data.head_branch}`);
403+
273404 - name : Install dependencies
274405 run : |
275406 python3 -m pip install --upgrade pip
@@ -278,6 +409,24 @@ jobs:
278409 - name : Generate combined reports
279410 id : combine
280411 run : |
412+ BASELINE_ARGS=()
413+ if [ -d "baseline-pytest-reports" ]; then
414+ BASELINE_ARGS+=(--baseline-pytest-dir baseline-pytest-reports)
415+ BASELINE_ARGS+=(--baseline-pytest-run-id "${{ steps.baseline-pytest-metadata.outputs.run_id }}")
416+ BASELINE_ARGS+=(--baseline-pytest-run-date "${{ steps.baseline-pytest-metadata.outputs.run_date }}")
417+ BASELINE_ARGS+=(--baseline-pytest-run-number "${{ steps.baseline-pytest-metadata.outputs.run_number }}")
418+ BASELINE_ARGS+=(--baseline-pytest-branch "${{ steps.baseline-pytest-metadata.outputs.branch }}")
419+ BASELINE_ARGS+=(--baseline-pytest-run-url "${{ steps.baseline-pytest-metadata.outputs.run_url }}")
420+ fi
421+ if [ -d "baseline-gtest-reports" ]; then
422+ BASELINE_ARGS+=(--baseline-gtest-dir baseline-gtest-reports)
423+ BASELINE_ARGS+=(--baseline-gtest-run-id "${{ steps.baseline-gtest-metadata.outputs.run_id }}")
424+ BASELINE_ARGS+=(--baseline-gtest-run-date "${{ steps.baseline-gtest-metadata.outputs.run_date }}")
425+ BASELINE_ARGS+=(--baseline-gtest-run-number "${{ steps.baseline-gtest-metadata.outputs.run_number }}")
426+ BASELINE_ARGS+=(--baseline-gtest-branch "${{ steps.baseline-gtest-metadata.outputs.branch }}")
427+ BASELINE_ARGS+=(--baseline-gtest-run-url "${{ steps.baseline-gtest-metadata.outputs.run_url }}")
428+ fi
429+
281430 python3 .github/scripts/combine_all_reports.py \
282431 --pytest-dir pytest-reports \
283432 --gtest-dir gtest-reports \
@@ -293,7 +442,8 @@ jobs:
293442 --gtest-run-date "${{ steps.gtest-metadata.outputs.run_date }}" \
294443 --gtest-run-number "${{ steps.gtest-metadata.outputs.run_number }}" \
295444 --gtest-branch "${{ steps.gtest-metadata.outputs.branch }}" \
296- --gtest-run-url "${{ steps.gtest-metadata.outputs.run_url }}"
445+ --gtest-run-url "${{ steps.gtest-metadata.outputs.run_url }}" \
446+ "${BASELINE_ARGS[@]}"
297447
298448 if [ -f "combined_nightly_report.xlsx" ] && [ -f "combined_nightly_report.html" ]; then
299449 echo "reports_generated=true" >> "$GITHUB_OUTPUT"
0 commit comments