Skip to content
v7 is in preview. Install it with dotnet tool install dotnet-affected --prerelease, and see what changed since v6.

SDK reference

The target that computes the affected projects. It is registered as an initial target, so it runs before every other target in the build. It replaces all ProjectReference items with the changed and affected projects.

Hook BeforeTargets="DotnetAffectedCheck" to set inputs, AfterTargets="DotnetAffectedCheck" to post-process the result.

Name Kind Type Description
UsingDotnetAffectedTasks Property bool Whether DotnetAffectedCheck runs. Empty or true runs it; any other value disables the SDK. Default: true
DotnetAffectedRoot Property string Repository root, where .git lives. Default: $(MSBuildStartupDirectory)
DotnetAffectedFromRef Property string Branch or commit to compare the working tree against. Default: empty, meaning HEAD
DotnetAffectedUncommitted Property string What the working tree contributes on top of the commits since FromRef: All, Staged or None. Default: All
DotnetAffectedToRef Property string Deprecated, removed in v8. Only accepted when it names the commit the working tree is checked out at
DotnetAffectedHonourGitIgnore Property bool Whether discovery skips paths git ignores. Set to false to search everything. Default: true
DotnetAffectedAssumeChanges Item item list Projects to treat as changed instead of using Git. Globs expand to paths; bare values match by project name
AffectedFilterClass Item item list Property templates read from each affected project — see Filtering
Name Kind Type Description
DotnetAffectedProjectCount Property int Number of changed plus affected projects
ProjectReference Item item list The changed and affected projects; replaces whatever was there before
AffectedFilterInstance Item item list One item per project per filter class, carrying the requested property values

ProjectReference is an ordinary item list once DotnetAffectedCheck has replaced it, so a target running after the check can add to it or take from it:

<Project Sdk="DotnetAffected.Tasks;Microsoft.Build.Traversal">
<Target Name="_AdjustAffected" AfterTargets="DotnetAffectedCheck">
<Message Text="Found $(DotnetAffectedProjectCount) affected projects" Importance="high" />
<ItemGroup>
<!-- Never build these, however they were reached -->
<ProjectReference Remove="$(MSBuildThisFileDirectory)src/DevTools/**/*.csproj" />
<!-- Always build these, whether or not anything touched them -->
<ProjectReference Include="$(MSBuildThisFileDirectory)src/Core/**/*.csproj" />
</ItemGroup>
</Target>
</Project>

Adding projects this way overrides the analysis rather than informing it: an included project is built even when nothing changed, and its dependents are not pulled in with it. To have a project’s changes propagate through the graph, use --assume-changes’s SDK equivalent, DotnetAffectedAssumeChanges, instead.

Property Description
CustomBeforeAffectedProps MSBuild projects imported before the SDK’s .props
CustomAfterAffectedProps MSBuild projects imported after the SDK’s .props
CustomBeforeAffectedTargets MSBuild projects imported before the SDK’s .targets
CustomAfterAffectedTargets MSBuild projects imported after the SDK’s .targets

These keep ad-hoc targets out of your .props file:

<Project Sdk="DotnetAffected.Tasks;Microsoft.Build.Traversal">
<PropertyGroup>
<CustomAfterAffectedTargets>$(CustomAfterAffectedTargets);$(MSBuildThisFileDirectory)ci.targets</CustomAfterAffectedTargets>
</PropertyGroup>
</Project>
<!-- ci.targets -->
<Project>
<Target Name="_DotnetAffectedCheck" AfterTargets="DotnetAffectedCheck">
<ItemGroup>
<ProjectReference Remove="$(MSBuildThisFileDirectory)src/DevTools/**/*.csproj" />
</ItemGroup>
</Target>
</Project>

All of Microsoft.Build.Traversal’s extensibility options apply as well.

If you cannot use the Sdk attribute — for example because you need the package resolved through Central Package Management — import the SDK files by path instead:

<Project Sdk="Microsoft.Build.Traversal/4.1.82">
<ItemGroup>
<!-- With Central Package Management -->
<PackageReference Include="DotnetAffected.Tasks" GeneratePathProperty="true" />
<PackageVersion Include="DotnetAffected.Tasks" Version="7.0.0" />
<!-- Without it -->
<!-- <PackageReference Include="DotnetAffected.Tasks" Version="7.0.0" GeneratePathProperty="true" /> -->
</ItemGroup>
<Import Project="$(PKGDotnetAffected_Tasks)/Sdk/Sdk.props" />
<Import Project="$(PKGDotnetAffected_Tasks)/Sdk/Sdk.targets" />
</Project>