Incrementalist.Cmd 1.0.0

dotnet tool install --global Incrementalist.Cmd --version 1.0.0
                    
This package contains a .NET tool you can call from the shell/command line.
dotnet new tool-manifest
                    
if you are setting up this repo
dotnet tool install --local Incrementalist.Cmd --version 1.0.0
                    
This package contains a .NET tool you can call from the shell/command line.
#tool dotnet:?package=Incrementalist.Cmd&version=1.0.0
                    
nuke :add-package Incrementalist.Cmd --version 1.0.0
                    

🔄 Incrementalist

<img src="https://raw.githubusercontent.com/petabridge/Incrementalist/refs/heads/dev/docs/incrementalist-logo-dark.svg" width="90" alt="Incrementalist Logo" />

Incrementalist is a .NET tool that leverages libgit2sharp and Roslyn to compute incremental build steps for large .NET solutions. It helps optimize your CI/CD pipeline by building and testing only the projects affected by your changes.

🎯 When to Use Incrementalist

Incrementalist is particularly valuable for:

  • 🏗️ Large Solutions: If your solution contains dozens or hundreds of projects, Incrementalist can significantly reduce build times by only building what's necessary.
  • 📦 Monorepos: When managing multiple applications or services in a single repository, Incrementalist helps identify and build only the affected components.
  • 🌐 Microservice Architectures: In repositories containing multiple microservices, build only the services impacted by your changes.
  • 🔗 Complex Dependencies: When projects have intricate dependencies, Incrementalist automatically determines the complete build graph.
  • CI/CD Optimization: Reduce CI/CD pipeline execution time by skipping unnecessary builds and tests.

⚙️ Requirements

  • .NET 8.0 SDK or later
  • Git installed and available in the system PATH

📥 Installation

Incrementalist is available in two forms:

  1. Incrementalist Library - a .NET 8 library for programmatic use
  2. Incrementalist.Cmd - a dotnet tool for command-line use ( recommended)

Install the command-line tool globally:

dotnet tool install --global Incrementalist.Cmd

Or install locally in your project:

# From your repository root
dotnet new tool-manifest # if you haven't already created a .config/dotnet-tools.json
dotnet tool install Incrementalist.Cmd

Running as a Global Tool

When installed globally, run commands directly using the incrementalist command with one of the available verbs:

# Get list of affected projects
incrementalist run --dry -b dev -f ./affected-projects.txt

# List affected folders
incrementalist list-affected-folders -b dev -f ./affected-folders.txt

# Run tests for affected projects
incrementalist run -b dev -- test -c Release

# Run tests for affected projects those matching a glob
incrementalist run -b dev --target-glob "src/*.Tests.csproj" -- test -c Release

Running as a Local Tool

When using Incrementalist as a local tool, you need to use dotnet tool run with an additional -- before the Incrementalist commands:

# Get list of affected projects
dotnet incrementalist -- -b dev -f ./affected-projects.txt

# List affected folders
dotnet incrementalist -- list-affected-folders -b dev -f ./affected-folders.txt

# Build affected projects
dotnet incrementalist -- run -b dev -- build -c Release --nologo

# Run tests with coverage
dotnet incrementalist -- run -b dev -- test -c Release --no-build --logger:trx --collect:"XPlat Code Coverage" --results-directory ./testresults

# Run in parallel mode
dotnet incrementalist -- run -b dev --parallel -- build -c Release --nologo

# Save affected projects AND run commands
dotnet incrementalist -- -b dev -f ./affected-projects.txt run -- build -c Release --nologo

![NOTE] Don't call dotnet tool run incrementalist - this runs into some very annoying parse issues: https://github.com/petabridge/Incrementalist/issues/378 . Just call dotnet incrementalist instead.

📄 Configuration Files

Incrementalist supports JSON configuration files to store commonly used settings. This eliminates the need to specify the same command-line arguments repeatedly.

# Use default configuration file (.incrementalist/incrementalist.json)
incrementalist run -- build

# Specify a custom configuration file
incrementalist -c my-config.json run -- build

# Create configuration file with current settings
incrementalist create-config -b dev --verbose --parallel

Create a configuration file in your repository:

{
  "gitBranch": "master",
  "solutionFilePath": "src/MySolution.sln",
  "verbose": true,
  "runInParallel": true
}

Command-line arguments take precedence over configuration file settings. See Configuration Documentation for complete details.

🚀 Quick Start Examples

# Get list of affected projects and save to file
incrementalist run --dry -b dev -f ./affected-projects.txt

# Specify solution explicitly
incrementalist run --dry -s ./src/MySolution.sln -b dev -f ./affected-projects.txt

# Get list of affected folders
incrementalist list-affected-folders -b dev -f ./affected-folders.txt

# Build only affected projects
incrementalist run -b dev -- build -c Release --nologo

# Run tests for affected projects
incrementalist run -b dev -- test -c Release --no-build --nologo

# Only include test projects in the final list
incrementalist run -b dev --target-glob "**/*.Tests.csproj" -f ./affected-test-projects.txt

