-
Notifications
You must be signed in to change notification settings - Fork 0
01 04 Local Package Development
This guide explains how to set up and use local NuGet packages for development and testing. This workflow is useful for:
- FractalDataWorks Contributors: Testing changes before publishing
- Application Developers: Testing pre-release FractalDataWorks packages
- Framework Developers: Building frameworks that depend on FractalDataWorks packages
The local package development workflow allows you to:
- Pack packages to a local folder instead of publishing to nuget.org
- Automatically use local packages in Debug/Alpha/Beta builds
- Seamlessly switch to published packages for Release builds
- Clean old package versions from local cache
- Customize config names for different workflows
PowerShell:
cd public
.\scripts\setup-local-nuget.ps1Bash/Linux/Mac:
cd public
./scripts/setup-local-nuget.shThis creates:
- Local NuGet folder (default:
C:\development\local-nugetor~/development/local-nuget) - NuGet config file with source mapping (
Fdw.Local.nuget.config)
PowerShell (Current Session):
$env:LocalNugetFolder = "C:\development\local-nuget"PowerShell (Permanent - User Level):
[System.Environment]::SetEnvironmentVariable('LocalNugetFolder', 'C:\development\local-nuget', 'User')
# Restart terminal/IDE for changes to take effectPowerShell Profile (Automatic on startup):
notepad $PROFILE
# Add this line:
$env:LocalNugetFolder = "C:\development\local-nuget"Bash (Current Session):
export LocalNugetFolder="$HOME/development/local-nuget"Bash (Permanent):
echo 'export LocalNugetFolder="$HOME/development/local-nuget"' >> ~/.bashrc
source ~/.bashrcPowerShell:
cd public
.\scripts\pack-local.ps1Bash:
cd public
./scripts/pack-local.shThis will:
- Detect current version (via Nerdbank.GitVersioning)
- Delete old packages with same version from local folder
- Clear matching versions from NuGet cache (
~/.nuget/packages) - Generate/update
Fdw.Local.nuget.configwith source mapping - Pack all FractalDataWorks.* packages to local folder
Projects configured with the local NuGet setup will automatically use local packages when:
- Building in Debug, Alpha, or Beta configuration
-
LocalNugetFolderenvironment variable is set
Release builds always use the standard NuGet config (published packages).
You can customize the NuGet config filename for different workflows (e.g., separate configs for different framework versions):
Setup with custom name:
# PowerShell
.\scripts\setup-local-nuget.ps1 -Path C:\dev\fdw-local -ConfigName MyProject.nuget.config
# Bash
./scripts/setup-local-nuget.sh ~/dev/fdw-local MyProject.nuget.configPack with custom name:
# PowerShell
.\scripts\pack-local.ps1 -ConfigName MyProject.nuget.config
# Bash
./scripts/pack-local.sh MyProject.nuget.configConfigure in your project:
Add to your project's Directory.Build.props:
<PropertyGroup>
<LocalNugetConfigFileName>MyProject.nuget.config</LocalNugetConfigFileName>
</PropertyGroup>You can maintain separate local NuGet folders for different purposes:
# Setup multiple folders
.\scripts\setup-local-nuget.ps1 C:\dev\fdw-stable -ConfigName Stable.nuget.config
.\scripts\setup-local-nuget.ps1 C:\dev\fdw-experimental -ConfigName Experimental.nuget.config
# Switch between them by changing environment variable
$env:LocalNugetFolder = "C:\dev\fdw-stable"
$env:LocalNugetConfigFileName = "Stable.nuget.config"
# Or
$env:LocalNugetFolder = "C:\dev\fdw-experimental"
$env:LocalNugetConfigFileName = "Experimental.nuget.config"PowerShell:
.\scripts\setup-local-nuget.ps1 -Path D:\Projects\NuGetLocal
$env:LocalNugetFolder = "D:\Projects\NuGetLocal"Bash:
./scripts/setup-local-nuget.sh /mnt/data/nuget-local
export LocalNugetFolder="/mnt/data/nuget-local"The generated Fdw.Local.nuget.config uses NuGet's package source mapping feature:
<packageSourceMapping>
<packageSource key="LocalFdw">
<package pattern="FractalDataWorks.*" />
</packageSource>
<packageSource key="nuget.org">
<package pattern="*" />
</packageSource>
</packageSourceMapping>This ensures:
- All
FractalDataWorks.*packages come from your local folder - All other packages come from nuget.org
- No ambiguity about package sources
Projects can use Directory.Build.props to conditionally use the local config.
From samples/ReferenceSolution/Directory.Build.props:21-30:
<!-- Local NuGet Development Configuration -->
<PropertyGroup>
<!-- Default config filename - can be overridden in project files -->
<LocalNugetConfigFileName Condition="'$(LocalNugetConfigFileName)' == ''">Fdw.Local.nuget.config</LocalNugetConfigFileName>
</PropertyGroup>
<!-- Use local NuGet config when LocalNugetFolder is set and not in Release -->
<PropertyGroup Condition="'$(Configuration)' != 'Release' AND '$(LocalNugetFolder)' != ''">
<RestoreConfigFile>$(LocalNugetFolder)\$(LocalNugetConfigFileName)</RestoreConfigFile>
</PropertyGroup>This pattern allows:
- Local Development: Debug/Alpha/Beta builds use local packages
- CI/CD: Release builds use published packages from nuget.org
-
Flexibility: Projects can override
LocalNugetConfigFileNamefor custom workflows
The pack script uses Nerdbank.GitVersioning to detect the current package version based on:
- Git history
- Version.json configuration
- Current branch/commit
It then:
- Finds packages in local folder matching:
FractalDataWorks.*.{version}.nupkg - Deletes them to prevent stale packages
- Scans
~/.nuget/packages/fractaldataworks.*/{version}/and removes cached versions - Packs fresh packages with current version
This ensures you're always testing the latest local changes.
Check environment variable is set:
# PowerShell
echo $env:LocalNugetFolder
# Bash
echo $LocalNugetFolderVerify build configuration:
- Local config only applies to Debug/Alpha/Beta
- Release builds intentionally use nuget.org
Check config file exists:
# PowerShell
Test-Path "$env:LocalNugetFolder\Fdw.Local.nuget.config"
# Bash
ls "$LocalNugetFolder/Fdw.Local.nuget.config"Force restore:
dotnet restore --force
dotnet buildIf you're still getting old versions:
-
Clear all NuGet caches:
dotnet nuget locals all --clear
-
Delete bin/obj folders:
# PowerShell Get-ChildItem -Recurse -Directory -Include bin,obj | Remove-Item -Recurse -Force # Bash find . -type d -name "bin" -o -name "obj" | xargs rm -rf
-
Run pack-local script again:
.\scripts\pack-local.ps1
Visual Studio / Rider:
- Close all instances
- Delete
.vsfolder (Visual Studio) or.ideafolder (Rider) - Clear NuGet cache:
dotnet nuget locals all --clear - Reopen solution
VS Code:
- Reload window (Ctrl+Shift+P → "Reload Window")
- Or restart VS Code
-
Set up once per machine:
.\scripts\setup-local-nuget.ps1
-
Add to PowerShell profile for automatic setup:
$env:LocalNugetFolder = "C:\development\local-nuget"
-
Use pack-local before testing changes:
# Make changes to FractalDataWorks code .\scripts\pack-local.ps1 # Build your test project cd samples/ReferenceSolution dotnet build
-
Test in Debug, release with Release config:
# Test with local packages dotnet build -c Debug # Verify published packages work dotnet build -c Release
-
Create project-specific config:
.\scripts\setup-local-nuget.ps1 ` -Path C:\MyApp\local-packages ` -ConfigName MyApp.nuget.config
-
Add to your project's Directory.Build.props:
<PropertyGroup> <LocalNugetConfigFileName>MyApp.nuget.config</LocalNugetConfigFileName> </PropertyGroup> <PropertyGroup Condition="'$(Configuration)' != 'Release' AND '$(LocalNugetFolder)' != ''"> <RestoreConfigFile>$(LocalNugetFolder)\$(LocalNugetConfigFileName)</RestoreConfigFile> </PropertyGroup>
-
Set environment variable per project:
# In your project's root folder $env:LocalNugetFolder = "C:\MyApp\local-packages"
-
Copy FractalDataWorks packages from their local folder:
# After FractalDataWorks team runs pack-local Copy-Item "C:\development\local-nuget\FractalDataWorks.*.nupkg" ` "C:\MyApp\local-packages\"
Scenario: Testing a contributor's branch
-
Contributor packs their changes:
git checkout feature/new-feature .\scripts\pack-local.ps1
-
Share the package version with team:
# Version is automatically detected and displayed # e.g., "0.25.0-alpha.1234.gabcd123"
-
Team members copy packages:
$contributorPkg = "\\shared\nuget\contributor-feature-branch" Copy-Item "$contributorPkg\FractalDataWorks.*.nupkg" "$env:LocalNugetFolder\"
-
Test with those packages:
dotnet restore --force dotnet build -c Debug
The local package development workflow is designed to be CI/CD safe:
-
Local Config Ignored: Local config files (in
LocalNugetFolder) are never committed to the repository -
Release Builds: CI/CD typically builds in Release configuration, which ignores
LocalNugetFolder -
No Environment Variable: CI/CD agents don't have
LocalNugetFolderset, so they use standardpublic/nuget.config - Predictable Behavior: Published packages always come from nuget.org in CI/CD
To explicitly test with published packages locally:
dotnet build -c Release- Package Management - Central Package Management
- Directory.Build.props - Build configuration
- Quick Start - General getting started guide