Add project Transient Deployment Targets deployment setting
Summary
Item 3 of the Machine Policy / deployment-settings series. Introduces a project-level DeploymentSettings concept (persisted as a jsonb blob on the project — extensible without a per-setting migration) and its first member, Transient Deployment Targets, mirroring the project deployment setting:
-
Unavailable deployment targets:
SkipAndContinue(default) orFailDeployment. -
Unhealthy deployment targets:
Exclude(default) orDoNotExclude.
The deploy pipeline (4_PrepareDeploymentPhase) now honours it. Previously it unconditionally excluded unavailable + unhealthy targets; a pure TransientDeploymentTargetEvaluator splits the two categories and the phase skips, keeps, or fails accordingly.
Settable via a dedicated get/save (GET/POST projects/{id}/deployment-settings), kept isolated from the project CRUD mapping. A null/blank/malformed blob degrades to all-defaults rather than throwing.
Why non-breaking
-
Defaults = today's behaviour:
SkipAndContinue+Exclude(enum value 0) reproduce the historical unconditional exclusion exactly, so an unconfigured project — and every pre-existing project, whose new column isnull— behaves identically. - New nullable
jsonbcolumn (additive DbUp migration); new files + an isolated get/save endpoint; no change to project CRUD, no enum/wire renames, no Octopus wording. - Operators opt into
FailDeployment/DoNotExcludeper project.
Test plan
-
Unit — TransientDeploymentTargetEvaluatorfull matrix (default reproduces historical exclusion; FailDeployment; DoNotExclude; mixed; empty). -
Unit — DeploymentSettingsSerializer(null/blank/malformed → defaults; round-trip; enums as stable strings). -
Unit — PrepareDeploymentPhase.ApplyTransientTargetPolicy(ctx mutation: default exclusion, FailDeployment throws, DoNotExclude keeps, SkipAndContinue skips). -
Integration (real Postgres) — ProjectDeploymentSettingsServiceget-defaults + save/get round-trip through thedeployment_settings_jsoncolumn. -
Full solution build 0 errors; full unit sweep 5738 passed.