# Exclude test projects from the final list
incrementalist run -b dev --skip-glob "**/*.Tests.csproj" -f ./affected-non-test-projects.txt

# Run tests with code coverage
incrementalist run -b dev -- test -c Release --no-build --nologo /p:CollectCoverage=true /p:CoverletOutputFormat=cobertura /p:CoverletOutput=./coverage/

# Save affected projects AND run commands
incrementalist run -b dev -f ./affected-projects.txt -- build -c Release --nologo

# Create configuration file with current settings (default path: .incrementalist/incrementalist.json)
incrementalist create-config -b dev --verbose --parallel

# Create configuration file with current settings and custom file name
incrementalist create-config -b dev --verbose --parallel -c ./my-incrementalist-config.json

# Run incrementalist with a custom configuration file
incrementalist run -c ./my-incrementalist-config.json -- build -c Release

# Perform a dry run without executing commands
incrementalist run -b dev --dry -- build -c Release --nologo

📄 Output Files

Incrementalist can generate two types of output files using -f, --file:

  1. Project Lists (with the run verb):

    D:\src\Project1\Project1.csproj,D:\src\Project2\Project2.csproj
    
  2. Folder Lists (with the list-affected-folders verb):

    D:\src\Project1,D:\src\Project2\SubFolder
    

These files can be used in build scripts, CI/CD pipelines, or other automation tools.

🛠️ Command-Line Options

Incrementalist now uses a verb-based command structure. Common options are available across all verbs, with some verb-specific options.

Common Options (available for all verbs)

  -s, --sln             Optional. Solution file to analyze. Uses first .sln in
                        current directory if not specified.

  -f, --file            Optional. Write output to the specified file.

  -b, --branch          Optional. Git branch to compare against
                        (e.g., 'dev' or 'master').

  -d, --dir             Optional. Working directory. Defaults to current directory.

  --verbose             Optional. (Default: false) Enable debug logging.

  -t, --timeout         Optional. (Default: 2) Solution load timeout in minutes.

  -c, --config          Optional. Path to the configuration file. Defaults to 
                        .incrementalist/incrementalist.json in the current directory.

  --continue-on-error   Optional. (Default: true) Continue executing commands even
                        if some fail.

  --parallel            Optional. (Default: false) Execute commands in parallel.

  --fail-on-no-projects Optional. (Default: false) Fail if no projects are affected.
                        
  --skip-glob           Optional. Glob pattern to exclude projects from the final
                        list. Applied after analyzing dependencies. Can be used
                        multiple times.
                        
  --target-glob         Optional. Glob pattern to include only matching projects in
                        the final list. Applied after analyzing dependencies. Can
                        be used multiple times.

  --help                Display help screen.

  --version             Display version information.

Available Verbs

create-config

Creates a new configuration file with current options.

incrementalist create-config [options]
list-affected-folders

List affected folders instead of .NET projects.

incrementalist list-affected-folders [options]
run

Run a command against affected projects. Use the --dry option to test without executing.

incrementalist run [options] -- [dotnet command and arguments]

Additional options for run:

  --dry                 Optional. (Default: false) Performs a dry run without
                        executing any commands. Useful for testing.

⚡ Running Commands

Execute dotnet CLI commands against affected projects using the run verb:

# Build affected projects
incrementalist run -b dev -- build -c Release --nologo

# Run tests
incrementalist run -b dev -- test -c Release --no-build --nologo

# Run in parallel
incrementalist run -b dev --parallel -- build -c Release --nologo

# Stop on first error
incrementalist run -b dev --continue-on-error=false -- build -c Release --nologo

# Perform a dry run (shows commands without executing them)
incrementalist run -b dev --dry -- build -c Release --nologo

🌐 Filtering Projects with Glob Patterns

After Incrementalist determines the initial set of affected projects based on Git changes and project dependencies, you can further refine this list using glob patterns.

  • --target-glob "<pattern>": Only includes projects whose paths match the specified glob pattern(s). If multiple patterns are provided, a project matching any of them will be included. This filter is applied first.
  • --skip-glob "<pattern>": Excludes projects whose paths match the specified glob pattern(s) from the list remaining after any --target-glob filters have been applied. If multiple patterns are provided, a project matching any of them will be excluded.

Both options can be specified multiple times on the command line.

Example: Find all affected projects, but only run the build command on non-test projects within the src directory.

incrementalist run -b dev --target-glob "src/**/*.csproj" --skip-glob "**/*.Tests.csproj" -- build -c Release --nologo

📚 Documentation

📜 License

Licensed under the Apache License, Version 2.0: http://www.apache.org/licenses/LICENSE-2.0

Copyright 2015-2025 Petabridge

Product Compatible and additional computed target framework versions.
.NET net8.0 is compatible.  net8.0-android was computed.  net8.0-browser was computed.  net8.0-ios was computed.  net8.0-maccatalyst was computed.  net8.0-macos was computed.  net8.0-tvos was computed.  net8.0-windows was computed.  net9.0 was computed.  net9.0-android was computed.  net9.0-browser was computed.  net9.0-ios was computed.  net9.0-maccatalyst was computed.  net9.0-macos was computed.  net9.0-tvos was computed.  net9.0-windows was computed. 
Compatible target framework(s)
Included target framework(s) (in package)
Learn more about Target Frameworks and .NET Standard.

