Skip to content

Fix macOS grep -P incompatibility in Stage 3 coverage threshold enforcement (pr.yaml)#78

Merged
Chris-Wolfgang merged 4 commits intocopilot/add-coverlet-collector-referencefrom
copilot/fix-grep-issues-in-workflow
Mar 12, 2026
Merged

Fix macOS grep -P incompatibility in Stage 3 coverage threshold enforcement (pr.yaml)#78
Chris-Wolfgang merged 4 commits intocopilot/add-coverlet-collector-referencefrom
copilot/fix-grep-issues-in-workflow

Conversation

Copy link
Copy Markdown
Contributor

Copilot AI commented Mar 12, 2026

Description

macOS BSD grep does not support -P (Perl-compatible regex), causing Stage 3 (macOS) to fail with an invalid option error during coverage gate enforcement — even when coverage is 100%. The while/grep -oP block in pr.yaml that parses CoverageReport/Summary.txt in the Stage 3 (macOS) coverage gate is replaced with a portable POSIX awk implementation. Stage 1 (Linux) is unchanged, as GNU grep supports -P on Ubuntu runners.

Changes — .github/workflows/pr.yaml:

  • Stage 3 (macOS) coverage gate only: Replace while IFS= read -r line; do ... grep -oP ... done with a single awk command
awk -v threshold="$THRESHOLD" '
  BEGIN { failed = 0 }
  /^[^ ]+.*[0-9]+%$/ && !/^Summary/ {
    module = $1
    pct = 0; s = $0
    while (match(s, /[0-9]+%/)) {
      pct = substr(s, RSTART, RLENGTH-1) + 0
      s = substr(s, RSTART + RLENGTH)
    }
    printf "Checking module: \047%s\047 - Coverage: %d%%\n", module, pct
    if (pct < threshold) {
      print "  \342\235\214 FAIL: Below " threshold "% threshold"
      failed = 1
    } else {
      print "  \342\234\205 PASS: Meets " threshold "% threshold"
    }
  }
  END { exit failed }
' CoverageReport/Summary.txt || FAILED=1
  • Iterates all number% occurrences per line to match the original grep -oP ... | tail -1 (last-match) behavior
  • Octal escapes for single quote (\047) and emoji to avoid shell quoting issues inside the awk single-quoted program
  • Logic is otherwise identical to the original: matches ^[^ ]+.*[0-9]+%$, skips Summary lines

Type of change

  • Bug fix

How Has This Been Tested?

  • Manually tested the awk logic against representative Summary.txt content: all-pass, mixed pass/fail, Summary-line exclusion, and empty-file cases all produce correct output and exit codes.

Checklist

  • My code follows the style guidelines of this project
  • I have performed a self-review of my own code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes

Screenshots (if applicable)

N/A

Additional context

Only the Stage 3 (macOS) Bash coverage parsing logic is changed. Stage 1 (Linux) retains the original grep -oP implementation, which works correctly on Ubuntu runners. No test projects, coverage config, or other workflow steps are modified. The grep -oP usages on lines 150 and 201 are framework-detection logic that runs exclusively on Ubuntu and are also unaffected.

Original prompt

The GitHub Actions workflow for Stage 3 (macOS) fails due to the use of GNU-specific 'grep -P' and 'grep -oP' in the Bash coverage threshold enforcement logic. On macOS, grep does not support these options, causing an invalid option error even when coverage is 100%.

Solution:

  • Replace the while-read/grep/grep -oP block that parses CoverageReport/Summary.txt with a portable awk-based check that extracts module and percent fields and compares percent to the threshold.
  • Confirm that the awk solution works for all lines checked by the old logic (parsing CoverageReport/Summary.txt, excluding 'Summary' lines, and checking all modules).
  • Ensure this new code works for both Linux and macOS runners.

No test or coverage config changes are needed, only the Bash parsing logic.

The following is the prior conversation context from the user's chat exploration (may be truncated):

User: This worked before and the pr.yaml was recently updated. Compare the current pr.yaml to the previous version

Assistant: The current and previous versions of your .github/workflows/pr.yaml are identical, at least as far as the linted output and job structure for test project discovery in the Linux/Stage 1 step are concerned.

Here’s the relevant block from both versions:

