Skip to content

EnvironmentPromotionService

Target

This page describes intended behaviour or structure. No implementation is claimed unless a section is explicitly marked Current implementation or Evidence.

Bounded context BC-24 Package & Release Delivery
Platform / plane DevOps / GitOps / Execution
Deployment granularity module of host · host DeliveryHost
Status target · ConnectSoft.Factory.Delivery.Promotions
Built from connectsoft-microservice · libraries: connectsoft-extensions-saas-abstractions, connectsoft-extensions-messaging-model, connectsoft-extensions-persistence-model-nhibernate, connectsoft-extensions-scheduler-model-hang-fire
Decisions ADR-0004, ADR-0015
Traceability FR-08 FUX-05 FUX-02 NFR-08 NFR-09 XL-04 XL-10

Purpose and responsibilities

EnvironmentPromotionService is the gate between a release and a running environment. A promotion evaluates its gates in order — pipeline results, the deployment-domain policy decision (BC-18), the prior environment class in the project's promotion path, the environment's readiness, and evaluation evidence where the release carries agent-generated assets — then, for production, waits for an approval of class production bound to the exact release and environment and decided by someone other than the requester (D21, ADR-0015). Once approved it builds the desired-state specification and hands it to IaCProvisioningService (BC-25), which applies it and reports back; the service then verifies (health, smoke suite, SLO window) and completes, or rolls back automatically to the previous release with evidence.

The deploy-environment tool (production class) is how an agent requests a promotion; an Operator can request or roll back from the Studio.

Context and boundaries

flowchart LR
    S["EnvironmentPromotionService"]
    ToolAdapterService["ToolAdapterService"] -->|grpc| S
    StudioBff["StudioBff"] -->|sync-http| S
    S -->|grpc| ReleaseService["ReleaseService"]
    S -->|grpc| PolicyEngineService["PolicyEngineService"]
    S -->|grpc| RunControlService["RunControlService"]
    S -->|event| IaCProvisioningService["IaCProvisioningService"]
    S -->|grpc| SloService["SloService"]
    S -. "PromotionRequested" .-> E_PromotionRequested(("event"))
    S -. "PromotionApproved" .-> E_PromotionApproved(("event"))
    S -. "PromotionCompleted" .-> E_PromotionCompleted(("event"))
    S -. "PromotionFailed" .-> E_PromotionFailed(("event"))
    S -. "RollbackCompleted" .-> E_RollbackCompleted(("event"))
Hold "Alt" / "Option" to enable pan & zoom

This service never touches infrastructure: it owns the decision and the evidence, provisioning owns the change. Rollback is a promotion of the previous release with the same gates except the approval, which the Operator holds by role.

Domain model

Promotion — One request to put a release into an environment: gates with their outcomes, the approval (production class) when the environment is production, the strategy, the desired-state hand-off to provisioning, verification results and, if needed, the rollback with its evidence. (catalog entry)

Field Type Required Description
promotionId guid yes
tenantId string yes
projectId string yes
releaseId guid yes
environmentId string yes
environmentClass string yes development
strategy enum:Strategy yes
gates json yes Per gate kind outcome and evidence reference.
approvalId guid no
requestedBy string yes
runId guid no The Factory run that requested it (deploy-environment tool).
desiredStateRef string no Deployment specification handed to BC-25.
verification json no Health, smoke and SLO checks after deploy.
previousReleaseId guid no
state enum:PromotionState yes
requestedAt datetime yes
completedAt datetime no

Invariants:

  • A production promotion needs an approval of class production bound to the exact release id and environment, decided by someone other than the requester (D21, ADR-0015); lower classes need policy allow and passing gates.
  • A release may only enter production after it completed in the prior environment class of the project's promotion path, unless policy allows a hotfix path with evidence.
  • Deployment itself is done by provisioning (BC-25) from the desired state; this service never touches infrastructure directly.
  • A rollback is a promotion of the previous release with the same gates except approval, which the Operator holds by role for rollbacks.
stateDiagram-v2
    Requested --> GatesEvaluating : Start
    GatesEvaluating --> AwaitingApproval : GatesPassedApprovalRequired
    GatesEvaluating --> Approved : GatesPassedNoApproval
    GatesEvaluating --> Rejected : GateFailed
    AwaitingApproval --> Approved : ApprovalGranted
    AwaitingApproval --> Rejected : ApprovalRejectedOrExpired
    Approved --> Deploying : DesiredStateHandedOff
    Deploying --> Verifying : ProvisioningApplied
    Verifying --> Completed : VerificationPassed
    Verifying --> RolledBack : VerificationFailedAutoRollback
    Deploying --> Failed : ProvisioningFailed
    Completed --> RolledBack : ManualRollback
Hold "Alt" / "Option" to enable pan & zoom

Events: PromotionRequested, PromotionApproved, PromotionCompleted, PromotionFailed, RollbackCompleted · Tables: Promotions, PromotionGates · Repository: PromotionRepository

