Generate and upload code coverage reports#38482
Conversation
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
There was a problem hiding this comment.
Pull request overview
Adds first-class GitHub Code Quality code coverage reporting to the existing Build GitHub Actions workflow, so PRs can display coverage results and compare against the default branch baseline.
Changes:
- Adds
pushtriggers onmain(in addition topull_request) to support baseline comparisons. - Grants per-job
contents: readandcode-quality: writepermissions required for coverage upload. - Generates Cobertura coverage during
dotnet test, merges per-project reports, and uploads the merged report for each test job/matrix leg.
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
… jobs in azure-pipelines-public.yml and azure-pipelines-internal-tests.yml Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
…MTP to 2.2.3 v17.10.1 guarded the TestingPlatformBuilderHook behind GenerateTestingPlatformEntryPoint == 'True', which xunit v3 sets to false (using GenerateSelfRegisteredExtensions=true instead), so the --coverage MTP extension was never registered → "Unknown option '--coverage'". v18.8.0 removes that condition. MTP must also be bumped to 2.2.3 because CodeCoverage 18.8.0 has a hard dependency on it; Arcade's XUnitV3.targets injects the MTP package references using $(MicrosoftTestingPlatformVersion). Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Code Coverage OverviewLanguages: C# C# / code-coverage/microsoft-data-sqlite-ubuntu-24.04The overall coverage in the branch is 76%. Coverage data for the branch is not yet available. Show a code coverage summary of the most covered files.
C# / code-coverage/microsoft-data-sqlite-windows-2025The overall coverage in the branch is 77%. Coverage data for the branch is not yet available. Show a code coverage summary of the most covered files.
C# / code-coverage/cosmos-ubuntu-24.04The overall coverage in the branch is 39%. Coverage data for the branch is not yet available. Show a code coverage summary of the most covered files.
C# / code-coverage/sqlite-ubuntu-24.04The overall coverage in the branch is 58%. Coverage data for the branch is not yet available. Show a code coverage summary of the most covered files.
C# / code-coverage/sqlite-windows-2025The overall coverage in the branch is 60%. Coverage data for the branch is not yet available. Show a code coverage summary of the most covered files.
C# / code-coverage/cosmos-windows-2025The overall coverage in the branch is 39%. Coverage data for the branch is not yet available. Show a code coverage summary of the most covered files.
C# / code-coverage/main-windows-2025The overall coverage in the branch is 34%. Coverage data for the branch is not yet available. Show a code coverage summary of the most covered files.
C# / code-coverage/main-ubuntu-24.04The overall coverage in the branch is 34%. Coverage data for the branch is not yet available. Show a code coverage summary of the most covered files.
Updated |
…es job Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: AndriySvyryd <6539701+AndriySvyryd@users.noreply.github.com>
Co-authored-by: Copilot Autofix powered by AI <175728472+Copilot@users.noreply.github.com>
| <_CoverageOutputDir Condition="'$(CollectCoverage)' == 'true'">$([MSBuild]::NormalizeDirectory('$(ArtifactsDir)', 'coverage'))</_CoverageOutputDir> | ||
| <TestingPlatformCommandLineArguments Condition="'$(CollectCoverage)' == 'true'">$(TestingPlatformCommandLineArguments) --coverage --coverage-output-format cobertura --coverage-output $(_CoverageOutputDir)$(MSBuildProjectName).cobertura.xml --coverage-settings $(MSBuildThisFileDirectory)..\eng\efcore.coverage.xml</TestingPlatformCommandLineArguments> |
| - name: Upload coverage report | ||
| if: github.event_name != 'pull_request' || github.event.pull_request.head.repo.full_name == github.repository | ||
| uses: actions/upload-code-coverage@abb5995db9e0199b0e2bb9dbd136fce4cb1ec4d3 |
Fixes #24990
Wires the PR
Buildworkflow into GitHub Code Quality coverage so reviewers see coverage results on pull requests. Also adds code coverage reporting to the AzDO pipelines.Changes
pushonmainalongsidepull_request; Code Quality diffs PR coverage against the default-branch baseline, so both are required.coveragejob grantscontents: read+code-quality: write; all other jobs and the top-level stay atpermissions: {}.Microsoft.Testing.Extensions.CodeCoverage(18.8.0) is now referenced by all runnable test projects viatest/Directory.Build.props(gated onIsTestProject != false, so shipped spec-test libraries are excluded). The version is declared asMicrosoftTestingExtensionsCodeCoverageVersionineng/Versions.propsandtest/Directory.Packages.props. v18+ is required because v17 guarded itsTestingPlatformBuilderHookbehindGenerateTestingPlatformEntryPoint='True', which xunit v3 sets tofalse.MicrosoftTestingPlatformVersionis also bumped to2.2.3as required by CodeCoverage 18.x.eng/efcore.coverage.xmlsettings file restricts coverage collection to source files undersrc/only (via aSources > Includefilter matching.*[/\\]src[/\\].*). This excludes test helpers such asEFCore.Specification.TestsandEFCore.Relational.Specification.Tests(which live undertest/) from all reports.CollectCoverageMSBuild property intest/Directory.Build.propsappends--coverage --coverage-output-format cobertura --coverage-output <ArtifactsDir>/coverage/<ProjectName>.cobertura.xml --coverage-settings <repo>/eng/efcore.coverage.xmltoTestingPlatformCommandLineArgumentswhen set. Passing/p:CollectCoverage=trueto the existing Arcade build/test command activates scoped coverage for all test projects without a separate test run.coverage-main-ubuntu-24.04). No merging or code-quality upload happens in individual test jobs.coveragejob (needsall five test jobs,if: always()) downloads everycoverage-*artifact, merges all Cobertura files into onecoverage.cobertura.xmlwithdotnet-coverage merge, and does a singleactions/upload-code-coverageupload (pinned to SHA,language: C#, labelcode-coverage,fail-on-error: false). The fork-skip guard is applied here.ApiBaselinesjob runsdotnet test test/EFCore.ApiBaseline.Testson ubuntu-24.04.ApiBaselineis added to the Main job's exclusion list to avoid running it twice.azure-pipelines-public.yml(Windows, Windows_SqlServer, macOS, Linux) andazure-pipelines-internal-tests.yml(Windows, Windows_SqlServer, macOS, Linux, Linux_Cosmos) by passing/p:CollectCoverage=trueto the existing build commands. Theeng/efcore.coverage.xmlsettings file is automatically applied via the MSBuild property, so AzDO reports also cover onlysrc/code. Per-project Cobertura reports are merged and published withPublishCodeCoverageResults@2so coverage is visible in the AzDO build UI. All coverage steps usecontinueOnError: trueto keep failures non-blocking.Note
The GitHub bot coverage comment also requires GitHub Code Quality to be enabled for the repository — a setting outside this file.