Add structured JSON configuration variable replacement to IIS deploy (Phase 9)
Summary
Mirrors Octopus's Octopus.Features.JsonConfigurationVariables (StructuredConfigurationVariablesBehaviour.cs:13-35). Walks operator-specified JSON files, recurses the object structure, replaces leaf values whose path matches a Squid variable name. Supports both : (colon, .NET Core IConfiguration style) and . (dot, .NET Framework style) path separators.
Distinct from Phase 8 SubstituteInFiles:
- SubstituteInFiles = TEXT-level
#{X}token replacement (any format) - StructuredConfigurationVariables = STRUCTURE-AWARE leaf replacement (operator stores
ConnectionStrings:Defaultas variable name; walker matches JSON pathconnectionStrings.defaultand replaces ONLY that leaf)
PS1 hook order matches Octopus pipeline: SubstituteInFiles → ConfigurationTransforms → ConfigurationVariables → StructuredConfigurationVariables → IIS configure.
What ships
Production (+105 LOC)
| Change | Notes |
|---|---|
| 2 new constants |
StructuredConfigurationVariablesEnabled + Targets
|
Targets via base64 |
Newlines preserved for multi-glob list |
Update-IISStructuredJsonConfiguration PS1 |
Recursive Walk-JsonReplace helper; both : and . path separators; arrays of primitives skipped (Phase 9 MVP) |
ConvertTo-Json -Depth 32 |
Default depth of 2 truncates configs |
Test code (+260 LOC, 6 new tests)
| Tier | New | What |
|---|---|---|
| Drift detector | 1 | Function presence; both path separators; ordering AFTER ConfigurationVariables |
| Unit | 1 | Toggle + Targets in preamble (Targets via base64) |
| Real-host | 4 | Top-level leaf; nested via : (.NET Core); nested via . (.NET Framework); feature-disabled gate |
Octopus alignment
- JSON-only Phase 9 MVP: Octopus also handles YAML/properties via separate parsers; deferred to 9.5
- Both path separators: matches Octopus's case-insensitive lookup against both forms
-
Hook order: matches
DeployPackageCommand.cs:118(LAST among rewriters)
Cumulative state after Phase 9
- Unit: 70 → 72 (+2)
- Real-host: 50 → 54 (+4)
- Octopus feature surface: 7/8 complete — only Package Extraction (Phase 10) remains
Test plan
-
dotnet test --filter FullyQualifiedName~IISDeployon macOS — 72 unit tests green -
dotnet test --filter Category=IISDeployE2Eon macOS — 54 real-host tests skip cleanly -
dotnet build0 errors -
CI run on windows-latest
Out of scope
- Phase 9.5: YAML/properties structured config; array element replacement
- Phase 10: Package extraction (NuGet/Zip) — unblocks UI "Package installation directory" mode
- Phase 11: Custom installation directory + purge
- Phase 12: IIS cert auto-import + private-key ACL
Breaking-change risk
None.