Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 9 additions & 0 deletions Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,15 @@
ReferenceOutputAssembly="false"
PrivateAssets="None"
Condition=" '$(OrleansBuildTimeCodeGen)' == 'true' "/>
<ProjectReference
Include="$(SourceRoot)src/Orleans.Analyzers.Contracts/Orleans.Analyzers.Contracts.csproj"
AssetTargetFallback="netstandard2.0"
UndefineProperties="TargetFramework"
SkipGetTargetFrameworkProperties="true"
OutputItemType="Analyzer"
ReferenceOutputAssembly="false"
PrivateAssets="None"
Condition=" '$(OrleansBuildTimeCodeGen)' == 'true' and '$(EnableOrleansContractsAnalyzer)' == 'true' "/>
</ItemGroup>

<ItemGroup Condition="'$(IsTestingPlatformApplication)' == 'true'">
Expand Down
2 changes: 2 additions & 0 deletions Orleans.slnx
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@
</Folder>
<Folder Name="/src/">
<Project Path="src/Orleans.Analyzers/Orleans.Analyzers.csproj" />
<Project Path="src/Orleans.Analyzers.Contracts/Orleans.Analyzers.Contracts.csproj" />
<Project Path="src/Orleans.BroadcastChannel/Orleans.BroadcastChannel.csproj" />
<Project Path="src/Orleans.Client/Orleans.Client.csproj" />
<Project Path="src/Orleans.CodeGenerator/Orleans.CodeGenerator.csproj" />
<Project Path="src/Orleans.ContractTool/Orleans.ContractTool.csproj" />
<Project Path="src/Orleans.Core.Abstractions/Orleans.Core.Abstractions.csproj" />
<Project Path="src/Orleans.Core/Orleans.Core.csproj" />
<Project Path="src/Orleans.EventSourcing/Orleans.EventSourcing.csproj" />
Expand Down
2 changes: 1 addition & 1 deletion docs/site/src/content/docs/diagnostics/orleans0020.md
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ The analyzer has no baseline, so it cannot detect RPC identity, signature, versi

## How to fix

