Skip to content

Releases: kostiantyn-matsebora/deployment-dashboard

v0.12.1

15 Jun 13:52
02e9d83

Choose a tag to compare

Fixed

  • Managed-identity Postgres connections now enforce SSL. The assembled connection string omitted the SslMode keyword, so Npgsql fell back to its Prefer default (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 to SslMode=Require, so AAD auth works out of the box; static-password mode is unchanged (local/bundled non-SSL container still works). A new POSTGRES_SSL_MODE env var (and matching Postgres:SslMode appsettings key) overrides the SSL mode for either auth mode, passed verbatim to Npgsql. See Configuration.

v0.12.0

14 Jun 17:56
495db1c

Choose a tag to compare

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

14 Jun 17:34
3fa538b

Choose a tag to compare

Added

  • Analytics view — DORA Four Keys dashboard. A third dashboard view (alongside Matrix and Swimlanes) surfacing deployment frequency, lead time (approximated from parent_deployments promotion 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 by HISTORY_RETENTION_DAYS.
  • ANALYTICS_WINDOW_GRANULARITY config var. Controls the UTC boundary the analytics window is truncated to (day | hour), governing ETag stability and data freshness. See Configuration — API.
  • ANALYTICS_FUNNEL_ENVIRONMENTS config 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 deployment environment field. 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

13 Jun 08:18
78df86e

Choose a tag to compare

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_PASSWORD set, 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_USER is 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

06 Jun 22:22
7124f2e

Choose a tag to compare

Added

  • Five new deployment statuses, surfaced end-to-end. Beyond in-progress / success / failure, the dashboard now distinguishes pending, queued, waiting, cancelled, and rejected (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 gains MatrixSlot.next (the latest non-effective deployment, when newer than the current effective one) and MatrixSlot.prev_failed.
  • Cancelled and not-approved deployments are distinguished from plain failures. The fetcher derives cancelled from the associated workflow-run conclusion and rejected from pending-deployment reviews — signals that live beyond GitHub's deployment_status pipeline, which has no cancelled/rejected state 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_id that ties a user-initiated action to all of its downstream events. For a reset it is born on reset-initiated and flows through reset-started, reset-completed, every component reset-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 optional X-Correlation-Id header (≤128 chars) that is persisted and echoed on the SSE frame.

Changed

  • Breaking — reset_id retired in favour of correlation_id. The control contract no longer exposes reset_id: the POST /api/control/reset 202 body returns correlation_id, the control-stream frames carry correlation_id, and the reset ack-gate now matches on the X-Correlation-Id request header instead of a payload.reset_id body field. The component_events, control_stream_events, and reset_cycle tables rename their reset_id column to correlation_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 (returning 304 with a content ETag) and exempts GET /rate_limit, so repeated fetcher polls of unchanged data no longer grow the dashboard's reported request count.

Security

  • .gitignore now ignores all **/.env.* files (while keeping .env.example), so environment files containing secrets cannot be committed accidentally.

v0.8.0

05 Jun 20:54
cf7fd41

Choose a tag to compare

Added

  • Deployment-history retention is now enforced. A daily background job prunes deployment_events older than HISTORY_RETENTION_DAYS (default 365, minimum 90 — smaller values clamp up), alongside the short-lived control/component event logs (fixed 2-hour window). Previously HISTORY_RETENTION_DAYS was 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 in compose/.env.example and 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_SNAKE variable (an appsettings section still provides the defaults; the environment variable overrides it). The previous .NET Section__Property env forms are removed:
    • Reset__AckTimeoutSeconds / Reset__GateMaxTtlSeconds / Reset__ExpectedComponents__NRESET_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) → flat GITHUB_* (GITHUB_BASE_URL, GITHUB_TOKEN, …).
    • ConnectionStrings__Postgres → assembled by the app from POSTGRES_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_PORT renamed to GATEWAY_PORT. API_PORT was documented but never had any effect (the gateway is the single public surface); the host port is now correctly named GATEWAY_PORT.

Documentation

  • Documented the GitHub deployment-status → contract-status mapping decisions — error collapses into failure, and inactive is 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

04 Jun 22:13
b2a3134

Choose a tag to compare

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

04 Jun 17:44
414ed74

Choose a tag to compare

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 repo scope 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 the 403 / X-GitHub-SSO symptom of an unauthorized token.

v0.6.0

04 Jun 16:09
49fa179

Choose a tag to compare

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-limit component 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 — no Dashboard.Api change.

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 Modified responses — which consume no GitHub quota — are excluded from the Fetcher's own-usage counter, so the reported own_used reflects 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, and BACKFILL_DEPTH did not bind (configuration binding does not strip underscores from the documented SCREAMING_SNAKE names), so they fell back to their defaults regardless of what was set. They are now read explicitly by their documented names.

v0.5.0

03 Jun 19:18
a360542

Choose a tag to compare

Changed

  • Fetcher live poll now uses conditional requests (ETag / If-None-Match). The per-repo deployments list and in-flight deployment status re-reads send If-None-Match; an unchanged response comes back 304 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.)