Releases: kostiantyn-matsebora/deployment-dashboard
Releases · kostiantyn-matsebora/deployment-dashboard
v0.12.1
Fixed
- Managed-identity Postgres connections now enforce SSL. The assembled connection string omitted the
SslModekeyword, so Npgsql fell back to itsPreferdefault (silent non-SSL) — which Azure Database for PostgreSQL rejects for AAD / managed-identity users, with no knob to force it. Managed-identity connections now default toSslMode=Require, so AAD auth works out of the box; static-password mode is unchanged (local/bundled non-SSL container still works). A newPOSTGRES_SSL_MODEenv var (and matchingPostgres:SslModeappsettings key) overrides the SSL mode for either auth mode, passed verbatim to Npgsql. See Configuration.
v0.12.0
Added
- Swimlanes — collapsible service lanes. Each service lane in the Swimlanes view can now collapse to a compact single-chain "vector" (the deployment chain ending at the service's newest event) and expand back to the full promotion DAG — via per-lane chevrons plus Collapse-all / Expand-all controls. An Auto-scroll-to-change toggle (on by default) keeps the latest change in view, and a card flashes to highlight a live status change in either state. Per-lane collapse state and the auto-scroll preference persist across reloads (lanes start collapsed). This is a Swimlanes-view enhancement only — no API or contract change.
v0.11.0
Added
- Analytics view — DORA Four Keys dashboard. A third dashboard view (alongside Matrix and Swimlanes) surfacing deployment frequency, lead time (approximated from
parent_deploymentspromotion chains), change failure rate, and mean time to restore (MTTR). Supported by eight charts: deployment frequency over time, change-failure-rate trend, deployment-duration distribution (p50/p95), promotion funnel (per-stage counts + conversion), status distribution, deploy heatmap (day-of-week × hour), top deployers, and time-to-restore incidents. The period control covers 7 / 14 / 30 days, bounded byHISTORY_RETENTION_DAYS. ANALYTICS_WINDOW_GRANULARITYconfig var. Controls the UTC boundary the analytics window is truncated to (day|hour), governing ETag stability and data freshness. See Configuration — API.ANALYTICS_FUNNEL_ENVIRONMENTSconfig var. Comma-separated, ordered promotion-funnel ladder; the last entry is the production terminal used for DORA lead-time measurement. Values matched case-insensitively against the deploymentenvironmentfield. See Configuration — API.
Fixed
- Demo dashboard no longer empties out as time passes. The github-emulator seeded its deployments with hard-coded absolute timestamps, which eventually aged past the fetcher's initial lookback window — so a fresh demo (or a reset + re-seed) could backfill nothing and render an empty dashboard. Seed timestamps are now shifted relative to load time (anchoring the newest event to "now"), so the demo always presents recent activity.
v0.10.0
Added
- Passwordless (managed-identity) Postgres authentication. PostgreSQL auth is now credential-optional, with the mode auto-detected from credential presence — no new toggle. With
POSTGRES_PASSWORDset, services use the static user/password as before (the default — local Compose, CI, and tests are unchanged). With it omitted or blank, each service authenticates as its ambient cloud identity (e.g. Azure Workload Identity / Managed Identity), obtaining a short-lived access token at connection time and refreshing it transparently;POSTGRES_USERis then the identity's PostgreSQL role name. This removes static-secret storage and rotation for the Azure target, behind a provider-agnostic token-provider seam. - Browser extension (MVP). A cross-browser MV3 WebExtension (
frontend/extension) that surfaces deployment status from a configured dashboard — a toolbar badge, a status filter, and a popup listing the most recent runs — with its own build and packaging CI. It is loaded manually in developer mode for now, ships outside the six published stack images, and follows its own release cycle.
Documentation
- Restructured and visually redesigned the adopter guide — install, configuration, quickstart, and screenshots — with paste-safe download steps, per-profile tabbed run cards, and clearer release-pinning guidance.
- Added a "Built by Claude" showcase page that tells the zero-to-hero story of the project as built by an AI engineering team under minimal human steering.
v0.9.0
Added
- Five new deployment statuses, surfaced end-to-end. Beyond
in-progress/success/failure, the dashboard now distinguishespending,queued,waiting,cancelled, andrejected(an 8-value status enum). The three effective statuses (success/in-progress/failure) still drive the matrix tile and swimlane card colour; the five new statuses surface as a distinct "next" badge for a deployment beyond the live one, and all eight appear in deployment history and the inspector. The contract gainsMatrixSlot.next(the latest non-effective deployment, when newer than the current effective one) andMatrixSlot.prev_failed. - Cancelled and not-approved deployments are distinguished from plain failures. The fetcher derives
cancelledfrom the associated workflow-run conclusion andrejectedfrom pending-deployment reviews — signals that live beyond GitHub'sdeployment_statuspipeline, which has nocancelled/rejectedstate of its own. - "Never deployed" neutral state. A slot whose only/latest deployment is non-effective with no effective baseline now renders a neutral tile and status chip instead of a spinner or a failure.
- Universal correlation id across the control plane. Every control command now carries a
correlation_idthat ties a user-initiated action to all of its downstream events. For a reset it is born onreset-initiatedand flows throughreset-started,reset-completed, every componentreset-ack, and the post-reset status events; the component-event stream and the demo driver's event feed surface it as a chip, and clicking a chip filters the feed to a single correlated process. Component events accept an optionalX-Correlation-Idheader (≤128 chars) that is persisted and echoed on the SSE frame.
Changed
- Breaking —
reset_idretired in favour ofcorrelation_id. The control contract no longer exposesreset_id: thePOST /api/control/reset202body returnscorrelation_id, the control-stream frames carrycorrelation_id, and the reset ack-gate now matches on theX-Correlation-Idrequest header instead of apayload.reset_idbody field. Thecomponent_events,control_stream_events, andreset_cycletables rename theirreset_idcolumn tocorrelation_id(handled by an EF migration). The demo's "reset on ingest/seed" checkboxes are removed — ingest never triggers a reset; use the dedicated Reset System control.
Fixed
- Demo rate-limit count no longer inflates on unchanged polls. The github-emulator now honours
If-None-Match(returning304with a content ETag) and exemptsGET /rate_limit, so repeated fetcher polls of unchanged data no longer grow the dashboard's reported request count.
Security
.gitignorenow ignores all**/.env.*files (while keeping.env.example), so environment files containing secrets cannot be committed accidentally.
v0.8.0
Added
- Deployment-history retention is now enforced. A daily background job prunes
deployment_eventsolder thanHISTORY_RETENTION_DAYS(default 365, minimum 90 — smaller values clamp up), alongside the short-lived control/component event logs (fixed 2-hour window). PreviouslyHISTORY_RETENTION_DAYSwas documented and wired into the API container but read by nothing, so deployment history grew unbounded. - Previously-undocumented configuration is now documented.
GATEWAY_PORT,BACKFILL,INITIAL_LOOKBACK,GITHUB_SERVICE_MAP,GITHUB_RATE_LIMIT, and the reset-choreography knobs (RESET_ACK_TIMEOUT_SECONDS,RESET_GATE_MAX_TTL_SECONDS,RESET_EXPECTED_COMPONENTS) are now incompose/.env.exampleand the configuration guide, with demo-only variables grouped in their own section.
Changed
- Breaking — unified, flat environment-variable convention. Every setting now reads as a flat
SCREAMING_SNAKEvariable (an appsettings section still provides the defaults; the environment variable overrides it). The previous .NETSection__Propertyenv forms are removed:Reset__AckTimeoutSeconds/Reset__GateMaxTtlSeconds/Reset__ExpectedComponents__N→RESET_ACK_TIMEOUT_SECONDS/RESET_GATE_MAX_TTL_SECONDS/RESET_EXPECTED_COMPONENTS(now a comma-separated list, which also removes the old array-append footgun).- every
GITHUB__<Pascal>(e.g.GITHUB__BaseUrl,GITHUB__Token) → flatGITHUB_*(GITHUB_BASE_URL,GITHUB_TOKEN, …). ConnectionStrings__Postgres→ assembled by the app fromPOSTGRES_HOST/POSTGRES_PORT/POSTGRES_DB/POSTGRES_USER/POSTGRES_PASSWORD.- Action required: adopters setting any of the old
__forms must switch to the new flat names.
- Breaking —
API_PORTrenamed toGATEWAY_PORT.API_PORTwas documented but never had any effect (the gateway is the single public surface); the host port is now correctly namedGATEWAY_PORT.
Documentation
- Documented the GitHub deployment-status → contract-status mapping decisions —
errorcollapses intofailure, andinactiveis skipped as a supersession marker — so they are not re-discovered as bugs. - The project home/README now leads with a views switcher and a light/dark C4 architecture diagram.
v0.7.0
Added
- Matrix environment-column controls. Per-user control over the matrix's environment columns: a Columns picker (matrix view) to show/hide individual environments — a hidden column is removed from the grid entirely — and drag-to-reorder of the column headers via a grip handle. The Fields and Columns buttons show a count badge when items are hidden, and "Show all · reset order" restores the defaults. Column order and visibility persist client-side and survive reloads. No API or contract change — the matrix response still carries every environment; this is purely a per-user view preference.
v0.6.1
Fixed
- Matrix tile showed an in-progress spinner for a deployment that had actually failed. A (service, environment) slot whose latest deployment failed and which had no earlier successful deployment was rendered with the amber in-progress spinner instead of a failed tile. The history drawer and swimlanes were unaffected (they read the status directly); only the matrix tile mis-derived its state. Failures now always render as a failed tile, with or without prior success history. Surfaced by backfilling a real repository whose environment had only ever failed.
Documentation
- GitHub authentication for organizations that disable fine-grained PATs. The install guide now gives the classic PAT first-class standing for private/organization repositories (previously a parenthetical), adds an over-grant caveat (the classic
reposcope grants full read/write — broader than the read-only access the Fetcher uses), and documents authorizing a classic PAT for SAML SSO — including re-authorizing after every token rotation. A new FAQ entry covers the403/X-GitHub-SSOsymptom of an unauthorized token.
v0.6.0
Added
- Fetcher rate-limit telemetry on the dashboard. The pull-mode Fetcher now reports its CI/CD API consumption after every poll cycle — a new
rate-limitcomponent event carrying the CI/CD API quota, the Fetcher's self-imposed budget, and its own usage. It is surfaced two ways: a usage chip with a click-to-expand popover in the dashboard header, and a "Fetcher · Rate Limit" card on the demo-driver panel. One indicator per configured CI/CD adapter, the last value persists across reloads, and it reuses the existing component-event stream — noDashboard.Apichange.
Changed
- Fetcher live poll stops paginating at the cursor window. The deployments-list fetch now stops as soon as it crosses the cursor cutoff (GitHub returns newest-first), instead of paging the entire repository history and trimming afterwards — turning a ~40-page scan on large, active repos into ~1 page, while keeping the page-1 ETag short-circuit. Backfill was already bounded; the live path now matches it.
- Fetcher self-throttle no longer counts free requests. Conditional
304 Not Modifiedresponses — which consume no GitHub quota — are excluded from the Fetcher's own-usage counter, so the reportedown_usedreflects real quota consumption and the budget is not tripped by free polls. The own-usage counter also resets correctly when the rate-limit window rolls over.
Fixed
- Fetcher re-fetched finished deployments on every poll cycle. A deployment's latest status was read by array position, but the GitHub deployment-statuses endpoint ordering is not guaranteed — so terminal deployments were never recorded in the skip cache and were re-polled (and their old statuses re-processed) indefinitely. The latest status is now selected by
created_at; finished deployments are fetched once and then skipped. - Fetcher top-level environment variables were silently ignored.
POLL_INTERVAL_SECONDS,INITIAL_LOOKBACK,BACKFILL_MAX_AGE, andBACKFILL_DEPTHdid not bind (configuration binding does not strip underscores from the documentedSCREAMING_SNAKEnames), so they fell back to their defaults regardless of what was set. They are now read explicitly by their documented names.
v0.5.0
Changed
- Fetcher live poll now uses conditional requests (ETag /
If-None-Match). The per-repo deployments list and in-flight deployment status re-reads sendIf-None-Match; an unchanged response comes back304 Not Modified, which does not count against the GitHub rate limit. Building on the terminal-deployment skip from 0.4.0, an idle poll cycle now returns cheap 304s instead of re-downloading the deployments list and statuses. Parent-deployment edges are preserved across cycles, and the optimization degrades gracefully to full fetches when the upstream does not supply ETags (e.g. the github-emulator). (Implements Fetcher spec F8.)