Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
85 changes: 85 additions & 0 deletions docs/introduction/cloudberry-history.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
---
title: Project History
---

import Timeline from "@site/src/components/common/Timeline";

# Apache Cloudberry Project History

This page chronicles the key milestones in the development of Apache Cloudberry, from its origins to the present day.

## Timeline

export const history = [
{
date: "May 2026",
title: "PostgreSQL 16.9 Kernel Upgrade",
description:
"The main branch upgraded the PostgreSQL kernel from 14.4 to PostgreSQL 16.9, bringing the modern PostgreSQL features, performance improvements, and security fixes to the MPP platform.",
links: [
{ label: "Announcement", url: "/blog/postgresql16-for-apache-cloudberry-202606" },
],
},
{
date: "April 2026",
title: "Apache Cloudberry (Incubating) 2.1.0 Released",
description:
"Version 2.1.0 was released, continuing the release momentum within the Apache Incubator with further enhancements and community contributions.",
links: [
{ label: "2.1 Preview", url: "/blog/apache-cloudberry-2.1.0-preview" },
{ label: "Announcement", url: "/blog/announce-apache-cloudberry-2.1.0" },
{ label: "Changelog", url: "/releases/2.1.0-incubating" },
],
},
{
date: "July 2025",
title: "First Apache Release — v2.0.0",
description:
"Apache Cloudberry (Incubating) 2.0.0 was released, marking the first official Apache Release and establishing the project's release process under Apache governance.",
links: [
{ label: "2.0 Preview", url: "/blog/apache-cloudberry-2.0-preview-key-features-and-improvements-ahead" },
{ label: "Announcement", url: "/blog/announce-apache-cloudberry-2.0.0" },
{ label: "What's New", url: "/blog/whats-new-in-apache-cloudberry-2.0.0" },
{ label: "Changelog", url: "/releases/2.0.0-incubating" },
],
},
{
date: "October 2024",
title: "Joined the Apache Incubator",
description:
"Cloudberry Database was voted into the Apache Incubator, rebranded as Apache Cloudberry, and began its incubation journey under the umbrella of the Apache Software Foundation Incubator.",
links: [
{ label: "Announcement", url: "/blog/cloudberry-database-enters-the-apache-incubator" },
],
},
{
date: "May 2024",
title: "Greenplum Database Went Closed-Source",
description:
"Greenplum Database archived its GitHub repository and went closed-source. This event cemented Apache Cloudberry's role as the open-source successor continuing the PostgreSQL-based MPP database lineage.",
},
{
date: "June 2023",
title: "Cloudberry Database Open-Sourced",
description:
"Cloudberry Database was officially open-sourced, inviting the global developer community to participate, contribute, and build together.",
},
{
date: "June 2022",
title: "Project Launched",
description:
"HashData launched the Cloudberry Database project, derived from Greenplum Database 7. The team upgraded the PostgreSQL kernel from 12.x to 14.4, laying a modern foundation for the future.",
},
];

<Timeline items={history} reversed />

## Incubation Reports

Apache Cloudberry submits regular incubation reports to the Apache Incubator PMC. These reports provide detailed updates on community growth, release progress, and project maturity.

