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

GitHub Action

leonardochaia/dotnet-affected-action installs dotnet-affected, runs it, and exposes the result as a step output so later steps can be skipped.

- uses: actions/checkout@v4
with:
fetch-depth: 0
- uses: leonardochaia/dotnet-affected-action@v7
id: affected
with:
from: ${{ steps.base.outputs.sha }}
- name: Test
if: success() && steps.affected.outputs.affected != ''
run: dotnet test affected.proj

fetch-depth: 0 is not optional. The default shallow clone has neither the baseline nor a merge base, and the comparison fails.

The action major tracks the dotnet-affected major it drives. Use @v7 with dotnet-affected 7.x — it installs the latest 7.x by default and refuses to run against a newer major.

@v1 targets 6.x and is deprecated: v1.5 is its last release, and every run logs a warning naming the version to move to. It is a warning, not an error, so it cannot fail a build.

The reason for the rule: @v1 used to install whatever dotnet-affected was newest on NuGet, so it would pick up a major it was never written against the moment one was published — arguments and exit codes included. Tying the action major to the tool major is what stops that.

  1. Installs the tool globally with dotnet tool install -g dotnet-affected --version <toolVersion>, and puts ~/.dotnet/tools on the path. A tool that is already installed is tolerated rather than treated as a failure.
  2. Reads back dotnet affected --version and stops if the major is newer than the one the action targets. A version it cannot parse is let through — this check must never be the thing that breaks a run that would otherwise work.
  3. Runs dotnet affected with the flags built from the inputs, always passing --repository-path so the output lands where the action reads it back from, and writing affected.proj and affected.txt there.
  4. Sets the affected output to the contents of affected.txt.

The reference has the exact mapping from inputs to CLI flags.

When nothing changed and nothing is affected, the tool exits with 166, which the action treats as success with an empty affected output — the job stays green and nothing is built.

Guard the steps that would otherwise fail on a missing affected.proj:

- name: Restore
if: success() && steps.affected.outputs.affected != ''
run: dotnet restore affected.proj

Any other non-zero exit fails the step, with the tool’s stderr in the log.

See Examples for complete pull-request and branch-build workflows.