Skip to content

Latest commit

 

History

History
208 lines (162 loc) · 9.51 KB

File metadata and controls

208 lines (162 loc) · 9.51 KB

Copilot instructions for this repository

ALWAYS follow these instructions first and only fallback to additional search and context gathering if the information here is incomplete or found to be in error.

  • Review the CONTRIBUTING.md file for instructions to build and test the software.
  • Run the .github/Prime-ForCopilot.ps1 script (once) before running any dotnet or msbuild commands. If you see any build errors about not finding git objects or a shallow clone, it may be time to run this script again.

Working Effectively

Bootstrap and Build

CRITICAL: Set the NBGV_GitEngine environment variable to Disabled before running ANY dotnet or msbuild commands.

export NBGV_GitEngine=Disabled

Setup dependencies (takes ~2-3 seconds):

./init.ps1 -UpgradePrerequisites -NoNuGetCredProvider

Build the repository (takes 7-76 seconds depending on cache - do not cancel unless it exceeds 10-15 minutes, set timeout to 10-15 minutes):

dotnet build tools/dirs.proj -t:build,pack --no-restore -c Release

Testing

Run tests (takes ~25 seconds - NEVER CANCEL, set timeout to 5-10 minutes):

dotnet test --no-build -c Release -- --filter-not-trait "TestCategory=FailsInCloudTest"

Code Quality

Verify code formatting (takes ~71 seconds - NEVER CANCEL, set timeout to 90+ minutes):

dotnet format --verify-no-changes --no-restore

Build documentation (takes ~19 seconds):

DocFx=true dotnet docfx docfx/docfx.json --warningsAsErrors --disableGitFeatures

NEVER CANCEL: Code formatting verification takes approximately 71 seconds. This is normal and expected.

Validation Scenarios

ALWAYS test functionality after making changes by running validation scenarios:

Test AOT Native Console sample:

cd test/AotNativeConsole
dotnet run --no-build -c Release

Expected output: JSON data followed by tree structure with fruits and seeds, ending with "Success".

Test ASP.NET MVC integration:

cd samples/AspNetMvc
dotnet run --no-build -c Release

Should start web server without errors (web UI testing limited in this environment).

Performance optimization

  • Establish a BenchmarkDotNet baseline before changing a hot path. For primitive integer encoding and decoding, run:
    dotnet run --project test/Benchmarks/Benchmarks.csproj -c Release -f net10.0 -- --filter "*IntegerPrimitives*" --job short
  • Keep benchmark input distributions explicit and reproducible. Small, Mixed, and Large integer datasets exercise distinct MessagePack encodings and branch-prediction behavior; do not replace them with a single representative input.
  • For branch-sensitive work, use sufficiently large randomized datasets so a branch predictor cannot learn a short repeating sequence. Preserve the fixed random seed unless intentionally changing the workload.
  • Review allocation, generated assembly, branch instructions, and branch mispredictions alongside elapsed time. Hardware counters require an elevated Windows process; an unavailable counter is not evidence of zero misses.
  • Benchmark changes measure behavior; they do not prove correctness. Verify all MessagePack encoding boundaries and error behavior with the relevant tests before accepting an optimization.
  • Prefer narrowly targeted candidates and retain a simple, verified baseline until benchmark results and generated assembly demonstrate a repeatable improvement for the intended distributions.

Repository Structure

Key Projects (src/)

  • Nerdbank.MessagePack - Main MessagePack serialization library
  • Nerdbank.MessagePack.SignalR - SignalR integration
  • Nerdbank.MessagePack.AspNetCoreMvcFormatter - ASP.NET Core MVC formatter
  • Nerdbank.MessagePack.Analyzers - Roslyn analyzers and code fixes

Test Projects (test/)

  • Each shipping project has a corresponding .Tests project
  • AotNativeConsole - NativeAOT compatibility validation
  • Benchmarks - Performance benchmarks

Samples (samples/)

  • AspNetMvc - ASP.NET Core MVC integration example
  • SignalR - SignalR integration example
  • cs and fs - C# and F# usage examples

Software Design

  • Design APIs to be highly testable, and all functionality should be tested.
  • Avoid introducing binary breaking changes in public APIs of projects under src unless their project files have IsPackable set to false.

Testing

IMPORTANT: This repository uses Microsoft.Testing.Platform (MTP v2) with xunit v3. Traditional --filter syntax does NOT work. Use the options below instead.

  • There should generally be one test project (under the test directory) per shipping project (under the src directory). Test projects are named after the project being tested with a .Tests suffix.
  • Tests use xunit v3 with Microsoft.Testing.Platform (MTP v2). Traditional VSTest --filter syntax does NOT work.
  • Some tests are known to be unstable. When running tests, you should skip the unstable ones by using -- --filter-not-trait "TestCategory=FailsInCloudTest".

