Saucery.NuGet
1.0.16
Prefix Reserved
See the version list below for details.
dotnet tool install --global Saucery.NuGet --version 1.0.16
dotnet new tool-manifest
dotnet tool install --local Saucery.NuGet --version 1.0.16
#tool dotnet:?package=Saucery.NuGet&version=1.0.16
nuke :add-package Saucery.NuGet --version 1.0.16
Saucery.NuGet
A .NET global tool that bumps every
PackageReferencein opted-in.csprojfiles — and everyPackageVersionentry inDirectory.Packages.propsfiles — to the next available version on NuGet.org.
Saucery.NuGet supports both traditional project-level NuGet package management and .NET Central Package Management.
Installation
Install globally:
dotnet tool install --global Saucery.NuGet
Or pin it to a repository using a tool manifest, which is recommended for CI:
dotnet new tool-manifest
dotnet tool install Saucery.NuGet
Features
- Scans a solution for projects that explicitly opt in to updates
- Inspects
PackageReferenceentries in opted-in.csprojfiles - Automatically discovers and processes
Directory.Packages.propsfiles under the solution root - Updates
PackageVersionentries used by .NET Central Package Management - Selects the next available NuGet version rather than automatically jumping to the latest version
- Optionally includes prerelease versions
- Optionally increments a project's own
PackageVersionwhen dependency updates are applied - Supports synchronising a project's
PackageVersionwith a dependency - Supports dry-run mode to preview changes without modifying files
- Optionally scans
.csprojfiles on disk that are not registered in the solution - Optionally excludes specific projects from processing
- Supports package exclusions through:
- the command line
- a solution-level configuration file
- per-project declarations
- per-
Directory.Packages.propsdeclarations
Requirements
- .NET 10 SDK
- Network access to the NuGet.org v3 API at
https://api.nuget.org/v3/index.json
Project Package Management
Opting a project in
Only projects that explicitly opt in are scanned and updated.
Add the following property to the .csproj file:
<PropertyGroup>
<SauceryNuGetOptIn>true</SauceryNuGetOptIn>
</PropertyGroup>
Important
- Opt-in is property-based, not package-based.
- You do not add a
PackageReferencetoSaucery.NuGet. Saucery.NuGetis a .NET tool, not a library dependency.
For example:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<SauceryNuGetOptIn>true</SauceryNuGetOptIn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Shouldly" Version="4.2.1" />
</ItemGroup>
</Project>
Saucery.NuGet will inspect the PackageReference, determine the next available version on NuGet.org and update the project if a newer version is available.
Central Package Management
Saucery.NuGet supports NuGet's Central Package Management model using Directory.Packages.props.
If your repository contains one or more Directory.Packages.props files beneath the solution root, Saucery.NuGet automatically discovers and processes them.
For example:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
<PackageVersion Include="Shouldly" Version="4.2.1" />
<PackageVersion Include="TUnit" Version="1.0.0" />
</ItemGroup>
</Project>
Each PackageVersion entry is independently checked against NuGet.org.
Given:
Current: 1.2.0
Available: 1.2.0, 1.3.0, 1.4.0, 2.0.0
Saucery.NuGet selects:
1.3.0
It does not jump directly to 2.0.0.
Automatic discovery
Directory.Packages.props files do not require SauceryNuGetOptIn.
Their presence beneath the solution root is the opt-in mechanism.
Given a repository such as:
MyRepository/
├── MySolution.sln
├── Directory.Packages.props
├── src/
│ ├── Application/
│ │ └── Application.csproj
│ └── Infrastructure/
│ ├── Directory.Packages.props
│ └── Infrastructure.csproj
└── tests/
└── Application.Tests/
└── Application.Tests.csproj
Running:
saucery-nuget --solution MySolution.sln
will discover and process both:
MyRepository/Directory.Packages.props
and:
MyRepository/src/Infrastructure/Directory.Packages.props
bin and obj directories are ignored during discovery.
How Central Package Management differs from .csproj processing
| Behaviour | .csproj |
Directory.Packages.props |
|---|---|---|
| Opt-in required | Yes — SauceryNuGetOptIn |
No — file presence is automatic opt-in |
| Package element updated | PackageReference |
PackageVersion |
--exclude-packages |
Supported | Supported |
| Per-file exclusions | Supported | Supported |
--bump-own-version |
Supported | Supported when central package updates affect opted-in projects |
--sync-with |
Resolves PackageReference or ProjectReference |
Can resolve centrally managed external dependency versions |
Central Package Management exclusions
Packages in a Directory.Packages.props file can be excluded using SauceryNuGetExcludePackage.
For example:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Selenium.WebDriver" Version="4.30.0" />
<PackageVersion Include="Selenium.Support" Version="4.30.0" />
<PackageVersion Include="Shouldly" Version="4.2.1" />
</ItemGroup>
<ItemGroup>
<SauceryNuGetExcludePackage Include="Selenium.WebDriver" />
<SauceryNuGetExcludePackage Include="Selenium.Support" />
</ItemGroup>
</Project>
In this example, Saucery.NuGet will ignore:
Selenium.WebDriver
Selenium.Support
while continuing to process:
Shouldly
The exclusion declarations can appear anywhere in the file.
Usage
Preview changes without writing
Always start with a dry run when introducing Saucery.NuGet to an existing repository:
saucery-nuget --solution MySolution.sln --dry-run
The proposed changes are printed without modifying any files.
Apply dependency updates
saucery-nuget --solution MySolution.sln
This processes:
- opted-in
.csprojfiles; and - automatically discovered
Directory.Packages.propsfiles.
Include prerelease versions
saucery-nuget \
--solution MySolution.sln \
--include-prerelease
Without --include-prerelease, prerelease packages are not considered when determining the next available version.
Bump the project's own PackageVersion
When a dependency changes, Saucery.NuGet can automatically increment the project's own PackageVersion.
saucery-nuget \
--solution MySolution.sln \
--bump-own-version
The default increment is:
patch
For example:
1.4.2 → 1.4.3
To increment the minor version:
saucery-nuget \
--solution MySolution.sln \
--bump-own-version \
--version-segment minor
For example:
1.4.2 → 1.5.0
To increment the major version:
saucery-nuget \
--solution MySolution.sln \
--bump-own-version \
--version-segment major
For example:
1.4.2 → 2.0.0
If no relevant dependencies change, the project's own PackageVersion is left unchanged.
Process specific opted-in projects
When multiple projects are opted in, processing can be limited using --project, or its alias -p.
You can specify:
- the project name without an extension;
- the
.csprojfilename; or - the absolute project path.
Examples:
saucery-nuget \
--solution MySolution.sln \
--project Saucery.Core
saucery-nuget \
--solution MySolution.sln \
--project Saucery.Core.csproj
saucery-nuget \
--solution MySolution.sln \
--project C:\repos\Saucery\Saucery.Core\Saucery.Core.csproj
If no opted-in project matches the supplied value, Saucery.NuGet exits with a non-zero exit code.
Synchronise PackageVersion with a dependency
An opted-in project's PackageVersion can be synchronised with a dependency using --sync-with, or its alias -w.
saucery-nuget \
--solution MySolution.sln \
--project Saucery.TUnit \
--sync-with TUnit
This is useful for integration packages whose own version should track the framework or dependency they integrate with.
For example:
TUnit 1.8.0
Saucery.TUnit 1.8.0
--sync-with supports:
- a
PackageReferencein the selected project; - a centrally managed
PackageVersion; - a
ProjectReferenceto another project.
Behaviour
Saucery.NuGet:
- Uses the updated dependency version if the dependency changed during the current run.
- Falls back to the dependency's existing version when no update occurred.
- Performs no synchronisation if the requested dependency cannot be resolved.
- Gives
--sync-withprecedence over--bump-own-version. - Reports the proposed synchronisation without writing files when
--dry-runis used.
--sync-with must be used with --project.
Examples
Synchronise with a NuGet dependency:
saucery-nuget \
--solution MySolution.sln \
--project Saucery.TUnit \
--sync-with TUnit
Synchronise with another project:
saucery-nuget \
--solution MySolution.sln \
--project Saucery \
--sync-with Saucery.Core
Preview the change:
saucery-nuget \
--solution MySolution.sln \
--project Saucery.TUnit \
--sync-with TUnit \
--dry-run
Scan unregistered projects
By default, project discovery is based on projects registered in the solution.
To include .csproj files that exist beneath the solution root but are not registered in the solution:
saucery-nuget \
--solution MySolution.sln \
--scan-unregistered
Opt-in rules still apply.
An unregistered project is processed only when it contains:
<SauceryNuGetOptIn>true</SauceryNuGetOptIn>
This option affects .csproj discovery.
Directory.Packages.props files are already discovered recursively beneath the solution root.
Exclude projects from processing
One or more projects can be skipped entirely using --exclude-projects.
saucery-nuget \
--solution MySolution.sln \
--exclude-projects Saucery.Core
Multiple projects can be specified:
saucery-nuget \
--solution MySolution.sln \
--exclude-projects Saucery.Core Saucery.XUnit
You can specify:
- project name without an extension;
.csprojfilename; or- absolute project path.
Excluded projects are removed from the opted-in project set before processing begins.
Exclude packages from updates
There are three ways to exclude packages.
The effective exclusion list is the union of all applicable exclusion sources.
Matching is case-insensitive and duplicate values are ignored.
1. Command-line exclusions
For one-off exclusions:
saucery-nuget \
--solution MySolution.sln \
--exclude-packages Selenium.WebDriver Selenium.Support
Command-line exclusions also apply when processing Directory.Packages.props.
2. Solution-level configuration
Create:
saucery-nuget.json
in the same directory as the solution file.
For example:
{
"excludePackages": [
"Selenium.WebDriver",
"Selenium.Support"
]
}
The file is loaded automatically.
No command-line argument is required.
If the file does not exist, processing continues normally.
If the file contains invalid JSON, Saucery.NuGet prints a warning and ignores the global configuration file.
These exclusions apply to both:
.csprojprocessing;Directory.Packages.propsprocessing.
3. Per-project or per-file exclusions
In a .csproj
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<SauceryNuGetOptIn>true</SauceryNuGetOptIn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Selenium.WebDriver" Version="4.30.0" />
<PackageReference Include="Selenium.Support" Version="4.30.0" />
<PackageReference Include="Shouldly" Version="4.2.1" />
</ItemGroup>
<ItemGroup>
<SauceryNuGetExcludePackage Include="Selenium.WebDriver" />
<SauceryNuGetExcludePackage Include="Selenium.Support" />
</ItemGroup>
</Project>
These exclusions affect only that project.
In Directory.Packages.props
<Project>
<ItemGroup>
<PackageVersion Include="Selenium.WebDriver" Version="4.30.0" />
<PackageVersion Include="Selenium.Support" Version="4.30.0" />
<PackageVersion Include="Shouldly" Version="4.2.1" />
</ItemGroup>
<ItemGroup>
<SauceryNuGetExcludePackage Include="Selenium.WebDriver" />
<SauceryNuGetExcludePackage Include="Selenium.Support" />
</ItemGroup>
</Project>
These exclusions affect only that Directory.Packages.props file.
All options
| Option | Alias | Description |
|---|---|---|
--solution <path> |
-s |
Path to the solution file to process. Required. |
--dry-run |
Print proposed changes without writing files. | |
--include-prerelease |
Consider prerelease versions as update candidates. | |
--bump-own-version |
Increment the project's own PackageVersion when dependencies change. |
|
--version-segment <segment> |
patch by default, or minor or major. |
|
--project <project> |
-p |
Limit project processing to a specific opted-in project. |
--sync-with <dependency> |
-w |
Synchronise the selected project's PackageVersion with a dependency. |
--scan-unregistered |
Include .csproj files not registered in the solution. |
|
--exclude-packages <packages> |
Exclude one or more packages from updates. | |
--exclude-projects <projects> |
Exclude one or more projects from project processing. |
What "next version" means
Saucery.NuGet deliberately updates dependencies incrementally.
Given:
Current: 1.2.0
Available:
1.2.0
1.3.0
1.4.0
2.0.0
Saucery.NuGet selects:
1.3.0
It always selects the smallest available version that is strictly greater than the current version.
The next run may then select:
1.4.0
and a later run:
2.0.0
This allows each dependency upgrade to be independently validated by your build and test pipeline.
Example repository using Central Package Management
Given:
MyRepository/
├── MySolution.sln
├── Directory.Packages.props
├── saucery-nuget.json
├── src/
│ ├── MyLibrary/
│ │ └── MyLibrary.csproj
│ └── MyApplication/
│ └── MyApplication.csproj
└── tests/
└── MyLibrary.Tests/
└── MyLibrary.Tests.csproj
Directory.Packages.props:
<Project>
<PropertyGroup>
<ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally>
</PropertyGroup>
<ItemGroup>
<PackageVersion Include="Microsoft.Extensions.Hosting" Version="10.0.0" />
<PackageVersion Include="Shouldly" Version="4.2.1" />
<PackageVersion Include="TUnit" Version="1.0.0" />
</ItemGroup>
</Project>
MyLibrary.csproj:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFramework>net10.0</TargetFramework>
<PackageVersion>1.0.0</PackageVersion>
<SauceryNuGetOptIn>true</SauceryNuGetOptIn>
</PropertyGroup>
<ItemGroup>
<PackageReference Include="Microsoft.Extensions.Hosting" />
</ItemGroup>
</Project>
Run:
saucery-nuget \
--solution MySolution.sln \
--dry-run
Saucery.NuGet will:
- Discover opted-in projects.
- Discover
Directory.Packages.props. - Check each centrally managed
PackageVersion. - Apply configured package exclusions.
- Determine the next available version for each dependency.
- Report the proposed changes.
Remove --dry-run to write the updates.
CI / Pipeline integration
Typical GitHub Actions usage:
- name: Install Saucery.NuGet
run: dotnet tool install --global Saucery.NuGet
- name: Add .NET tools to PATH
run: echo "$HOME/.dotnet/tools" >> $GITHUB_PATH
- name: Run Saucery.NuGet
run: saucery-nuget --solution MySolution.sln
When Central Package Management is used, no additional command-line option is required.
Directory.Packages.props files beneath the solution root are discovered automatically.
For a real-world example, see the Saucery dogfooding pipeline:
How it works
.csproj pipeline
Parses the solution to discover
.csprojfiles.Optionally discovers unregistered
.csprojfiles when--scan-unregisteredis used.Filters projects to those containing:
<SauceryNuGetOptIn>true</SauceryNuGetOptIn>Removes projects listed in
--exclude-projects.Loads
saucery-nuget.jsonfrom the solution directory, when present.Merges solution-level exclusions with
--exclude-packages.Reads project-specific
SauceryNuGetExcludePackageentries.Finds
PackageReferenceentries.Skips packages in the effective exclusion list.
Resolves the next available version using
NuGet.Versioning.Updates the
.csprojwhile preserving its encoding and BOM.Optionally updates the project's own
PackageVersion.
Directory.Packages.props pipeline
- Recursively discovers every
Directory.Packages.propsfile beneath the solution root. - Skips
binandobjdirectories. - Loads global exclusions from:
--exclude-packages;saucery-nuget.json.
- Reads file-specific
SauceryNuGetExcludePackageentries. - Merges the exclusion sources into the effective exclusion list for the file.
- Finds every
PackageVersionentry. - Skips packages in the effective exclusion list.
- Resolves the next available version using
NuGet.Versioning. - Updates the
Directory.Packages.propsfile while preserving its encoding and BOM.
No explicit opt-in property is required for Directory.Packages.props.
Contributing
Contributions are welcome.
- Fork the repository.
- Create a branch.
- Follow the existing coding and testing patterns.
- Submit a pull request.
Source:
https://github.com/Sauceforge/Saucery
License
Copyright © 2024 Andrew Gray.
All rights reserved.
| Product | Versions Compatible and additional computed target framework versions. |
|---|---|
| .NET | net10.0 is compatible. net10.0-android was computed. net10.0-browser was computed. net10.0-ios was computed. net10.0-maccatalyst was computed. net10.0-macos was computed. net10.0-tvos was computed. net10.0-windows was computed. |
This package has no dependencies.
| Version | Downloads | Last Updated |
|---|---|---|
| 1.0.18 | 214 | 8/11/2026 |
| 1.0.17 | 170 | 7/26/2026 |
| 1.0.16 | 112 | 7/24/2026 |
| 1.0.15 | 116 | 7/21/2026 |
| 1.0.14 | 113 | 7/18/2026 |
| 1.0.13 | 99 | 7/18/2026 |
| 1.0.12 | 93 | 7/18/2026 |
| 1.0.11 | 138 | 7/12/2026 |
| 1.0.10 | 556 | 5/14/2026 |
| 1.0.9 | 150 | 5/9/2026 |
| 1.0.8 | 202 | 4/22/2026 |
| 1.0.7 | 128 | 4/22/2026 |
| 1.0.6 | 130 | 4/21/2026 |
| 1.0.5 | 142 | 4/20/2026 |
| 1.0.4 | 138 | 4/19/2026 |
| 1.0.3 | 134 | 4/19/2026 |
| 1.0.2 | 132 | 4/19/2026 |
| 1.0.1 | 153 | 4/18/2026 |
| 1.0.0 | 124 | 4/18/2026 |