This package has no dependencies.

Version Downloads Last updated
1.0.0 2,022 4/18/2025
1.0.0-rc5 774 4/17/2025
1.0.0-rc4 196 4/17/2025
1.0.0-rc3 198 4/16/2025
1.0.0-rc2 363 4/14/2025
1.0.0-rc1 273 4/13/2025
1.0.0-beta4 792 2/25/2025
1.0.0-beta3 152 2/25/2025
1.0.0-beta2 149 2/24/2025
1.0.0-beta1 153 2/21/2025
0.9.0 51,320 11/22/2023
0.8.0 34,556 11/24/2022
0.7.0 12,649 5/24/2022
0.6.0 30,028 11/10/2021
0.5.0 1,016 6/16/2021
0.4.0 25,104 12/23/2020
0.3.0 819 9/26/2020
0.2.2 38,345 2/14/2020
0.2.1 6,310 11/18/2019
0.2.0 2,068 10/29/2019
0.1.7 3,295 9/9/2019
0.1.6 805 8/30/2019
0.1.5 748 8/30/2019
0.1.4 3,793 5/17/2019
0.1.3 849 5/15/2019
0.1.2 759 5/8/2019
0.1.1 734 5/8/2019
0.1.0 812 5/3/2019

Incrementalist v1.0.0 is here! This release marks a significant step forward, introducing powerful new features focused on usability, performance, and integration with modern .NET development workflows.

**Major New Features:**

*   **Built-in `dotnet` Command Execution:** Directly execute `dotnet` CLI commands on projects affected by changes since a specified base revision (e.g., `main` or `dev`). Use the `-r` or `--run` flag followed by your standard `dotnet` command.

   ```shell
   # Build only affected projects compared to the 'dev' branch
   incrementalist -b dev -r -- build -c Release --nologo

   # Run tests for affected projects in parallel
   incrementalist -b dev -r --parallel -- test -c Release --no-build --nologo
   ```

*   **File-based Configuration (`.incrementalist.yml`):** Configure Incrementalist using a YAML file instead of command-line arguments. Store common settings, project filters, and default branches.

   ```yaml
   # .incrementalist.yml
   base-branch: dev
   skip-glob: "**/obj/**,**/bin/**"
   target-glob: "src/**/*.csproj"
   log-level: Information
   run: build -c Release
   parallel: true
   ```

   Load the configuration: `incrementalist -c .incrementalist.yml`

*   **File Globbing for Commands (`--glob`, `--skip-glob`, `--target-glob`):** Precisely target or exclude projects for command execution using glob patterns. This allows for fine-grained control over which affected projects specific commands are run against.

   ```shell
   # Run tests only on affected *.Tests.csproj projects
   incrementalist -b dev -r --target-glob "**/*.Tests.csproj" -- test
   
   # Build all affected projects EXCEPT those in the 'samples' directory
   incrementalist -b dev -r --skip-glob "**/samples/**/*.csproj" -- build
   ```

*   **Command-Line Verbs:** Reorganized command-line arguments using verbs for better structure and clarity (Breaking Change introduced in `1.0.0-rc4`). See documentation for updated commands.

**Improvements:**

*   Improved detection of changes in shared MSBuild files like `Directory.Build.props` and imported `.props`/`.targets` files.
*   Enhanced project dependency analysis for more accurate calculation of affected projects.
*   Improved logging system with configurable levels and better context.
*   More robust quoting for arguments passed to `dotnet` commands.
*   Added support for detecting unstaged file changes in Git.
*   Added `IProgress<ProjectLoadProgress>` support for MSBuild loading.
*   Updated documentation with examples for configuration files and globbing.
*   Upgraded dependencies (Roslyn, NuGet, Microsoft.Extensions.Logging, etc.) to latest versions.

**Bug Fixes:**

*   Resolved issues with configuration-based `SkipGlob` and `TargetGlob` being overwritten by unspecified CLI arguments ([#402](https://github.com/petabridge/Incrementalist/issues/402)).
*   Fixed globbing pattern application when a full solution build is required ([#395](https://github.com/petabridge/Incrementalist/issues/395)).
*   Corrected dependency graph calculation errors ([#389](https://github.com/petabridge/Incrementalist/issues/389)).
*   Fixed globbing with absolute paths ([#386](https://github.com/petabridge/Incrementalist/issues/386)).
*   Resolved issues with command-line option parsing, including duplicate definitions and `--create-config` behavior ([#379](https://github.com/petabridge/Incrementalist/pull/379), [#382](https://github.com/petabridge/Incrementalist/pull/382)).
*   Fixed various issues related to command execution, parallelism, and error handling (`--continue-on-error`, `--fail-on-no-projects`).
*   Fixed NuGet packaging metadata ([#337](https://github.com/petabridge/Incrementalist/pull/337)).
*   Corrected logging of `null` values during default config loading ([#401](https://github.com/petabridge/Incrementalist/pull/401)).