NuGroom

Automated Updates

NuGroom can automatically create feature branches and pull requests to update outdated package references across your Azure DevOps repositories.


How It Works

  1. Scan — repositories are scanned and NuGet metadata is resolved (as usual)
  2. Plan — the tool compares used versions against latest available and builds an update plan within the configured scope
  3. Preview (dry-run) — the plan is displayed showing what branches and PRs would be created
  4. Apply — feature branches are created from the source branch, updated project (.csproj, .vbproj, .fsproj) files are pushed, and PRs are opened against the target branch

Projects within each repository are processed in order of dependency count (fewest dependencies first).


Update Scope

The scope controls the maximum version change that will be applied. Scopes are cumulative:

Scope Allowed Updates Example
Patch Patch only 1.2.31.2.5
Minor Minor and patch 1.2.31.4.0
Major Any version 1.2.32.0.0

Branch Resolution


Dry-Run Mode

Dry-run is enabled by default in configuration ("DryRun": true). Use --dry-run on the CLI or set "DryRun": false / --update-references to apply changes.

In dry-run mode the tool shows:


Pinned Packages

Pin packages to prevent automatic updates:

{
  "Update": {
    "PinnedPackages": [
      {
        "PackageName": "Newtonsoft.Json",
        "Version": "13.0.1",
        "Reason": "Breaking changes in newer versions"
      },
      {
        "PackageName": "Serilog",
        "Version": null,
        "Reason": "Keep current version until logging migration is complete"
      }
    ]
  }
}

Project Version Increment

When updating package references, the tool can automatically increment version properties (<Version>, <AssemblyVersion>, <FileVersion>) in each project file that receives updates. This ensures the project version reflects that its dependencies have changed.

CLI flags:

The optional [scope] parameter controls which component is bumped:

Scope Example
Patch (default) 1.2.31.2.4
Minor 1.2.31.3.0
Major 1.2.32.0.0

Both 3-part (Major.Minor.Patch) and 4-part (Major.Minor.Build.Revision) version formats are supported. Lower components are reset to zero when a higher component is incremented.

Config file:

{
  "Update": {
    "VersionIncrement": {
      "IncrementVersion": true,
      "IncrementAssemblyVersion": true,
      "IncrementFileVersion": true,
      "Scope": "Patch"
    }
  }
}

Version properties that do not exist in a project file are silently skipped. The increment is only applied to .csproj / .vbproj / .fsproj project files — Directory.Packages.props and packages.config files are not affected.


Minimum Age Filter

Use --minage <days> or "MinAgeDays": 30 in the config file to skip package versions that were published too recently. When set, only versions whose publish date is at least the specified number of days ago are considered as the latest available version.

This is useful to avoid adopting brand-new releases that might contain undiscovered bugs:

# Only consider versions published at least 30 days ago
nugroom --config settings.json --dry-run --minage 30
{
  "MinAgeDays": 30
}

The filter applies to all resolution — scans, updates, and sync (when no explicit target version is specified). If no version meets the age threshold, the package is reported as not found on the feed.

Security Bypass

When the minimum age filter is active, security updates bypass the age threshold. If the age-filtered latest version of a package has known NuGet vulnerabilities, the tool automatically falls back to the newest non-vulnerable version — even if that version was published more recently than the minimum age cutoff.

This matches the behavior of Renovate’s minimumReleaseAge, which allows security patches through regardless of age constraints. The bypass ensures that known-vulnerable versions are never selected as the update target when a safer alternative exists.


Source Packages Only

Use --source-packages-only


PR Reviewers

Add required and optional reviewers to created pull requests:

{
  "Update": {
    "RequiredReviewers": ["lead@company.com", "security@company.com"],
    "OptionalReviewers": ["teammate@company.com"]
  }
}

Or via CLI (both are repeatable):

--required-reviewer "lead@company.com" --optional-reviewer "teammate@company.com"

Package Sync

The --sync option lets you force a specific package to an exact version across all repositories in a single operation. Unlike --update-references which updates many packages within a scope, --sync targets one package and supports both upgrades and downgrades.

Usage

# Sync to latest available version
NuGroom --config settings.json --sync Newtonsoft.Json

# Sync to a specific version (upgrade or downgrade)
NuGroom --config settings.json --sync Newtonsoft.Json 13.0.1

# Preview what would change
NuGroom --config settings.json --sync Newtonsoft.Json 13.0.1 --dry-run

How It Works

  1. If no version is provided, the latest stable version is resolved from configured feeds
  2. All repositories are scanned for project files (.csproj, .vbproj, .fsproj) referencing the specified package
  3. Projects already at the target version are skipped
  4. For each affected repository, a feature branch is created, changes are pushed, and a PR is opened

Behavior


See also: CLI Reference · Configuration · Renovate Compatibility