Baseline Architecture¶
How the four Progress.* NuGet packages fit together, where they come from, and what each client repo actually owns.
1. The Four Baseline Packages¶
Every client site references the same four NuGet packages — pinned at 1.* (stable per-major float). Fixes published to the baseline flow into all clients on the next dotnet restore.
| Package | Contents | Consumed where |
|---|---|---|
| Progress.Baseline.Core | Shared C# services (ISiteSettingsService, IDictionaryService, IArticleService, IGlobalNotificationsService, …), interfaces, view models, DI registration (AddProgressBaselineCore()), configuration defaults (AddProgressBaselineDefaults()), URL rewriting, security middleware. |
Program.cs — DI registration |
| Progress.Baseline.Web | 190+ Razor views (page templates, BlockGrid/BlockList components, site layout partials), 172 historical client CSS themes, JavaScript, vendor libraries (Bootstrap 5.3.3, jQuery, Slick), uSync baseline schema files (555+ content types, 666 data types, 142 dictionary items, 36 templates). Copies views and assets into the client repo on dotnet build. |
Client Views/ + wwwroot/ via build-time copy |
| Progress.CustomPropertyEditors | 31 TypeScript-based Umbraco backoffice property editors (headings, testimonials, calculators, FAQ, maps, social, etc.) — packaged as static App_Plugins/ assets. |
Auto-registered by Umbraco at startup |
| Progress.LoanCalculator | Standalone loan calculation engine (ILoanCalculatorEstimator) plus calculator API and Razor views. |
Program.cs — DI registration |
2. Source of Truth¶
The baseline is built from a single Azure DevOps repo:
- Org / Project:
https://dev.azure.com/ProgressSystemsLtd/CUCloud.Web - Repo:
Umbraco.Core(branch:main) - Build pipeline: The baseline NuGet build pipeline (pipeline 51 in Azure DevOps)
- NuGet feed: Azure Artifacts feed
CUCloud-Web-Packageshttps://pkgs.dev.azure.com/ProgressSystemsLtd/CUCloud.Web/_packaging/CUCloud-Web-Packages/nuget/v3/index.json
Authentication for client dotnet restore:
- Interactive (developer): Install the Azure Artifacts credential provider, then
az login - PAT: Generate an Azure DevOps PAT with
Packaging: Readand embed it innuget.config - CI pipelines: Use the
NuGetAuthenticate@1Azure Pipelines task
3. Release Model¶
Each commit landed on Umbraco.Core/main triggers Pipeline 51, which:
- Builds and tests the solution
- Packs the four
Progress.*packages - Auto-bumps the patch tag (e.g.
1.0.7→1.0.8) and pushes the tag - The tag drives MinVer to produce a stable NuGet version (no
-previewsuffix) - Pushes the stable package to
CUCloud-Web-Packages
Major and minor version bumps are manual — performed when intentionally breaking API or shipping a substantial feature set.
Client impact: With Version="1.*" pinned in Progress.Web.csproj, each client picks up the latest stable patch on every dotnet restore. Major bumps require an explicit version change in the client csproj.
How baseline file updates reach the client repo —
dotnet restorepulls the new package, but baseline templates and assets are not silently overwritten in the client'sViews/andwwwroot/on the next build. See Section 6 — Pulling baseline file updates for the opt-in flow.
4. AddProgressBaselineDefaults()¶
The template's Program.cs already wires up:
This loads a baseline appsettings.json shipped inside Progress.Baseline.Web at the lowest precedence in the configuration chain. It currently covers:
Umbraco:CMS:Runtime:Mode(production-appropriate default)Umbraco:CMS:Content:DisallowedUploadedFileExtensions- BlockPreview configuration
- Other baseline-wide settings that should be uniform across all clients
Precedence (lowest → highest):
AddProgressBaselineDefaults()← baseline defaultsappsettings.json← client base configappsettings.{Environment}.json← per-environment overrides- Environment variables ← container / hosting overrides
To override a baseline default, simply set the same key in client appsettings.json (or a more specific layer). Baseline-wide settings don't need to live in every client repo.
5. What Each Client Repo Owns vs Inherits¶
| Concern | Owner | Location |
|---|---|---|
| Connection string | Client | appsettings.{Environment}.json |
| Brand CSS theme | Client | src/Progress.Web/wwwroot/cssCreditUnion/theme.css |
| Client logo / brand images | Client | src/Progress.Web/wwwroot/images/ |
| Client-specific config (Google Maps key, notifications filters, etc.) | Client | src/Progress.Web/appsettings.json |
| View overrides (when needed) | Client | src/Progress.Web/Views/Overrides/ (or edit baseline view in-place after build copy) |
| Page templates, layouts, BlockGrid components | Baseline | Progress.Baseline.Web |
| Backoffice property editors | Baseline | Progress.CustomPropertyEditors |
| C# services + DI | Baseline | Progress.Baseline.Core |
| Loan calculator engine | Baseline | Progress.LoanCalculator |
| Umbraco schema (content types, data types, templates) | Baseline | uSync files in Progress.Baseline.Web, imported on first run |
Rule of thumb: if the change is brand/data/config, it lives in the client repo. If it's structural or shared, it lives in Umbraco.Core and ships via the next baseline release.
6. Pulling Baseline File Updates¶
Progress.Baseline.Web ships its views and static assets as physical files that land in the client Views/ and wwwroot/ folders at build time. Umbraco requires this — the backoffice template editor and Razor view engine read from disk, not from a NuGet's bin/ output.
Because those files are physically present and tracked by git, the build target follows an opt-in update model so a dotnet restore of a newer package version never silently overwrites client customisations.
Default behaviour (no flag)¶
On every dotnet build:
- New files present in the package but not yet on disk → copied in. This is how new clients get the full baseline on first restore and how brand-new components in a baseline release reach existing clients.
- Existing files → never touched. Local edits — whether changed in the IDE or saved via the Umbraco backoffice — survive every build.
- A one-line informational hint is logged once existing files are detected:
Baseline views: to pull package updates into existing files,
run 'dotnet build /p:BaselineUpdate=true' and review with 'git diff'.
Pulling updates from a newer baseline package¶
When a baseline release fixes or improves a view/asset you have not customised, opt in explicitly:
This copies every baseline file from the package over the local copy. Copy SkipUnchangedFiles="true" means identical files are a no-op — only genuinely different files end up in git diff. The dev then:
git diff -- Views/ wwwroot/— review every change.- Keep, revert, or merge each modified file (file-by-file).
- Commit what you want to keep.
CI / CD safety guarantee¶
CI pipelines never pass /p:BaselineUpdate=true. Whatever is committed to the client repo is what ships — automated builds cannot silently clobber committed overrides. Override behaviour is a deliberate developer action.
Local vs RCL view resolution¶
Razor view resolution picks the local file in Views/ ahead of any embedded view from a Razor Class Library. After dotnet build the baseline view is always physically present on disk, so the file you see in Views/ is the file Umbraco renders and the file the backoffice template editor opens.
Resetting a single file to baseline¶
Delete it and rebuild — the default "copy new files" path re-creates it:
Historical: Views/Views nesting (baseline ≤ 1.0.0)¶
Baseline 1.0.0 had a PackagePath bug in Progress.Baseline.Web.csproj that materialised templates into Views/Views/… instead of Views/…. Symptom: the Umbraco backoffice template editor opened blank for affected templates while the file existed on disk. Fixed in Progress.Baseline.Web 1.0.1. Clients with a stale install must clean up before rebuilding with a newer baseline:
After the rebuild, the 1.0.1+ target copies every view to the correct flat Views/<path>/<file>.cshtml location and the backoffice editor renders the content as expected.
Related¶
- Quick Start — New Project — Scaffold a client from the template
- Adding a New Client — End-to-end onboarding with Azure deployment
- Developer Guide — Service APIs and customisation patterns
- CSS Theming — Per-client brand overrides