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:
1 parent
9aa2594df7
commit
e69f40fdd0
5 files changed
+400
No files matched your search
@@ -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>
|
||||
@@ -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>
|
||||
@@ -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",
|
||||
],
|
||||
},
|
||||
];
|
||||
@@ -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>
|
||||
Reference in new issue
Block a user