Apply **Regenerate OrleansContracts.txt** to create and populate the complete project manifest. Use **Fix all in solution** to create manifests for every affected project, then add the generated files to source control and review the baseline using the [contract compatibility guidance](../grains/grain-versioning/contract-compatibility-analyzer.md#regenerate-the-manifest).
Apply **Regenerate OrleansContracts.txt** to create and populate the complete project manifest. The configured path can be absent; the code fix creates the file and its parent directory. For a large solution, use the `Microsoft.Orleans.ContractTool` tool to regenerate every enabled project through a filtered workspace. Add the generated files to source control and review the baseline using the [contract compatibility guidance](../grains/grain-versioning/contract-compatibility-analyzer.md#regenerate-the-manifest).

## Suppress the diagnostic

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@ The analyzer is **disabled by default**. Enable it explicitly in a project file
</PropertyGroup>
```

Projects which use `Microsoft.Orleans.Sdk`, `Microsoft.Orleans.Client`, or `Microsoft.Orleans.Server` already receive the Orleans analyzers through those packages. A project which references `Microsoft.Orleans.Analyzers` directly can use the same property.
Projects which use `Microsoft.Orleans.Sdk`, `Microsoft.Orleans.Client`, or `Microsoft.Orleans.Server` already receive the Orleans analyzers through those packages. A project which references `Microsoft.Orleans.Analyzers` directly can use the same property. Scope this property to projects which own Orleans contracts. In a large repository, set it in those projects or in a shared props file for their subtree instead of enabling contract analysis at the repository root.

To promote every contract diagnostic, configure the standard `Versioning` category:

Expand All @@ -30,14 +30,14 @@ This also promotes informational diagnostics such as `ORLEANS0020`. Configure `d

## Configure the manifest path

By default, the analyzer looks for `OrleansContracts.txt` beside the project file. The analyzer package automatically adds an existing file at that location as a compiler `AdditionalFile`; no explicit `AdditionalFiles` item is required.
By default, the analyzer tracks `OrleansContracts.txt` beside the project file. During design-time builds used by IDEs and `dotnet format`, the analyzer package registers the configured path as a compiler `AdditionalFile` before the file exists, allowing regeneration to create it. Regular builds register an existing manifest and report `ORLEANS0020` when the configured manifest is absent. No explicit `AdditionalFiles` item or seed file is required.

Set `OrleansContractsPath` to use another location or filename:

```xml
<PropertyGroup>
<EnableOrleansContractsAnalyzer>true</EnableOrleansContractsAnalyzer>
<OrleansContractsPath>$(MSBuildProjectDirectory)\contracts\rpc-contracts.txt</OrleansContractsPath>
<OrleansContractsPath>$(MSBuildProjectDirectory)/contracts/rpc-contracts.txt</OrleansContractsPath>
</PropertyGroup>
```

Expand All @@ -58,10 +58,20 @@ Apply **Regenerate OrleansContracts.txt** from `ORLEANS0016`, `ORLEANS0017`, `OR
Agents and command-line workflows can regenerate manifests without an IDE:

```dotnetcli
dotnet format PATH_TO_PROJECT_OR_SOLUTION analyzers --severity info --diagnostics ORLEANS0016 ORLEANS0017 ORLEANS0018 ORLEANS0019 ORLEANS0020 ORLEANS0022 ORLEANS0023 ORLEANS0024
dotnet format PATH_TO_PROJECT.csproj analyzers --severity info --diagnostics ORLEANS0016 ORLEANS0017 ORLEANS0018 ORLEANS0019 ORLEANS0020 ORLEANS0022 ORLEANS0023 ORLEANS0024
```

Run the command from the repository root. Replace `PATH_TO_PROJECT_OR_SOLUTION` with the path to the owning `.csproj` to regenerate one manifest, or a `.sln`/`.slnx` path to regenerate manifests in every affected project. The `--severity info` option includes `ORLEANS0020`, allowing the command to create a missing manifest.
Run the command from the repository root. Replace `PATH_TO_PROJECT.csproj` with the owning project path to regenerate one manifest. The `--severity info` option includes `ORLEANS0020`, allowing the command to create the default manifest or a configured `OrleansContractsPath`, including its parent directory.

For a large solution, install the contract tool in the repository and use it to regenerate only analyzer-enabled projects. If the repository does not have a tool manifest, create one first:

```dotnetcli
dotnet new tool-manifest
dotnet tool install Microsoft.Orleans.ContractTool
dotnet tool run orleans-contracts PATH_TO_SOLUTION.slnx
```

The tool evaluates the solution to identify enabled C# projects which contain a manifest or Orleans contract declarations, creates a temporary filtered solution, and runs regeneration against that smaller workspace. Commit the tool manifest so every developer and build agent uses the same tool version.

Regeneration edits `OrleansContracts.txt` files only. Source `[Alias]`, `[Id]`, `[GrainType]`, and `[GrainInterfaceType]` attributes remain unchanged.

Expand All @@ -71,7 +81,7 @@ After the command completes:

1. Inspect `git diff -- "*OrleansContracts.txt"` and account for every changed identity, version, and method signature.
2. Preserve all `*RETIRED*` declarations and retained removed-method signatures unless the compatibility break is intentional.
3. Run `dotnet build PATH_TO_PROJECT_OR_SOLUTION` and resolve all Orleans contract diagnostics. `ORLEANS0027` remains until a removed method is restored or its retained signature is explicitly deleted after compatibility review.
3. Run `dotnet build PATH_TO_PROJECT.csproj` and resolve all Orleans contract diagnostics. `ORLEANS0027` remains until a removed method is restored or its retained signature is explicitly deleted after compatibility review.

Add the generated file to source control and review its diff before committing. Treat every changed contract line as a potential wire-compatibility change:

Expand All @@ -89,10 +99,10 @@ Interface methods are indented beneath their interface:

```text
# This file is generated by the Orleans contract analyzer.
# To regenerate, run this command from the repository root after replacing
# PATH_TO_PROJECT_OR_SOLUTION with the owning .csproj, .sln, or .slnx path:
# dotnet format PATH_TO_PROJECT_OR_SOLUTION analyzers --severity info --diagnostics ORLEANS0016 ORLEANS0017 ORLEANS0018 ORLEANS0019 ORLEANS0020 ORLEANS0022 ORLEANS0023 ORLEANS0024
# Verify with: dotnet build PATH_TO_PROJECT_OR_SOLUTION
# To regenerate this project from the repository root:
# dotnet format PATH_TO_PROJECT.csproj analyzers --severity info --diagnostics ORLEANS0016 ORLEANS0017 ORLEANS0018 ORLEANS0019 ORLEANS0020 ORLEANS0022 ORLEANS0023 ORLEANS0024
# To regenerate an enabled solution: dotnet tool run orleans-contracts PATH_TO_SOLUTION
# Verify with: dotnet build PATH_TO_PROJECT.csproj
# The regeneration command edits this manifest only; it does not change source attributes.
# OrleansContracts format: 2
# Method lines use: wire-identity: CLR-signature.
Expand Down
8 changes: 7 additions & 1 deletion docs/site/src/content/docs/resources/nuget-packages.md
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
---
title: Orleans NuGet packages
description: Choose Orleans packages for hosts, providers, serialization, observability, and testing.
ms.date: 08/21/2026
ms.date: 08/29/2026
ms.topic: reference
---

Expand All @@ -21,6 +21,12 @@ Most applications should begin with one of these packages and then add only the

For installation guidance, see [`dotnet package add`](https://learn.microsoft.com/dotnet/core/tools/dotnet-package-add) and [NuGet package installation workflows](https://learn.microsoft.com/nuget/consume-packages/overview-and-workflow).

## Development tools

| Package | Purpose |
| --- | --- |
| `Microsoft.Orleans.ContractTool` | .NET tool which regenerates `OrleansContracts.txt` manifests for every analyzer-enabled project in a project or solution. |

## Hosting and observability

| Package | Purpose |
Expand Down
13 changes: 11 additions & 2 deletions src/Directory.Build.targets
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,18 @@
<CompilerVisibleProperty Include="OrleansContractsPath" />
</ItemGroup>

<ItemGroup Condition="'$(EnableOrleansContractsAnalyzer)' == 'true' and Exists('$(OrleansContractsPath)')">
<AdditionalFiles Include="$(OrleansContractsPath)" OrleansContractsFile="true" />
<ItemGroup Condition="'$(EnableOrleansContractsAnalyzer)' == 'true'">
<Analyzer Include="$(OrleansContractsAnalyzerPath)"
Condition="'$(OrleansContractsAnalyzerPath)' != ''" />
<AdditionalFiles Include="$(OrleansContractsPath)"
OrleansContractsFile="true"
OrleansContractsFileExists="false"
Condition="'$(DesignTimeBuild)' == 'true' or Exists('$(OrleansContractsPath)')" />
<AdditionalFiles Update="$(OrleansContractsPath)"
OrleansContractsFileExists="true"
Condition="Exists('$(OrleansContractsPath)')" />
<CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="OrleansContractsFile" />
<CompilerVisibleItemMetadata Include="AdditionalFiles" MetadataName="OrleansContractsFileExists" />
</ItemGroup>

<ItemGroup Condition="'$(IsPackable)'=='true' and '$(SourceLinkCreate)'=='true' and '$(IncludeBuildOutput)'=='true'">
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
; This analyzer has no shipped rules yet.
17 changes: 17 additions & 0 deletions src/Orleans.Analyzers.Contracts/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
; Please do not edit this file manually, it should only be updated through code fix application.

### New Rules

Rule ID | Category | Severity | Notes
--------|----------|----------|-------
ORLEANS0016 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Grain interface not declared in OrleansContracts.txt
ORLEANS0017 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Grain interface version mismatch between code and file
ORLEANS0018 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Grain interface member not declared in OrleansContracts.txt
ORLEANS0019 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Removed interface not marked as *RETIRED*
ORLEANS0020 | Versioning | Info | GrainInterfaceVersionAnalyzer, OrleansContracts.txt file is missing
ORLEANS0021 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Duplicate interface declaration in file
ORLEANS0022 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Grain class not declared in OrleansContracts.txt
ORLEANS0023 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Grain class alias mismatch
ORLEANS0024 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Removed grain class not marked as *RETIRED*
ORLEANS0025 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Duplicate grain class declaration in file
ORLEANS0027 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Removed grain interface member remains in OrleansContracts.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,90 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>netstandard2.0</TargetFramework>
<AssemblyName>Orleans.Analyzers.Contracts</AssemblyName>
<RootNamespace>Orleans.Analyzers</RootNamespace>
<PackageId>Microsoft.Orleans.Analyzers</PackageId>
<Title>Microsoft Orleans Analyzers</Title>
<Description>C# Analyzers for Microsoft Orleans.</Description>
<NoPackageAnalysis>true</NoPackageAnalysis>
<IncludeBuildOutput>false</IncludeBuildOutput>
<DevelopmentDependency>true</DevelopmentDependency>
<IsOrleansFrameworkPart>false</IsOrleansFrameworkPart>
<EnforceExtendedAnalyzerRules>true</EnforceExtendedAnalyzerRules>
<NoWarn>$(NoWarn);RS1038</NoWarn>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.CodeAnalysis.CSharp.Workspaces" PrivateAssets="all" />
<PackageReference Update="NETStandard.Library" PrivateAssets="all" />
<ProjectReference Include="..\Orleans.Analyzers\Orleans.Analyzers.csproj"
ReferenceOutputAssembly="false"
PrivateAssets="all" />
</ItemGroup>

<ItemGroup>
<Compile Include="..\Orleans.Analyzers\Constants.cs" Link="Constants.cs" />
<Compile Include="..\Orleans.Analyzers\GrainInterfaceVersionAnalyzer.cs" Link="GrainInterfaceVersionAnalyzer.cs" />
<Compile Include="..\Orleans.Analyzers\GrainInterfaceVersionCodeFix.cs" Link="GrainInterfaceVersionCodeFix.cs" />
<Compile Include="..\Orleans.Analyzers\NullableAttributes.cs" Link="NullableAttributes.cs" />
<Compile Include="..\Orleans.Analyzers\Properties\IsExternalInit.cs" Link="Properties\IsExternalInit.cs" />
<Compile Include="..\Orleans.Analyzers\Resources.Designer.cs" Link="Resources.Designer.cs" />
<Compile Include="..\Orleans.Analyzers\SymbolHelpers.cs" Link="SymbolHelpers.cs" />
<Compile Include="..\Orleans.Analyzers\SyntaxHelpers.cs" Link="SyntaxHelpers.cs" />
<Compile Include="..\Orleans.CodeGenerator.Shared\InvokableBaseTypeResolver.cs" Link="InvokableBaseTypeResolver.cs" />
<Compile Include="..\Orleans.CodeGenerator.Shared\MethodIdProvider.cs" Link="MethodIdProvider.cs" />
<Compile Include="..\Orleans.CodeGenerator\Hashing\BitOperations.cs" Link="Hashing\BitOperations.cs" />
<Compile Include="..\Orleans.CodeGenerator\Hashing\NonCryptographicHashAlgorithm.cs" Link="Hashing\NonCryptographicHashAlgorithm.cs" />
<Compile Include="..\Orleans.CodeGenerator\Hashing\XxHash32.cs" Link="Hashing\XxHash32.cs" />
<Compile Include="..\Orleans.CodeGenerator\Hashing\XxHash32.State.cs" Link="Hashing\XxHash32.State.cs" />
</ItemGroup>

<ItemGroup>
<None Include="..\Orleans.Analyzers\bin\$(Configuration)\netstandard2.0\Orleans.Analyzers.dll"
Pack="true"
PackagePath="analyzers/dotnet/cs"
Visible="false" />
<None Include="$(OutputPath)\$(AssemblyName).dll"
Pack="true"
PackagePath="tools/analyzers"
Visible="false" />
<AdditionalFiles Include="AnalyzerReleases.Shipped.md" />
<AdditionalFiles Include="AnalyzerReleases.Unshipped.md" />
<EmbeddedResource Include="..\Orleans.Analyzers\Resources.resx" Link="Resources.resx" />
</ItemGroup>

<ItemGroup>
<Compile Update="Resources.Designer.cs">
<DesignTime>True</DesignTime>
<AutoGen>True</AutoGen>
<DependentUpon>Resources.resx</DependentUpon>
</Compile>
<EmbeddedResource Update="Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
</EmbeddedResource>
</ItemGroup>

<ItemGroup>
<Content Include="..\Orleans.Analyzers\build\Microsoft.Orleans.Analyzers.props"
Pack="true"
PackagePath="build\Microsoft.Orleans.Analyzers.props"
Visible="true" />
<Content Include="..\Orleans.Analyzers\build\Microsoft.Orleans.Analyzers.targets"
Pack="true"
PackagePath="build\Microsoft.Orleans.Analyzers.targets"
Visible="true" />
<Content Include="..\Orleans.Analyzers\buildTransitive\Microsoft.Orleans.Analyzers.props"
Pack="true"
PackagePath="buildTransitive\Microsoft.Orleans.Analyzers.props"
Visible="true" />
<Content Include="..\Orleans.Analyzers\buildTransitive\Microsoft.Orleans.Analyzers.targets"
Pack="true"
PackagePath="buildTransitive\Microsoft.Orleans.Analyzers.targets"
Visible="true" />
</ItemGroup>

<ItemGroup>
<AssemblyAttribute Remove="Orleans.Metadata.FrameworkPartAttribute" />
</ItemGroup>
</Project>
11 changes: 0 additions & 11 deletions src/Orleans.Analyzers/AnalyzerReleases.Unshipped.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,3 @@ Rule ID | Category | Severity | Notes
--------|----------|----------|-------
ORLEANS0026 | Usage | Error | Invalid invokable base type mapping
ORLEANS0014 | Usage | Warning | ConfigureAwaitAnalyzer, Grain code should not use ConfigureAwait(false) or ConfigureAwait without ContinueOnCapturedContext
ORLEANS0016 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Grain interface not declared in OrleansContracts.txt
ORLEANS0017 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Grain interface version mismatch between code and file
ORLEANS0018 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Grain interface member not declared in OrleansContracts.txt
ORLEANS0019 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Removed interface not marked as *RETIRED*
ORLEANS0020 | Versioning | Info | GrainInterfaceVersionAnalyzer, OrleansContracts.txt file is missing
ORLEANS0021 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Duplicate interface declaration in file
ORLEANS0022 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Grain class not declared in OrleansContracts.txt
ORLEANS0023 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Grain class alias mismatch
ORLEANS0024 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Removed grain class not marked as *RETIRED*
ORLEANS0025 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Duplicate grain class declaration in file
ORLEANS0027 | Versioning | Warning | GrainInterfaceVersionAnalyzer, Removed grain interface member remains in OrleansContracts.txt
Loading