erDiagram
    Promotion {
        guid promotionId PK
        string tenantId
        string projectId
        guid releaseId
        string environmentId
        string environmentClass
        enum_Strategy strategy
        json gates
        guid approvalId
        string requestedBy
        guid runId
        string desiredStateRef
        json verification
        guid previousReleaseId
        enum_PromotionState state
        datetime requestedAt
        datetime completedAt
    }
Hold "Alt" / "Option" to enable pan & zoom

Entities and value objects

None modelled

No entities or value objects are modelled for this item yet.

Data model and storage

Store Role Engine / profile Tables
Delivery store primary azure-sql / nhibernate-sqlserver Promotions, PromotionGates
Table Owner Columns Indexes
dbo.Promotions Promotion 16 2
dbo.PromotionGates Promotion 6 0

Full DDL: appendix.

APIs

Method Path Operation Scope Side effects Idempotency Gateway Summary
GET /factory/delivery/promotions ListPromotions factory.delivery.read read natural GW-03 Promotions by environment, release and state with gates.
GET /factory/delivery/promotions/{promotionId} GetPromotion factory.delivery.read read natural GW-03 One promotion with gates, approval, desired state, verification and rollback evidence.
POST /factory/delivery/promotions RequestPromotion factory.delivery.promote production key-header GW-03 Promote a ready release into an environment (production class for production; called by the deploy-environment tool or an Operator).
POST /factory/delivery/promotions/{promotionId}/rollback RollbackPromotion factory.delivery.operate production natural GW-03 Roll back to the previous release in that environment (Operator by role; evidence recorded).
GET /factory/environments/{environmentId}/current-release GetCurrentRelease factory.delivery.read read natural GW-03 The release currently completed in an environment (fleet inventory and the Studio read it).
gRPC service Method Streaming Visibility Side effects Summary
Promotions Request none internal production Request a promotion from the deploy-environment tool with the run and receipt.

Messages

Event Topic Scope / v Aggregate Consumers Summary
PromotionRequested releases.promotions.v1.promotion-requested integration / 1 Promotion StudioBff, AuditService, DashboardService A promotion was requested; gates are evaluating.
PromotionApproved releases.promotions.v1.promotion-approved integration / 1 Promotion IaCProvisioningService, StudioBff, AuditService Gates passed and (for production) the approval was granted; desired state is handed to provisioning.
PromotionCompleted releases.promotions.v1.promotion-completed integration / 1 Promotion FleetRolloutService, FleetInventoryService, RunControlService, EnvironmentService, StudioBff, AuditService, DashboardService, StudioNotificationService The release is running and verified in the environment.
PromotionFailed releases.promotions.v1.promotion-failed integration / 1 Promotion FleetRolloutService, RunControlService, StudioBff, AuditService, AlertRuleService, DashboardService Provisioning or verification failed.
RollbackCompleted releases.promotions.v1.rollback-completed integration / 1 Promotion FleetInventoryService, EnvironmentService, StudioBff, AuditService, AlertRuleService The previous release is back in the environment.

PromotionRequested payload:

Field Type Required Description
promotionId guid yes
tenantId string yes
projectId string yes
releaseId guid yes
environmentId string yes
environmentClass string yes
runId guid no

PromotionApproved payload:

Field Type Required Description
promotionId guid yes
tenantId string yes
releaseId guid yes
environmentId string yes
strategy enum:Strategy yes
desiredStateRef string yes
approvalId guid no

PromotionCompleted payload:

Field Type Required Description
promotionId guid yes
tenantId string yes
projectId string yes
releaseId guid yes
environmentId string yes
environmentClass string yes
previousReleaseId guid no

PromotionFailed payload:

Field Type Required Description
promotionId guid yes
tenantId string yes
releaseId guid yes
environmentId string yes
reason string yes
rolledBack bool yes

RollbackCompleted payload:

Field Type Required Description
promotionId guid yes
tenantId string yes
environmentId string yes
releaseId guid yes
restoredReleaseId guid yes
Command Handled by Result events Summary
RequestPromotion Promotion PromotionRequested
RollbackPromotion Promotion RollbackCompleted
Event Producer Handler Purpose
ReleaseReady ReleaseService EnablePromotion Only ready releases are promotable.
ReleaseWithdrawn ReleaseService BlockPromotion Reject pending promotions of a withdrawn release.
ApprovalDecided RunControlService ApplyApproval Production promotions wait for the bound approval.
EnvironmentStateChanged EnvironmentService GateEnvironment The EnvironmentReady gate and completion tracking.
ProvisioningApplied IaCProvisioningService StartVerification Provisioning reports the desired state applied.
ProvisioningFailed IaCProvisioningService FailPromotion Provisioning reports failure.

Workers and jobs

