docs(api): add releases timeline page

## Changes
- Add a Releases tab to the top navigation via a custom Starlight
  Header override (HeaderLinks.astro)
- Add ReleaseCard.astro — Vercel/Linear-style entry with sticky date
  + version on the left, headline and feature bullets on the right
- Curate 14 release entries spanning v1.0 (Sept 2024) through v3.7.1
  (April 2026), each focused on the most important user-facing
  features rather than every commit
- Newest release carries a "Latest" badge in the brand color
- Mobile layout collapses the two-column timeline to a single column

## Benefits
- Visitors can see at a glance what shipped recently and what
  Checkmate has matured into over time
- The data file (src/data/releases.ts) is the only thing that needs
  editing when a new version ships — no template or styling churn
- Built on the same Starlight site as the API docs, so look and feel
  stay consistent
This commit is contained in:
gorkem-bwl committed 2026-05-22 10:25:06 -04:00
1 parent 9aa2594df7
commit e69f40fdd0
5 files changed
+400

No files matched your search

+29
View File
@@ -0,0 +1,29 @@
---
// Renders next to the search/theme controls in Starlight's header.
// Adds a "Releases" link plus delegates to the default SocialIcons.
import Default from "@astrojs/starlight/components/SocialIcons.astro";
---
<a class="header-link" href="/docs/releases">Releases</a>
<Default><slot /></Default>
<style>
.header-link {
color: var(--sl-color-white);
font-size: var(--sl-text-sm);
font-weight: 500;
text-decoration: none;
padding: 0.4rem 0.75rem;
border-radius: 0.375rem;
transition: background-color 0.15s ease;
}
.header-link:hover {
background-color: var(--sl-color-gray-5);
}
:global([data-theme="light"]) .header-link {
color: var(--sl-color-gray-6);
}
:global([data-theme="light"]) .header-link:hover {
background-color: var(--sl-color-gray-1);
}
</style>
+139
View File
@@ -0,0 +1,139 @@
---
interface Props {
version: string;
date: string;
headline: string;
highlights: string[];
isLatest?: boolean;
}
const { version, date, headline, highlights, isLatest = false } = Astro.props;
const formattedDate = new Date(date).toLocaleDateString("en-US", {
month: "long",
day: "numeric",
year: "numeric",
});
---
<article class="release-card">
<aside class="release-meta">
<time datetime={date}>{formattedDate}</time>
<span class="release-version">
{version}
{isLatest && <span class="latest-badge">Latest</span>}
</span>
</aside>
<div class="release-content">
<h2 class="release-headline">{headline}</h2>
<ul class="release-highlights">
{highlights.map((item) => <li>{item}</li>)}
</ul>
</div>
</article>
<style>
.release-card {
display: grid;
grid-template-columns: 200px 1fr;
gap: 2.5rem;
padding: 2rem 0;
border-bottom: 1px solid var(--sl-color-gray-5);
align-items: flex-start;
}
.release-card:last-child {
border-bottom: none;
}
.release-meta {
display: flex;
flex-direction: column;
gap: 0.4rem;
position: sticky;
top: 6rem;
}
.release-meta time {
color: var(--sl-color-gray-3);
font-size: var(--sl-text-sm);
font-feature-settings: "tnum";
}
.release-version {
display: inline-flex;
align-items: center;
gap: 0.5rem;
color: var(--sl-color-white);
font-weight: 600;
font-size: var(--sl-text-base);
font-variant-numeric: tabular-nums;
}
.latest-badge {
background: var(--sl-color-accent);
color: var(--sl-color-white);
font-size: 0.6875rem;
font-weight: 600;
letter-spacing: 0.04em;
text-transform: uppercase;
padding: 0.15rem 0.5rem;
border-radius: 0.25rem;
line-height: 1.2;
}
.release-content {
min-width: 0;
}
.release-headline {
margin: 0 0 1rem 0;
font-size: var(--sl-text-xl);
font-weight: 600;
color: var(--sl-color-white);
line-height: 1.3;
}
.release-highlights {
margin: 0;
padding-left: 1.25rem;
display: flex;
flex-direction: column;
gap: 0.5rem;
}
.release-highlights li {
color: var(--sl-color-gray-2);
line-height: 1.55;
font-size: var(--sl-text-base);
}
.release-highlights li::marker {
color: var(--sl-color-accent);
}
:global([data-theme="light"]) .release-card {
border-bottom-color: var(--sl-color-gray-2);
}
:global([data-theme="light"]) .release-version,
:global([data-theme="light"]) .release-headline {
color: var(--sl-color-gray-6);
}
:global([data-theme="light"]) .release-highlights li {
color: var(--sl-color-gray-5);
}
@media (max-width: 768px) {
.release-card {
grid-template-columns: 1fr;
gap: 0.75rem;
padding: 1.5rem 0;
}
.release-meta {
position: static;
flex-direction: row;
align-items: center;
gap: 1rem;
}
}
</style>
+168
View File
@@ -0,0 +1,168 @@
// Source of truth for the Releases timeline. Newest first.
// Each entry should focus on user-facing features — leave routine
// bumps, lint fixes, and dependency updates out.
export interface Release {
version: string;
date: string; // ISO 8601 yyyy-mm-dd
headline: string;
highlights: string[];
}
export const releases: Release[] = [
{
version: "v3.7.1",
date: "2026-04-29",
headline: "Status page themes and a polished incidents page",
highlights: [
"Pick a theme for your public status page: Refined, Modern, Bold, or Editorial",
"Choose between light, dark, or auto theme modes",
"Polished incidents page with better filtering and grouping",
"New empty state for the infrastructure network view",
"Remove-monitors confirmation modal in settings",
],
},
{
version: "v3.6.1",
date: "2026-04-23",
headline: "Twilio SMS notifications and incident comments",
highlights: [
"Send incident alerts via SMS using Twilio",
"Resolve incidents with a comment so context is preserved",
"Login page no longer shows the register tip when registration is closed",
"Removed TimescaleDB dependency for a leaner deployment",
"New monitor-lifecycle documentation",
],
},
{
version: "v3.5.1",
date: "2026-03-06",
headline: "Uptime over WebSockets, Globalping ping, and team member removal",
highlights: [
"Real-time uptime updates over WebSockets — no more polling delays",
"Use Globalping as the engine for distributed ping monitors",
"Admins can remove team members from the team settings page",
"Fixed dark-mode background and several theme contrast issues",
],
},
{
version: "v3.5.0",
date: "2026-03-04",
headline: "SWR data layer and tightened validation",
highlights: [
"Global SWR-based data fetching for snappier navigation and automatic revalidation",
"Stricter server-side validation across all monitor types",
"Env-var validation surfaces misconfiguration at startup, not at first failure",
"Logs page improvements for easier debugging",
],
},
{
version: "v3.4.0",
date: "2026-02-20",
headline: "Settings refactor and status page access fixes",
highlights: [
"Settings UI rebuilt for clarity and consistency",
"Fixed access rules so unpublished status pages remain admin-only",
"Several caching fixes for fresher data after configuration changes",
],
},
{
version: "v3.3",
date: "2026-01-27",
headline: "PageSpeed v2 details and a faster uptime details page",
highlights: [
"Rebuilt PageSpeed details view with deeper Core Web Vitals breakdown",
"v2 uptime details page with denser charts and faster loading",
"Recent-checks endpoint redesigned for lower latency",
"PageSpeed tooltips clarify what each metric means",
],
},
{
version: "v3.2.0",
date: "2025-09-18",
headline: "Notification bodies and uptime % charts",
highlights: [
"Customise the body of email, Slack, Discord, and webhook notifications",
"Toggle between absolute uptime and uptime % on monitor charts",
"Sliding-window threshold evaluation for more stable status decisions",
"Skip-maintenance notifications no longer fire during maintenance windows",
],
},
{
version: "v3.1",
date: "2025-08-20",
headline: "N-of-M alert thresholds and PagerDuty",
highlights: [
"Alert only after N consecutive failures out of M checks — fewer flaky alerts",
"PagerDuty notification channel",
"Streamlined maintenance window creation flow",
"Network service refactor for more reliable cross-region checks",
],
},
{
version: "v2.3",
date: "2025-07-08",
headline: "Resolvable incidents and a cleaner incidents UI",
highlights: [
"Mark incidents as resolved from the UI with a single click",
"Redesigned incidents page with better grouping",
"Move the status-page delete action out of harm's way",
"Configurable behavior when no notifications are attached to a monitor",
],
},
{
version: "v2.2",
date: "2025-07-07",
headline: "Notification management and i18n polish",
highlights: [
"Delete notification channels with confirmation",
"Sorted translation keys for easier maintenance",
"Many small i18n fixes across pages",
],
},
{
version: "v2.1",
date: "2025-05-13",
headline: "Maintenance window improvements and form fixes",
highlights: [
"Settings update flow rebuilt",
"Fixed monitor resume / pause behavior",
"Better PageSpeed reliability",
"Infrastructure monitor filtering improvements",
"Conditional alert rendering during maintenance windows",
],
},
{
version: "v2.0",
date: "2024-12-04",
headline: "Major UI refresh and password security",
highlights: [
"Major frontend redesign with a refreshed theme",
"Improved password validation and error messages",
"Many fixes to incident detail views, colors, and responsiveness",
],
},
{
version: "v1.1.0",
date: "2024-10-11",
headline: "Maintenance windows and JWT-expiry handling",
highlights: [
"Schedule maintenance windows so checks don't fire false incidents",
"Auto-logout users when their JWT expires",
"Centralised backend error handling",
"Initial maintenance-page feature",
],
},
{
version: "v1.0",
date: "2024-09-23",
headline: "First public release",
highlights: [
"HTTP, ping, port, and PageSpeed monitors",
"Incident detection with email and Discord notifications",
"Public status pages",
"Team management with role-based access",
"Open source under the AGPL — self-host the entire stack",
],
},
];
+59
View File
@@ -0,0 +1,59 @@
---
import StarlightPage from "@astrojs/starlight/components/StarlightPage.astro";
import ReleaseCard from "../components/ReleaseCard.astro";
import { releases } from "../data/releases";
---
<StarlightPage
frontmatter={{
title: "Releases",
description: "What's new in Checkmate — every release with the most important features.",
template: "splash",
pagefind: false,
}}
>
<div class="releases-intro">
<p>
Every meaningful Checkmate release, newest first. For the
complete commit history, see the
<a href="https://github.com/bluewave-labs/Checkmate/releases" rel="noopener">GitHub releases page</a>.
</p>
</div>
<div class="releases-timeline">
{releases.map((release, index) => (
<ReleaseCard
version={release.version}
date={release.date}
headline={release.headline}
highlights={release.highlights}
isLatest={index === 0}
/>
))}
</div>
</StarlightPage>
<style>
.releases-intro {
max-width: 60ch;
margin: 0 0 2rem 0;
color: var(--sl-color-gray-3);
font-size: var(--sl-text-base);
line-height: 1.55;
}
.releases-intro a {
color: var(--sl-color-accent-high);
text-decoration: underline;
text-underline-offset: 2px;
}
.releases-timeline {
max-width: 56rem;
margin: 0;
}
:global([data-theme="light"]) .releases-intro {
color: var(--sl-color-gray-5);
}
</style>