Skip to content

ReleaseService

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.Releases
Built from connectsoft-microservice · libraries: connectsoft-extensions-saas-abstractions, connectsoft-extensions-messaging-model, connectsoft-extensions-persistence-model-nhibernate
Decisions ADR-0014
Traceability FR-08 FUX-05 NFR-08 NFR-12 XL-04 XL-10

Purpose and responsibilities

ReleaseService turns a succeeded pipeline run into a product release: an immutable record with a semantic version, the merged commit, the components the run produced (container images, NuGet and npm packages, Helm charts, templates, static sites) each with its digest and target, the SBOM and provenance attestations, the change proposals merged since the previous release, and the asset releases (agents, templates, blueprints) that generated the code. A release is Candidate until the PublicationVerifier has found every digest in its registry or feed — publication itself stays in the existing CI (external canonical PackagePublishingService, TemplatePublishingService) — then Released, and only a Released release can be promoted. Release notes are drafted with the structured profile as an artifact and never published automatically.

It absorbs ContainerImageService (images are components).

Context and boundaries

flowchart LR
    S["ReleaseService"]
    EnvironmentPromotionService["EnvironmentPromotionService"] -->|grpc| S
    StudioBff["StudioBff"] -->|sync-http| S
    S -->|event| PipelineExecutionService["PipelineExecutionService"]
    S -->|grpc| ArtifactService["ArtifactService"]
    S -->|grpc| ConnectorRegistryService["ConnectorRegistryService"]
    S -->|grpc| ModelRouterService["ModelRouterService"]
    S -. "ReleaseCreated" .-> E_ReleaseCreated(("event"))
    S -. "ReleaseReady" .-> E_ReleaseReady(("event"))
    S -. "ReleaseWithdrawn" .-> E_ReleaseWithdrawn(("event"))
Hold "Alt" / "Option" to enable pan & zoom

The release is the unit the Product Fleet Operations platform inventories and upgrades (P12), the unit promotions move (BC-24), and the unit the marketplace can list when a template is the product. Withdrawing a release blocks promotion; it never revokes what is already deployed — that is a rollback.

Domain model

ProductRelease — An immutable release of a generated product or module: semantic version, merged commit, components with digests, SBOM and attestations, the pipeline run and change proposals that produced it, and the asset releases (agents, templates, blueprints) that generated it. (catalog entry)

Field Type Required Description
releaseId guid yes
tenantId string yes
projectId string yes
productId string yes Generated product or module id.
version string yes
commit string yes
pipelineRunId guid yes
proposalIds list:guid yes
generatedBy json yes agent, template and blueprint release ids (provenance)
sbomRef string yes
attestationRefs list:string yes Build provenance attestations (in-toto / SLSA style)
state enum:ReleaseState yes
notesRef string no Generated release notes artifact.
createdAt datetime yes

Invariants:

  • A release is immutable once Released; a change is a new version; Withdrawn releases cannot be promoted.
  • Every component has a digest; a component without publication evidence keeps the release Candidate.
  • Provenance (commit trailers, pipeline run, generating asset releases) is required; a release without provenance is refused.
stateDiagram-v2
    Assembling --> Candidate : ComponentsResolved
    Candidate --> Released : AllPublished
    Released --> Superseded : NewerReleased
    Candidate --> Withdrawn : Withdraw
    Released --> Withdrawn : Withdraw
Hold "Alt" / "Option" to enable pan & zoom

Events: ReleaseCreated, ReleaseReady, ReleaseWithdrawn · Tables: ProductReleases, ReleaseComponents · Repository: ProductReleaseRepository