Worker Trigger Output events Retry Idempotency key Summary
GateEvaluator event PromotionApproved fixed promotionId + gateKind Evaluates gates in order (pipeline results, policy, prior environment, environment ready, evaluation evidence where the product release carries agent-generated assets) and requests the approval when the environment class demands it.
Verifier event PromotionCompleted, PromotionFailed, RollbackCompleted fixed promotionId Runs post-deploy verification (health, smoke suite from the pipeline, SLO window) and completes or auto-rolls back per strategy.

Actors and grains

None modelled

No grains are modelled for this item yet.

Sagas and long-running flows

PromotionSaga — correlation promotionId; starts on EnvironmentPromotionService.PromotionRequested

Step Trigger Do Compensation
1 PromotionRequested Evaluate gates in order and record evidence per gate. Reject with the failing gate named.
2 GatesPassed (production) Request an approval of class production bound to the release and environment; wait. Reject on rejection or expiry.
3 Approved Build the desired-state specification from the release and the environment and hand it to IaCProvisioningService. Fail the promotion; environment unchanged.
4 ProvisioningApplied Run verification (health Roll back to the previous release through provisioning; record evidence.
5 VerificationPassed Complete; notify; update the environment's current release. none
sequenceDiagram
    participant O as Operator / deploy-environment tool
    participant E as EnvironmentPromotionService
    participant PE as PolicyEngineService
    participant RC as RunControlService (approvals)
    participant PR as IaCProvisioningService
    participant S as SloService
    O->>E: RequestPromotion (release 2.3.0 → production)
    E->>E: gates: pipeline results, prior environment (staging Completed), environment Ready
    E->>PE: Decide (Deployment, production) → RequireApproval
    E->>RC: approval (production class, bound to release + environment)
    RC-)E: ApprovalDecided (Approved by a Reviewer ≠ requester)
    E-)PR: PromotionApproved (desired state, strategy Canary)
    PR-)E: ProvisioningApplied
    E->>S: SLO window 15 min, health, smoke
    alt verified
        E-)O: PromotionCompleted
    else failed
        E-)PR: roll back to 2.2.4
        E-)O: PromotionFailed (rolledBack) + RollbackCompleted
    end
Hold "Alt" / "Option" to enable pan & zoom

Options and configuration

Section Key Type Default Reloadable Secret Summary
Delivery:Promotions PromotionPath string[] [development, test, staging, production] yes no Environment classes in promotion order.
Delivery:Promotions VerificationWindowMinutes int 15 yes no SLO observation window before completion.
Delivery:Promotions AutoRollbackOnVerificationFailure bool true yes no Roll back automatically when verification fails.

Metrics and observability

Metric Instrument Unit Dimensions Summary
connectsoft.factory.delivery.promotions counter {promotion} tenant, environmentClass, state Promotions by outcome.
connectsoft.factory.delivery.promotion_lead_time histogram s environmentClass Request to completion.
connectsoft.factory.delivery.rollbacks counter {rollback} tenant, environmentClass, automatic Rollbacks.

Security

Authentication client-credentials
Scopes factory.delivery.read (Read promotions.); factory.delivery.promote (Request promotions (the deploy-environment tool, Operator, Workspace admin).); factory.delivery.operate (Roll back (Operator).)
Roles Operator, Reviewer, WorkspaceAdmin, PlatformAdmin, Observer
Tenant isolation row-filter
Data classification internal
Max side-effect class production
Secrets —

Dependencies

Outbound

Target Kind Purpose Failure mode Required
ReleaseService grpc Release resolution. fail-fast yes
PolicyEngineService grpc Deployment-domain decisions. fail-fast yes
RunControlService grpc Approval requests of class production. fail-fast yes
IaCProvisioningService event Desired state hand-off; apply and failure reports. queue yes
SloService grpc SLO window verification. degrade no

Inbound

Target Kind Purpose Failure mode Required
ToolAdapterService grpc Request from the deploy-environment tool. — yes
StudioBff sync-http Promotion views and operator actions. — yes

Failure and recovery

Scenario Detection Recovery Data impact RTO (min)
Approval expires ApprovalDecided Expired promotion Rejected; a new request binds a new approval none 0
Verification fails health or smoke failure within the window automatic rollback to the previous release with evidence; alert brief exposure of the failed release 15

NFR targets

Target Class value (pilot-batch) Override
latency_p95_ms 0 —
availability_pct 99.5 —
throughput_rps 10 —
rpo_minutes 15 —
rto_minutes 240 —
cost_class medium —

Deployment

Granularity module of host · host DeliveryHost
Topologies saas-default, hybrid, on-prem, hybrid-compute
Runtime —; replicas —–—
Ports —

Current implementation

Pulumi programs and Azure Pipelines stages deploy per repository with manual approvals in Azure DevOps environments. No Factory gate, approval binding, desired-state hand-off or verification exists.

Later capabilities

Progressive delivery with automatic canary analysis against SLOs; promotion windows and freeze periods per tenant; fleet-wide rollout orchestration (P12) built on single-environment promotions.

Decisions and traceability

Family Ids
FR FR-08
FUX FUX-05, FUX-02
NFR NFR-08, NFR-09
XL XL-04, XL-10