In large-scale, long-lived enterprise applications, upgrading core framework baselines and runtime libraries carries inherent risk: individual sub-projects bumping dependencies in isolation, Roslyn incremental source generators serving stale disk caches resulting in missing generated symbols, and database schema drifts causing runtime outages.
BitzOrcas.Modern enforces a modern upgrade paradigm based on “Centralized Governance, Stateless Code Generation, and Automated Quality Gates”:
- Central Package Management (CPM): All NuGet package versions across the solution are strictly declared within the root
Directory.Packages.props. HardcodingVersionattributes inside individual.csprojfiles is prohibited; - Deterministic Generator Cache Invalidation: Following framework updates, local
bin/,obj/, and Roslyn generator caches must be completely cleared to guarantee 100% clean compilation; - Seamless Schema Evolution: Executing
--init-schemaon the API Host composition root performs idempotent schema verification, table migrations, and index alignments; - Dual-Track Automated Acceptance: Verified end-to-end via backend
dotnet test(ArchUnit boundary tests and Testcontainers integration tests) paired with frontendyarn buildbundle budget assertions.
This operational manual guides architects and engineering leads through the standard 4-step upgrade workflow.
4-Step Upgrade Workflow
Step 1: Update Dependency Baselines in Directory.Packages.props
All NuGet dependencies are centrally governed. Never hardcode package versions inside individual module projects:
<Project> <PropertyGroup> <ManagePackageVersionsCentrally>true</ManagePackageVersionsCentrally> <CentralPackageTransitivePinningEnabled>true</CentralPackageTransitivePinningEnabled> </PropertyGroup>
<ItemGroup> <!-- .NET 10 Runtime and Official Extensions --> <PackageVersion Include="Microsoft.Extensions.DependencyInjection" Version="10.0.0" /> <PackageVersion Include="Microsoft.Extensions.Logging.Abstractions" Version="10.0.0" /> <PackageVersion Include="Microsoft.Extensions.Options.ConfigurationExtensions" Version="10.0.0" />
<!-- Persistence and Dual-ORM Baselines --> <PackageVersion Include="Microsoft.EntityFrameworkCore.SqlServer" Version="10.0.0" /> <PackageVersion Include="SqlSugarCore" Version="5.1.4.195" />
<!-- Distributed Middleware and Messaging --> <PackageVersion Include="DotNetCore.CAP" Version="8.3.0" /> <PackageVersion Include="DotNetCore.CAP.RabbitMQ" Version="8.3.0" /> <PackageVersion Include="DotNetCore.CAP.SqlServer" Version="8.3.0" /> <PackageVersion Include="StackExchange.Redis" Version="2.8.24" />
<!-- Testing Infrastructure and Testcontainers --> <PackageVersion Include="Testcontainers.MsSql" Version="4.1.0" /> <PackageVersion Include="Testcontainers.Redis" Version="4.1.0" /> <PackageVersion Include="ArchUnitNET.xUnit" Version="0.11.1" /> </ItemGroup></Project>Step 2: Thoroughly Invalidate Roslyn Incremental Generator Caches
Because BitzOrcas relies heavily on Roslyn incremental source generators (such as BitzOrcas.Endpoint.SourceGenerator and BitzOrcas.DI.SourceGenerator) to synthesize Minimal API endpoints and DI registrations, upgrading packages requires clearing local compiler caches:
# 1. Clean all bin and obj directories (preserving IDE configurations)git clean -xdf -e ".vs" -e ".idea"
# 2. Restore locked dependencies and perform clean non-incremental builddotnet restore BitzOrcas.Modern.slnxdotnet build BitzOrcas.Modern.slnx -c Release --no-incrementalStep 3: Execute Database Schema Synchronization
Execute database schema inspection and seed reconciliation using the API Host CLI:
# 1. Synchronize schema tables and indexesdotnet run --project src/Hosts/BitzOrcas.Api -- --init-schema
# 2. In non-production environments requiring demo password resetsUSER__ADMIN__PASSWORD="YourStrongPassword123!" dotnet run --project src/Hosts/BitzOrcas.Api -- --init-schema --reset-demo-passwordsStep 4: Full-Repository Automated Acceptance Gates
After rebuilding the solution, execute backend tests and frontend production builds:
# 1. Backend: Verify architectural boundary invariants (prevents cross-module leaks)dotnet test tests/BitzOrcas.Architecture.Tests/
# 2. Backend: Execute containerized integration tests via Testcontainersdotnet test tests/BitzOrcas.Integration.Tests/
# 3. Frontend: Switch to frontend/ and run strict type checks and bundle budget assertionscd frontendyarn install --immutableyarn typecheckyarn workspace @bitz/app buildCommon Upgrade Pitfalls & Remediation
| Issue | Root Cause | Remediation |
|---|---|---|
NU1008: Projects that use central package management should not define the version | A subproject .csproj retained an inlined Version="1.0.0" attribute | Remove the Version attribute from the .csproj and maintain it in Directory.Packages.props |
CS0246: The type or namespace name 'XxxEndpoint' could not be found | Stale Roslyn generator cache prevented regeneration of Minimal API endpoints | Run git clean -xdf to purge obj/ directories and rebuild with --no-incremental |
SqlException: Invalid object name 'SysPlatformConfig' | Upgraded code expects newly introduced tables that have not been migrated | Run dotnet run --project src/Hosts/BitzOrcas.Api -- --init-schema to create missing tables |
Bundle budget exceeded in @bitz/app | Upgraded frontend dependencies expanded a bundle chunk beyond defined budgets | Check vite.config.ts manualChunks configuration to split bulky dependencies |
Summary
Following the standardized upgrade workflow minimizes operational risk across the engineering organization:
- Centralized Dependency Governance: CPM eliminates version drift across 100+ projects;
- Stateless Source Generation: Cache purges ensure generated code mirrors domain models with 100% precision;
- Continuous Quality Gates: Architecture guardrails, real-container integration tests, and frontend bundle budgets prevent regressions before reaching production.