erDiagram
    ProductRelease {
        guid releaseId PK
        string tenantId
        string projectId
        string productId
        string version
        string commit
        guid pipelineRunId
        list_guid proposalIds
        json generatedBy
        string sbomRef
        list_string attestationRefs
        enum_ReleaseState state
        string notesRef
        datetime createdAt
    }
    ReleaseComponent {
        enum_ComponentKind kind

        string name

        string digest

        string target

        enum_PublicationState publication

        string evidenceRef

    }
    ProductRelease ||--o{ ReleaseComponent : contains
Hold "Alt" / "Option" to enable pan & zoom

Entities and value objects

ReleaseComponent (entity, in ProductRelease) — One component with its digest, target feed or registry and publication evidence (from the existing CI publishing).

Field Type Required Description
kind enum:ComponentKind yes
name string yes
digest string yes
target string yes registry or feed
publication enum:PublicationState yes
evidenceRef string no

Data model and storage

Store Role Engine / profile Tables
Delivery store primary azure-sql / nhibernate-sqlserver ProductReleases, ReleaseComponents
Artifact content store blob blob / azure-blob —
Table Owner Columns Indexes
dbo.ProductReleases ProductRelease 14 2
dbo.ReleaseComponents ReleaseComponent 8 0

Full DDL: appendix.

APIs

Method Path Operation Scope Side effects Idempotency Gateway Summary
GET /factory/delivery/releases ListProductReleases factory.delivery.read read natural GW-03 Releases by product, version and state with components and provenance.
GET /factory/delivery/releases/{releaseId} GetProductRelease factory.delivery.read read natural GW-03 One release with components, SBOM, attestations, pipeline run, proposals and generating assets.
POST /factory/delivery/releases CreateProductRelease factory.delivery.release shared-write key-header GW-03 Assemble a release from a succeeded pipeline run (version, components from its results, provenance); Candidate until every component has publication evidence.
POST /factory/delivery/releases/{releaseId}/withdraw WithdrawProductRelease factory.delivery.release shared-write natural GW-03 Withdraw a release with a reason (blocks promotion; revokes nothing already deployed).
gRPC service Method Streaming Visibility Side effects Summary
Releases GetRelease none internal read Resolve a release with digests and evidence for promotion and fleet inventory.

Messages

Event Topic Scope / v Aggregate Consumers Summary
ReleaseCreated releases.products.v1.release-created integration / 1 ProductRelease StudioBff, AuditService, DashboardService A candidate release exists.
ReleaseReady releases.products.v1.release-ready integration / 1 ProductRelease FleetRolloutService, EnvironmentPromotionService, StudioBff, AuditService, StudioNotificationService Every component has publication evidence; the release may be promoted.
ReleaseWithdrawn releases.products.v1.release-withdrawn integration / 1 ProductRelease EnvironmentPromotionService, StudioBff, AuditService A release was withdrawn.

ReleaseCreated payload:

Field Type Required Description
releaseId guid yes
tenantId string yes
projectId string yes
productId string yes
version string yes
commit string yes

ReleaseReady payload:

Field Type Required Description
releaseId guid yes
tenantId string yes
projectId string yes
productId string yes
version string yes
components json yes

ReleaseWithdrawn payload:

Field Type Required Description
releaseId guid yes
tenantId string yes
productId string yes
version string yes
reason string yes
Command Handled by Result events Summary
CreateProductRelease ProductRelease ReleaseCreated
WithdrawProductRelease ProductRelease ReleaseWithdrawn
Event Producer Handler Purpose
PipelineRunCompleted PipelineExecutionService AssembleFromRun A succeeded run on a release branch or tag assembles a candidate with its images, packages, SBOM and attestations.
ChangeProposalMerged PipelineExecutionService LinkProposal Proposals merged since the last release become part of the next.

Workers and jobs

Worker Trigger Output events Retry Idempotency key Summary
PublicationVerifier event ReleaseReady exponential releaseId + componentName Checks each component's feed or registry for the digest (through the existing CI publishing evidence and registry reads) and records publication evidence; moves the release to Released when complete.
ReleaseNotesWriter event — fixed releaseId Drafts release notes from merged proposals and results with the structured profile and stores them as an artifact (never auto-published).

Actors and grains

None modelled

No grains are modelled for this item yet.

Sagas and long-running flows

None modelled

No sagas are modelled for this item yet.

stateDiagram-v2
    [*] --> Assembling
    Assembling --> Candidate: ComponentsResolved
    Candidate --> Released: AllPublished (evidence per component)
    Released --> Superseded: NewerReleased
    Candidate --> Withdrawn: Withdraw
    Released --> Withdrawn: Withdraw
Hold "Alt" / "Option" to enable pan & zoom

Options and configuration

Section Key Type Default Reloadable Secret Summary
Delivery:Releases RequireAttestations bool true no no Refuse a release without provenance attestations.
Delivery:Releases NotesProfile string structured yes no Model profile for release notes.

Metrics and observability

Metric Instrument Unit Dimensions Summary
connectsoft.factory.delivery.releases counter {release} tenant, state Releases by state.
connectsoft.factory.delivery.publication_failures counter {component} tenant, kind Components whose publication could not be verified.

Security

Authentication client-credentials
Scopes factory.delivery.read (Read releases.); factory.delivery.release (Create and withdraw releases (Operator, Workspace admin, the release workflow).)
Roles Operator, WorkspaceAdmin, PlatformAdmin, Observer
Tenant isolation row-filter
Data classification internal
Max side-effect class shared-write
Secrets —

Dependencies

Outbound

Target Kind Purpose Failure mode Required
PipelineExecutionService event Run results and merged proposals. queue yes
ArtifactService grpc SBOMs, attestations, release notes. fail-fast yes
ConnectorRegistryService grpc Registry and feed reads for publication evidence. degrade yes
ModelRouterService grpc Release notes drafting. degrade no

Inbound

Target Kind Purpose Failure mode Required
EnvironmentPromotionService grpc GetRelease for promotion. — yes
StudioBff sync-http Release views. — yes

Failure and recovery

Scenario Detection Recovery Data impact RTO (min)
Component never appears in the registry verifier retries exhausted release stays Candidate with the failing component named; Operator re-runs publication in CI none 0

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

Azure Artifacts publishing and container builds exist in the pipelines; versions are tags in repositories. No release record, SBOM or attestation handling exists in the estate.

Later capabilities

Signed releases with the Factory's workload identity; SLSA level targets per edition; dependency-vulnerability re-scans of Released components with advisories as alerts.

Decisions and traceability

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