Skip to content

Build one test project per Roslyn version - #1301

Merged
meziantou merged 2 commits into
mainfrom
feature/test-csproj-roslyn-version-7cf854
Aug 19, 2026
Merged

meziantou merged 2 commits into
mainfrom
feature/test-csproj-roslyn-version-7cf854

Conversation

@meziantou

Copy link
Copy Markdown
Owner

The analyzer and the code fixers already had one project per Roslyn version, but the tests did not: a single test project was built against whatever /p:RoslynVersion was passed to it. This applies the same pattern to the tests, and removes the duplication that made it necessary.

Tests follow the src pattern

One Meziantou.Analyzer.Test.roslyn<version>.csproj per version, with the shared content moved to the Directory.Build.props of the folder. Each test project references the analyzer and the code fixers of its own Roslyn version.

The development projects are gone

Meziantou.Analyzer.csproj, Meziantou.Analyzer.CodeFixers.csproj and Meziantou.Analyzer.Test.csproj are removed, as every project is now tied to a Roslyn version. DocumentationGenerator is not specific to a version, so it references Meziantou.Analyzer.$(RoslynVersion).csproj and follows the default. Its Version="4.11.0" on Microsoft.CodeAnalysis.CSharp.Workspaces was already dead (the Update in Directory.Build.targets overrode it to 5.9.0), so it was dropped.

/p:RoslynVersion is no longer a way to build another version — build or test the project of that version instead. The version specific projects keep TreatAsLocalProperty="RoslynVersion" so a stray /p:RoslynVersion cannot silently retarget them.

Less to maintain per version

RoslynVersion is derived from the name of the project file in the Directory.Build.props of the repository root, so the 15 version specific projects are now empty. The version of the Microsoft.CodeAnalysis.* packages is derived from it too, replacing the 15 hardcoded entries in Directory.Build.targets; what stays version specific there is DefineConstants and the warnings to disable.

Removing the Otherwise branch created a silent failure path: a project named after an unsupported version would have compiled with no ROSLYN_* constant at all, quietly dropping #if blocks while still succeeding. Each When now sets RoslynVersionSupported and a BeforeBuild target errors otherwise.

CI

The build_and_test matrix is discovered from the test projects present in the repository instead of being hardcoded, and a list_test_projects job validates that every Roslyn version has an analyzer, a code fixer and a test project, and that the default version is the latest supported one. The version comparison casts to [version], so roslyn5.10 sorts after roslyn5.9.

Also removed runs-on and configuration from the matrix, as each had a single value.

Note for reviewers

All the test projects produce an assembly named Meziantou.Analyzer.Test (required by the InternalsVisibleTo in AssemblyInfo.cs), so on a solution wide run they all wrote the same trx file and five reports were silently overwritten. Each project now sets its own report name. CI was never affected, as it runs one project per job.

build/update-version.ps1 referenced the deleted Meziantou.Analyzer.csproj, but it was already dead before this change: it targets a PackageVersion property and a src/Meziantou.Analyzer.Vsix/ folder that no longer exist, and the CI computes the version itself. Left untouched, but it looks like a candidate for deletion.

Verification

  • Solution builds with 0 warnings and 0 errors.
  • 17,921 tests pass across the 5 Roslyn versions, and each project writes its own trx file.
  • Resolved package versions checked project by project against the removed table: identical.
  • dotnet run --project src/DocumentationGenerator exits 0 with byte identical markdown.
  • The packed nupkg contains the analyzers for the 5 versions and nothing under lib/.
  • Both CI PowerShell steps were run against the real tree, including the failure paths: missing test project, orphan test project, missing code fixer, a newer version added without bumping the default, and a default pointing at a removed version.

meziantou and others added 2 commits August 19, 2026 01:38
The analyzer and the code fixers already had one project per Roslyn
version. The tests did not, so a single test project was built against
whatever /p:RoslynVersion was passed to it.

- Add tests/Meziantou.Analyzer.Test/Meziantou.Analyzer.Test.roslyn<version>.csproj
  and move the shared content to the Directory.Build.props of the folder,
  the same way the src folders are organized. Each test project references
  the analyzer and the code fixers of its own Roslyn version.
- Remove the development projects (Meziantou.Analyzer.csproj,
  Meziantou.Analyzer.CodeFixers.csproj and Meziantou.Analyzer.Test.csproj),
  as every project is now tied to a Roslyn version. DocumentationGenerator
  uses the default version.
- Derive RoslynVersion from the name of the project file in the
  Directory.Build.props of the repository root, so the version specific
  projects are empty, and derive the version of the Microsoft.CodeAnalysis
  packages from it instead of listing it for each version. A project named
  after an unsupported version now fails with an explicit error.
- Give each test project its own trx file, as they all produce an assembly
  named Meziantou.Analyzer.Test and would otherwise overwrite each other.
- Build the CI matrix from the test projects found in the repository
  instead of hardcoding it, and validate that every Roslyn version has an
  analyzer, a code fixer and a test project, and that the default version
  is the latest supported one.
@meziantou
meziantou merged commit fdec2e6 into main Aug 19, 2026
12 checks passed
@meziantou
meziantou deleted the feature/test-csproj-roslyn-version-7cf854 branch August 19, 2026 05:54
This was referenced Aug 19, 2026
This was referenced Sep 20, 2026
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.

1 participant