- [May 2026](/blog/apache-cloudberry-incubation-report-202605)
- [February 2026](/blog/apache-cloudberry-incubation-report-202602)
- [November 2025](/blog/apache-cloudberry-incubation-report-202511)
- [August 2025](/blog/apache-cloudberry-incubation-report-202508)
- [May 2025](/blog/apache-cloudberry-incubation-report-202505)
2 changes: 1 addition & 1 deletion sidebars.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ const sidebars: SidebarsConfig = {
{
type: 'category',
label: 'Introduction',
items: ['introduction/cbdb-overview', 'introduction/cbdb-architecture', 'introduction/cbdb-scenarios', 'introduction/cbdb-vs-gp-features']
items: ['introduction/cbdb-overview', 'introduction/cbdb-architecture', 'introduction/cbdb-scenarios', 'introduction/cbdb-vs-gp-features', 'introduction/cloudberry-history']
},

{
Expand Down
78 changes: 78 additions & 0 deletions src/components/common/Timeline/index.tsx
Original file line number Diff line number Diff line change
@@ -0,0 +1,78 @@
import React from "react";
import styles from "./styles.module.scss";

export interface TimelineLink {
/** Link label shown to the user */
label: string;
/** Target URL (internal path like /blog/... or full URL) */
url: string;
}

export interface TimelineItem {
/** Display date, e.g. "June 2022" */
date: string;
/** Event title */
title: string;
/** Short description */
description: string;
/** Optional reference links shown below the description */
links?: TimelineLink[];
}

interface TimelineProps {
items: TimelineItem[];
/** When true, the first item is treated as the latest (pulse animation).
* Default: last item is latest (chronological order). */
reversed?: boolean;
}

export default function Timeline({ items, reversed }: TimelineProps) {
if (!items || items.length === 0) {
return null;
}

const lastIndex = items.length - 1;

return (
<div className={styles.timeline}>
{items.map((item, index) => {
const isLast = index === lastIndex;
const isLatest = reversed ? index === 0 : index === lastIndex;

return (
<div key={index} className={styles.item}>
{/* Marker column: dot + connecting line */}
<div className={styles.marker}>
<div
className={`${styles.dot} ${isLatest ? styles.dotLatest : ""}`}
/>
{!isLast && <div className={styles.line} />}
</div>

{/* Content column */}
<div className={styles.content}>
<time className={styles.date}>{item.date}</time>
<h3 className={styles.title}>{item.title}</h3>
<p className={styles.desc}>{item.description}</p>
{item.links && item.links.length > 0 && (
<div className={styles.links}>
{item.links.map((link, li) => (
<a
key={li}
href={link.url}
className={styles.link}
target="_blank"
rel="noopener noreferrer"
>
{link.label}
</a>
))}
</div>
)}
</div>
</div>
);
})}
</div>
);
}
165 changes: 165 additions & 0 deletions src/components/common/Timeline/styles.module.scss
Original file line number Diff line number Diff line change
@@ -0,0 +1,165 @@
/* ------------------------------------------------------------------ */
/* Timeline — vertical milestone timeline */
/* ------------------------------------------------------------------ */

.timeline {
margin: 2.5rem 0;
}

/* ---- Row: marker + content -------------------------------------- */
.item {
display: flex;
gap: 28px;

&:hover .dot {
transform: scale(1.35);
box-shadow: 0 0 0 6px rgba(255, 89, 0, 0.18);
}
}

/* ---- Marker (dot + line) ---------------------------------------- */
.marker {
display: flex;
flex-direction: column;
align-items: center;
width: 20px;
flex-shrink: 0;
}

.dot {
width: 16px;
height: 16px;
border-radius: 50%;
background: var(--brand-orange-deep);
border: 3px solid var(--color-bg);
flex-shrink: 0;
margin-top: 5px;
z-index: 1;
transition: transform 0.3s ease, box-shadow 0.3s ease;
}

.dotLatest {
animation: dotPulse 2.2s ease-in-out infinite;
box-shadow: 0 0 0 0 rgba(255, 89, 0, 0.45);
}

@keyframes dotPulse {
0% {
box-shadow: 0 0 0 0 rgba(255, 89, 0, 0.45);
}
70% {
box-shadow: 0 0 0 10px rgba(255, 89, 0, 0);
}
100% {
box-shadow: 0 0 0 0 rgba(255, 89, 0, 0);
}
}

.line {
width: 2px;
flex: 1;
min-height: 28px;
background: linear-gradient(
to bottom,
var(--brand-orange-deep) 0%,
var(--color-border) 20%
);
margin-top: 6px;
border-radius: 1px;
}

/* ---- Content ---------------------------------------------------- */
.content {
flex: 1;
padding-bottom: 40px;
}

.date {
display: inline-block;
font-family: var(--font-family-mono);
font-size: 0.8125rem;
font-weight: 600;
color: var(--color-accent);
text-transform: uppercase;
letter-spacing: 0.06em;
margin-bottom: 6px;
}

.title {
font-family: var(--font-family-display);
font-size: 1.125rem;
font-weight: 700;
line-height: 1.35;
color: var(--color-text);
margin: 0 0 8px 0;
}

.desc {
font-size: 0.9375rem;
line-height: 1.7;
color: var(--color-text-muted);
margin: 0;
max-width: 640px;
}

/* ---- Reference links ------------------------------------------- */
.links {
display: flex;
flex-wrap: wrap;
gap: 12px;
margin-top: 12px;
}

.link {
font-size: 0.8125rem;
font-weight: 500;
color: var(--color-accent);
text-decoration: underline;
text-decoration-thickness: 1px;
text-underline-offset: 2px;
transition: color var(--motion-fast);

&:hover {
color: var(--color-accent-hover);
text-decoration-thickness: 2px;
}
}

/* ---- Dark-mode overrides --------------------------------------- */
html[data-theme="dark"] {
.dot {
/* Match the surface color so the border ring blends in */
border-color: var(--color-bg);
}
}

/* ---- Accessibility: reduce motion ------------------------------ */
@media (prefers-reduced-motion: reduce) {
.dot {
transition: none;
}

.dotLatest {
animation: none;
box-shadow: 0 0 0 4px rgba(255, 89, 0, 0.25);
}
}

/* ---- Responsive ------------------------------------------------- */
@media (max-width: 768px) {
.item {
gap: 18px;
}

.content {
padding-bottom: 28px;
}

.title {
font-size: 1rem;
}

.desc {
font-size: 0.875rem;
}
}
Loading
Loading