Running Tests

Run all tests:

dotnet test --no-build -c Release

Run tests for a specific test project:

dotnet test --project test/Nerdbank.MessagePack.Tests/Nerdbank.MessagePack.Tests.csproj --no-build -c Release

Run a single test method:

dotnet test --project test/Nerdbank.MessagePack.Tests/Nerdbank.MessagePack.Tests.csproj --no-build -c Release -- --filter-method ClassName.MethodName

Run all tests in a test class:

dotnet test --project test/Nerdbank.MessagePack.Tests/Nerdbank.MessagePack.Tests.csproj --no-build -c Release -- --filter-class ClassName

Run tests with wildcard matching (supports wildcards at beginning and/or end):

dotnet test --project test/Nerdbank.MessagePack.Tests/Nerdbank.MessagePack.Tests.csproj --no-build -c Release -- --filter-method "*Pattern*"

Run tests with a specific trait (equivalent to category filtering):

dotnet test --project test/Nerdbank.MessagePack.Tests/Nerdbank.MessagePack.Tests.csproj --no-build -c Release -- --filter-trait "TraitName=value"

Exclude tests with a specific trait (skip unstable tests):

dotnet test --project test/Nerdbank.MessagePack.Tests/Nerdbank.MessagePack.Tests.csproj --no-build -c Release -- --filter-not-trait "TestCategory=FailsInCloudTest"

Run tests for a specific framework only:

dotnet test --project test/Nerdbank.MessagePack.Tests/Nerdbank.MessagePack.Tests.csproj --no-build -c Release --framework net9.0

List all available tests without running them:

cd test/Nerdbank.MessagePack.Tests
dotnet run --no-build -c Release --framework net9.0 -- --list-tests

Key points about test filtering with MTP v2 / xunit v3:

  • Options after -- are passed to the test runner, not to dotnet test
  • Use --filter-method, --filter-class, --filter-namespace for simple filtering
  • Use --filter-trait and --filter-not-trait for trait-based filtering (replaces --filter "TestCategory=...")
  • Traditional VSTest --filter expressions do NOT work
  • Wildcards * are supported at the beginning and/or end of filter values
  • Multiple simple filters of the same type use OR logic, different types combine with AND
  • See --help for query filter language for advanced scenarios

Coding Style

  • Honor StyleCop rules and fix any reported build warnings after getting tests to pass.
  • In C# files, use namespace statements instead of namespace blocks for all new files.
  • Add API doc comments to all new public and internal members.
  • Always run dotnet format --verify-no-changes --no-restore before committing changes or CI will fail.

Documentation

  • When writing DocFX documentation (.md files in the docfx directory), use <xref:symbolname> syntax for cross-references to types and members instead of @symbolname syntax.
    • Example: Use <xref:Nerdbank.MessagePack.ConverterContext> instead of @Nerdbank.MessagePack.ConverterContext
    • This ensures proper linking and IDE support in the generated documentation.
  • Code samples should be placed in the samples/cs directory with region tags and referenced from documentation using [!code-csharp[](path#region)] syntax.
    • This keeps samples compilable and tested as part of the build.

Common Tasks

After Making Changes

  1. Build: dotnet build tools/dirs.proj -t:build,pack --no-restore -c Release (NEVER CANCEL - 7-76s)
  2. Test: dotnet test --no-build -c Release -- --filter-not-trait "TestCategory=FailsInCloudTest" (25s)
  3. Format: dotnet format --verify-no-changes --no-restore (NEVER CANCEL - 71s)
  4. Validate: Run AOT console sample for functionality verification

Documentation Updates

cd docfx
dotnet docfx --serve
# Make changes, then rebuild with:
dotnet docfx

Troubleshooting

  • Build fails: Ensure NBGV_GitEngine=Disabled is set
  • Long restore times: Use ./init.ps1 to bootstrap dependencies first
  • Test instability: Always use -- --filter-not-trait "TestCategory=FailsInCloudTest"
  • Format failures: Run dotnet format (without --verify-no-changes) to fix automatically

CRITICAL Timing Expectations

  • Dependency setup: 2-3 seconds
  • Full build: 7-76 seconds (fast with cache, slower on first build) (NEVER CANCEL - use 120+ minute timeouts)
  • Test suite: ~25 seconds (NEVER CANCEL - use 60+ minute timeouts)
  • Format verification: ~71 seconds (NEVER CANCEL - use 90+ minute timeouts)
  • Documentation build: ~19 seconds

NEVER CANCEL long-running commands - these timing expectations are normal for this repository.