- name: Run tests (.NET 5.0-10.0 and netcoreapp3.1)
  run: |
    # Find all test projects (C#, VB.NET, F#)
    mapfile -d '' -t test_projects < <(find ./tests -type f \( -name "*.csproj" -o -name "*.vbproj" -o -name "*.fsproj" \) -print0)
    if [ ${#test_projects[@]} -eq 0 ]; then
      echo "❌ No test projects found in ./tests directory!"
      exit 1
    fi
    ...

The search looks in ./tests recursively for any .csproj file, which matches your actual structure.


What might be different?

If you are suddenly getting the "No test projects found in ./tests directory!" error, but the workflow didn't change, consider:

  • Has the repo's test folder path or contents changed (symlinks, permissions, or casing)?
  • Is the workflow running in an environment where Bash is missing or not the default shell? (mapfile is Bash-specific)
  • Could there be a GLOBIGNORE, .dockerignore, or CI env oversight that prevents find from matching anything?
  • Did anything change in your repo’s check-out or working-directory logic?

What to do next

1. Confirm the Bash Shell

Make your test step explicit (add this if missing!):

shell: bash

2. Add Debug Output

Add this debug just before the mapfile step to catch directory structure issues:

- name: Debug folder structure
  run: |
    ls -lR ./tests
    find ./tests -type f
  shell: bash

3. Confirm the path exists at runtime (sometimes checkouts or job matrixes mess up working dirs).


Summary

There is no detectable difference in the discovery logic between the current and previous PR workflow YAML. All code is still searching for test projects in ./tests as before.

  • The most likely root cause is an environment or shell difference, or subtle path/checkout issue not directly related to the contents of the YAML itself.

If you want, I can generate a patched step for debugging this issue further!

User: The pr.yaml is still failing on step 1 linux on the code coverage.

if find ./TestResults -name "coverage.cobertura.xml" -print -quit 2>/dev/null | grep -q .; then
reportgenerator
-reports:"TestResults/**/coverage.cobertura.xml"
-targetdir:"CoverageReport"
-reporttypes:"Html;TextSummary;MarkdownSummaryGithub;CsvSummary"
else
echo "ℹ️ No coverage files found - skipping report generation"
fi
shell: /usr/bin/bash -e {0}
env:
CODECOV_MINIMUM: 90
DOTNET_ROOT: /usr/share/dotnet
ℹ️ No coverage files found - skipping report generation
0s
Run if [ ! -f "CoverageReport/Summary.txt" ]; then
if [ ! -f "CoverageReport/Summary.txt" ]; then
echo "❌ Coverage report not generated!"
exit 1
fi

echo "Coverage Summary:"
cat CoverageReport/Summary.txt
echo ""

THRESHOLD=${CODECOV_MINIMUM:-90}
FAILED=0

while IFS= read -r line; do
if echo "$line" | grep -qE '^[^ ]+.*[0-9]+%$' && ! echo "$line" | grep -q '^Summary'; then
MODULE=$(echo "$line" | grep -oP '^[^ ]+')
PERCENT=$(echo "$line" | grep -oP '[0-9]+(?=%)' | tail -1)
echo "Checking module: '$MODULE' - Coverage: ${PERCENT}%"
if [ "$PERCENT" -lt "$THRESHOLD" ]; then
echo " ❌ FAIL: Below ${THRESHOLD}% threshold"
FAILED=1
else
echo " ✅ PASS: Meets ${THRESHOLD}% threshold"
fi
fi
done < CoverageReport/Summary.txt

if [ "$FAILED" -ne 0 ]; then
echo ""
echo "=========================================="
echo "❌ COVERAGE GATE FAILED"
echo "=========================================="
echo "One or more modules are below ${THRESHOLD}% coverage."
echo "Stage 1 failed. Windows and macOS tests will NOT run."
exit 1
fi

e...

This pull request was created from Copilot chat.


💡 You can make Copilot smarter by setting up custom instructions, customizing its development environment and configuring Model Context Protocol (MCP) servers. Learn more Copilot coding agent tips in the docs.

Co-authored-by: Chris-Wolfgang <210299580+Chris-Wolfgang@users.noreply.github.com>
Copilot AI changed the title [WIP] Fix GitHub Actions workflow by replacing grep with awk Fix macOS grep -P incompatibility in coverage threshold enforcement (pr.yaml) Mar 12, 2026
Copilot AI requested a review from Chris-Wolfgang March 12, 2026 19:21
@Chris-Wolfgang Chris-Wolfgang changed the base branch from main to copilot/add-coverlet-collector-reference March 12, 2026 19:42
Copy link
Copy Markdown
Owner

@Chris-Wolfgang Chris-Wolfgang left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This change should only be applied to stage 3. stage 1 works fine

…Stage 3 only

Co-authored-by: Chris-Wolfgang <210299580+Chris-Wolfgang@users.noreply.github.com>
Copy link
Copy Markdown
Contributor Author

Copilot AI commented Mar 12, 2026

This change should only be applied to stage 3. stage 1 works fine

Reverted in 7d66b76 — Stage 1 is back to the original grep -oP logic; only Stage 3 (macOS) has the awk fix.

Copilot AI changed the title Fix macOS grep -P incompatibility in coverage threshold enforcement (pr.yaml) Fix macOS grep -P incompatibility in Stage 3 coverage threshold enforcement (pr.yaml) Mar 12, 2026
Copilot AI requested a review from Chris-Wolfgang March 12, 2026 19:45
@Chris-Wolfgang Chris-Wolfgang marked this pull request as ready for review March 12, 2026 19:52
Copilot AI review requested due to automatic review settings March 12, 2026 19:52
Copy link
Copy Markdown
Contributor

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Copilot wasn't able to review any files in this pull request.


You can also share your feedback on Copilot code review. Take the survey.

@Chris-Wolfgang Chris-Wolfgang merged commit 5db3174 into copilot/add-coverlet-collector-reference Mar 12, 2026
1 check passed
@Chris-Wolfgang Chris-Wolfgang deleted the copilot/fix-grep-issues-in-workflow branch March 12, 2026 19:53
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants