Test Results #5
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: Test Results | |
| on: | |
| workflow_run: | |
| workflows: [Linux] | |
| types: [completed] | |
| permissions: | |
| contents: read | |
| actions: read | |
| checks: write | |
| pull-requests: write | |
| jobs: | |
| post-results: | |
| name: Post Linux Results | |
| runs-on: ubuntu-latest | |
| if: github.event.workflow_run.event == 'pull_request' | |
| timeout-minutes: 10 | |
| steps: | |
| - name: Checkout | |
| uses: actions/checkout@v6 | |
| with: | |
| sparse-checkout: .github/actions/coverage-comment | |
| sparse-checkout-cone-mode: false | |
| - name: Get PR number | |
| id: pr | |
| uses: actions/github-script@v8 | |
| with: | |
| script: | | |
| const run = context.payload.workflow_run; | |
| if (run.pull_requests && run.pull_requests.length > 0) { | |
| return run.pull_requests[0].number; | |
| } | |
| const prs = await github.rest.pulls.list({ | |
| owner: context.repo.owner, | |
| repo: context.repo.repo, | |
| state: 'open', | |
| head: `${context.repo.owner}:${run.head_branch}` | |
| }); | |
| return prs.data.length > 0 ? prs.data[0].number : null; | |
| - name: Download test artifacts | |
| if: steps.pr.outputs.result != 'null' | |
| id: download-tests | |
| uses: actions/download-artifact@v7 | |
| continue-on-error: true | |
| with: | |
| pattern: test-results-* | |
| path: test-results | |
| run-id: ${{ github.event.workflow_run.id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| - name: Download coverage artifact | |
| if: steps.pr.outputs.result != 'null' && github.event.workflow_run.conclusion == 'success' | |
| id: download-coverage | |
| uses: actions/download-artifact@v7 | |
| continue-on-error: true | |
| with: | |
| name: coverage-report | |
| run-id: ${{ github.event.workflow_run.id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| path: coverage | |
| - name: Restore baseline coverage | |
| if: steps.pr.outputs.result != 'null' && steps.download-coverage.outcome == 'success' | |
| id: baseline | |
| uses: actions/cache/restore@v5 | |
| with: | |
| path: baseline-coverage.xml | |
| key: coverage-baseline-latest | |
| - name: Generate combined report | |
| if: steps.pr.outputs.result != 'null' | |
| id: report | |
| run: | | |
| echo "## 🐧 Linux Build Results" > comment.md | |
| echo "" >> comment.md | |
| # === Test Results Section === | |
| if [[ -d "test-results" && -n "$(ls -A test-results 2>/dev/null)" ]]; then | |
| echo "### 🧪 Test Results" >> comment.md | |
| echo "" >> comment.md | |
| TOTAL_PASSED=0 | |
| TOTAL_FAILED=0 | |
| TOTAL_SKIPPED=0 | |
| # Function to process a test output file | |
| process_test_file() { | |
| local file="$1" | |
| local arch="$2" | |
| # grep -c outputs count but exits 1 if no matches, so we can't use || | |
| PASSED=$(grep -c "^PASS" "$file" 2>/dev/null) || PASSED=0 | |
| FAILED=$(grep -c "^FAIL" "$file" 2>/dev/null) || FAILED=0 | |
| SKIPPED=$(grep -c "^SKIP" "$file" 2>/dev/null) || SKIPPED=0 | |
| TOTAL_PASSED=$((TOTAL_PASSED + PASSED)) | |
| TOTAL_FAILED=$((TOTAL_FAILED + FAILED)) | |
| TOTAL_SKIPPED=$((TOTAL_SKIPPED + SKIPPED)) | |
| if [[ "$FAILED" -gt 0 ]]; then | |
| echo "**$arch**: ❌ $PASSED passed, $FAILED failed, $SKIPPED skipped" >> comment.md | |
| echo "" >> comment.md | |
| echo "<details><summary>Failed tests</summary>" >> comment.md | |
| echo "" >> comment.md | |
| echo '```' >> comment.md | |
| grep "^FAIL" "$file" | head -20 >> comment.md | |
| echo '```' >> comment.md | |
| echo "</details>" >> comment.md | |
| else | |
| echo "**$arch**: ✅ $PASSED passed, $SKIPPED skipped" >> comment.md | |
| fi | |
| echo "" >> comment.md | |
| } | |
| # Check for test files in subdirectories (multiple artifacts downloaded) | |
| for dir in test-results/*/; do | |
| if [[ -d "$dir" && -f "${dir}test-output.txt" ]]; then | |
| ARCH=$(basename "$dir" | sed 's/test-results-//') | |
| process_test_file "${dir}test-output.txt" "$ARCH" | |
| fi | |
| done | |
| # Also check for test file directly in test-results/ (single artifact case) | |
| if [[ -f "test-results/test-output.txt" ]]; then | |
| process_test_file "test-results/test-output.txt" "linux_gcc_64" | |
| fi | |
| if [[ "$TOTAL_FAILED" -gt 0 ]]; then | |
| echo "**Total: $TOTAL_PASSED passed, $TOTAL_FAILED failed, $TOTAL_SKIPPED skipped** ❌" >> comment.md | |
| else | |
| echo "**Total: $TOTAL_PASSED passed, $TOTAL_SKIPPED skipped** ✅" >> comment.md | |
| fi | |
| echo "" >> comment.md | |
| fi | |
| # === Coverage Section === | |
| if [[ -f "coverage/coverage.xml" ]]; then | |
| echo "### 📊 Code Coverage" >> comment.md | |
| echo "" >> comment.md | |
| # Extract coverage percentage | |
| COVERAGE=$(python3 -c " | |
| import xml.etree.ElementTree as ET | |
| tree = ET.parse('coverage/coverage.xml') | |
| root = tree.getroot() | |
| line_rate = float(root.get('line-rate', 0)) | |
| print(f'{line_rate * 100:.1f}%') | |
| " 2>/dev/null || echo "N/A") | |
| if [[ -f "baseline-coverage.xml" ]]; then | |
| BASELINE=$(python3 -c " | |
| import xml.etree.ElementTree as ET | |
| tree = ET.parse('baseline-coverage.xml') | |
| root = tree.getroot() | |
| line_rate = float(root.get('line-rate', 0)) | |
| print(f'{line_rate * 100:.1f}') | |
| " 2>/dev/null || echo "0") | |
| CURRENT=$(python3 -c " | |
| import xml.etree.ElementTree as ET | |
| tree = ET.parse('coverage/coverage.xml') | |
| root = tree.getroot() | |
| line_rate = float(root.get('line-rate', 0)) | |
| print(f'{line_rate * 100:.1f}') | |
| " 2>/dev/null || echo "0") | |
| DIFF=$(python3 -c "print(f'{float(\"$CURRENT\") - float(\"$BASELINE\"):+.1f}')" 2>/dev/null || echo "+0.0") | |
| echo "| Coverage | Baseline | Change |" >> comment.md | |
| echo "|----------|----------|--------|" >> comment.md | |
| echo "| $COVERAGE | ${BASELINE}% | ${DIFF}% |" >> comment.md | |
| else | |
| echo "Coverage: **$COVERAGE**" >> comment.md | |
| echo "" >> comment.md | |
| echo "*No baseline available for comparison*" >> comment.md | |
| fi | |
| echo "" >> comment.md | |
| fi | |
| echo "---" >> comment.md | |
| echo "<sub>From Linux workflow run at $(date -u '+%Y-%m-%d %H:%M:%S UTC')</sub>" >> comment.md | |
| cat comment.md | |
| - name: Post combined comment | |
| if: steps.pr.outputs.result != 'null' | |
| uses: thollander/actions-comment-pull-request@v3 | |
| with: | |
| pr-number: ${{ steps.pr.outputs.result }} | |
| comment-tag: test-results | |
| file-path: comment.md | |
| save-baseline: | |
| name: Save Coverage Baseline | |
| runs-on: ubuntu-latest | |
| if: > | |
| github.event.workflow_run.head_branch == 'master' && | |
| github.event.workflow_run.conclusion == 'success' | |
| timeout-minutes: 5 | |
| steps: | |
| - name: Download coverage artifact | |
| id: download | |
| uses: actions/download-artifact@v7 | |
| continue-on-error: true | |
| with: | |
| name: coverage-report | |
| run-id: ${{ github.event.workflow_run.id }} | |
| github-token: ${{ secrets.GITHUB_TOKEN }} | |
| path: coverage | |
| - name: Save baseline coverage | |
| if: steps.download.outcome == 'success' | |
| uses: actions/cache/save@v5 | |
| with: | |
| path: coverage/coverage.xml | |
| key: coverage-baseline-latest |