feat: add react-markdown dependency and update README with release process
This commit is contained in:
21
CHANGELOG.md
Normal file
21
CHANGELOG.md
Normal file
@@ -0,0 +1,21 @@
|
|||||||
|
# Changelog
|
||||||
|
|
||||||
|
All notable changes to Pulse (frontend and product) are documented in this file.
|
||||||
|
|
||||||
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/), and Pulse uses [Semantic Versioning](https://semver.org/spec/v2.0.0.html) with a **0.x.y** version scheme while in initial development. The leading `0` indicates that the public API and behaviour may change until we release **1.0.0**.
|
||||||
|
|
||||||
|
## [Unreleased]
|
||||||
|
|
||||||
|
- No unreleased changes yet; add items here as you work toward the next release.
|
||||||
|
|
||||||
|
## [0.1.0] - 2026-02-09
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Initial changelog and release process (PULSE-28).
|
||||||
|
- Release documentation in `docs/releasing.md` and optional changelog check script.
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
[Unreleased]: https://github.com/ciphera-net/pulse/compare/v0.1.0...HEAD
|
||||||
|
[0.1.0]: https://github.com/ciphera-net/pulse/releases/tag/v0.1.0
|
||||||
@@ -60,6 +60,10 @@ npm run build
|
|||||||
npm start
|
npm start
|
||||||
```
|
```
|
||||||
|
|
||||||
|
## Releasing
|
||||||
|
|
||||||
|
Changelog and release process (who updates it, when, how to tag, deploy) are documented in [docs/releasing.md](docs/releasing.md). Versions use **0.x.y** while in initial development; the single product changelog is [CHANGELOG.md](CHANGELOG.md).
|
||||||
|
|
||||||
## Design System
|
## Design System
|
||||||
|
|
||||||
The frontend follows the Ciphera design language:
|
The frontend follows the Ciphera design language:
|
||||||
|
|||||||
46
app/changelog/page.tsx
Normal file
46
app/changelog/page.tsx
Normal file
@@ -0,0 +1,46 @@
|
|||||||
|
import fs from 'fs'
|
||||||
|
import path from 'path'
|
||||||
|
import ReactMarkdown from 'react-markdown'
|
||||||
|
import type { Metadata } from 'next'
|
||||||
|
|
||||||
|
export const metadata: Metadata = {
|
||||||
|
title: 'Changelog - Pulse',
|
||||||
|
description: 'Release history and notable changes for Pulse, privacy-first web analytics.',
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Reads CHANGELOG.md from the project root and renders it on the /changelog page.
|
||||||
|
* Content is loaded at build time; redeploy to show new releases.
|
||||||
|
*/
|
||||||
|
export default function ChangelogPage() {
|
||||||
|
const changelogPath = path.join(process.cwd(), 'CHANGELOG.md')
|
||||||
|
const content = fs.readFileSync(changelogPath, 'utf-8')
|
||||||
|
|
||||||
|
return (
|
||||||
|
<div className="mx-auto max-w-3xl px-4 sm:px-6 py-8">
|
||||||
|
<h1 className="text-3xl font-bold text-neutral-900 dark:text-white mb-2">
|
||||||
|
Changelog
|
||||||
|
</h1>
|
||||||
|
<p className="text-neutral-600 dark:text-neutral-400 mb-8 text-sm">
|
||||||
|
Release history and notable changes. We use{' '}
|
||||||
|
<a
|
||||||
|
href="https://keepachangelog.com/en/1.1.0/"
|
||||||
|
target="_blank"
|
||||||
|
rel="noopener noreferrer"
|
||||||
|
className="text-brand-orange hover:underline"
|
||||||
|
>
|
||||||
|
Keep a Changelog
|
||||||
|
</a>{' '}
|
||||||
|
and <strong>0.x.y</strong> versioning while in initial development.
|
||||||
|
</p>
|
||||||
|
<article
|
||||||
|
className="prose prose-neutral dark:prose-invert max-w-none
|
||||||
|
prose-headings:font-semibold prose-headings:tracking-tight
|
||||||
|
prose-a:text-brand-orange prose-a:no-underline hover:prose-a:underline
|
||||||
|
prose-ul:my-4 prose-li:my-0.5"
|
||||||
|
>
|
||||||
|
<ReactMarkdown>{content}</ReactMarkdown>
|
||||||
|
</article>
|
||||||
|
</div>
|
||||||
|
)
|
||||||
|
}
|
||||||
@@ -26,6 +26,7 @@ const footerLinks = {
|
|||||||
{ name: 'Contact', href: 'https://ciphera.net/contact', external: true },
|
{ name: 'Contact', href: 'https://ciphera.net/contact', external: true },
|
||||||
],
|
],
|
||||||
resources: [
|
resources: [
|
||||||
|
{ name: 'Changelog', href: '/changelog', external: false },
|
||||||
{ name: 'Installation', href: '/installation', external: false },
|
{ name: 'Installation', href: '/installation', external: false },
|
||||||
{ name: 'Integrations', href: '/integrations', external: false },
|
{ name: 'Integrations', href: '/integrations', external: false },
|
||||||
{ name: 'Documentation', href: 'https://docs.ciphera.net', external: true },
|
{ name: 'Documentation', href: 'https://docs.ciphera.net', external: true },
|
||||||
@@ -55,6 +56,9 @@ export function Footer({ LinkComponent = Link, appName = 'Pulse', isAuthenticate
|
|||||||
<Component href="/about" className="hover:text-brand-orange transition-colors focus:outline-none focus:ring-2 focus:ring-brand-orange focus:rounded">
|
<Component href="/about" className="hover:text-brand-orange transition-colors focus:outline-none focus:ring-2 focus:ring-brand-orange focus:rounded">
|
||||||
Why {appName}
|
Why {appName}
|
||||||
</Component>
|
</Component>
|
||||||
|
<Component href="/changelog" className="hover:text-brand-orange transition-colors focus:outline-none focus:ring-2 focus:ring-brand-orange focus:rounded">
|
||||||
|
Changelog
|
||||||
|
</Component>
|
||||||
<Component href="/pricing" className="hover:text-brand-orange transition-colors focus:outline-none focus:ring-2 focus:ring-brand-orange focus:rounded">
|
<Component href="/pricing" className="hover:text-brand-orange transition-colors focus:outline-none focus:ring-2 focus:ring-brand-orange focus:rounded">
|
||||||
Pricing
|
Pricing
|
||||||
</Component>
|
</Component>
|
||||||
|
|||||||
54
docs/releasing.md
Normal file
54
docs/releasing.md
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
# Releasing Pulse
|
||||||
|
|
||||||
|
This document describes how to cut a release for Pulse (changelog, tagging, and deploy). It applies to the **pulse-frontend** repo (GitHub: [ciphera-net/pulse](https://github.com/ciphera-net/pulse)). The backend (pulse-backend) can be tagged separately if you version it; the single product changelog lives here.
|
||||||
|
|
||||||
|
## Who updates the changelog
|
||||||
|
|
||||||
|
The person cutting the release (or the PR author merging the release PR) is responsible for updating `CHANGELOG.md` before the tag is created. No release tag should be pushed without a corresponding changelog entry.
|
||||||
|
|
||||||
|
## When to update
|
||||||
|
|
||||||
|
- **Before** creating the git tag for the release.
|
||||||
|
- Move items from the `[Unreleased]` section into a new version section (e.g. `[0.2.0] - YYYY-MM-DD`), then clear or repopulate `[Unreleased]` as needed.
|
||||||
|
- Update the comparison links at the bottom of `CHANGELOG.md` (e.g. add `[0.2.0]: ...` and set `[Unreleased]` to `compare/v0.2.0...HEAD`).
|
||||||
|
|
||||||
|
## Version numbering (0.x.y)
|
||||||
|
|
||||||
|
While Pulse is in initial development we use **0.x.y**:
|
||||||
|
|
||||||
|
- **0** = initial development; we may change behaviour or “API” without a new major version.
|
||||||
|
- **x** (minor) = new features or small breaking changes; bump for a release that adds functionality.
|
||||||
|
- **y** (patch) = bug fixes only; bump for a release that only fixes bugs.
|
||||||
|
|
||||||
|
When we are ready to commit to stability we release **1.0.0** and then follow strict [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
||||||
|
|
||||||
|
## How to tag a release
|
||||||
|
|
||||||
|
1. Ensure `CHANGELOG.md` has an entry for the new version (see **When to update** above).
|
||||||
|
2. (Optional) Run the changelog check so the version in the tag matches an entry in the changelog:
|
||||||
|
```bash
|
||||||
|
./scripts/check-changelog.sh 0.2.0
|
||||||
|
```
|
||||||
|
3. Commit any changelog (and link) updates, merge to the target branch (usually `main` for production).
|
||||||
|
4. Create an annotated tag (use the same version as in the changelog, with a `v` prefix):
|
||||||
|
```bash
|
||||||
|
git tag -a v0.2.0 -m "Release 0.2.0"
|
||||||
|
git push origin v0.2.0
|
||||||
|
```
|
||||||
|
|
||||||
|
Use the same version number in the tag as in the changelog (e.g. `v0.2.0` ↔ `[0.2.0]`).
|
||||||
|
|
||||||
|
## Deploy (staging and production)
|
||||||
|
|
||||||
|
- **Staging:** Push to the `staging` branch; Coolify deploys from `staging` to the staging environment.
|
||||||
|
- **Production:** Only the `main` branch is deployed to production. Merge `staging` → `main` when ready, then push. Tagging (e.g. `v0.2.0`) is done from `main` after the release commit is merged; Coolify auto-deploys on push to `main`.
|
||||||
|
|
||||||
|
So the usual flow is: merge release work (including changelog) to `main`, then create and push the tag from `main`.
|
||||||
|
|
||||||
|
## Checklist for each release
|
||||||
|
|
||||||
|
- [ ] Changelog updated: new version section with date, and `[Unreleased]` updated.
|
||||||
|
- [ ] Bottom-of-file comparison links updated in `CHANGELOG.md`.
|
||||||
|
- [ ] (Optional) `./scripts/check-changelog.sh <version>` passes.
|
||||||
|
- [ ] Changes merged to `main`.
|
||||||
|
- [ ] Tag created and pushed: `git tag -a vX.Y.Z -m "Release X.Y.Z"` then `git push origin vX.Y.Z`.
|
||||||
1177
package-lock.json
generated
1177
package-lock.json
generated
File diff suppressed because it is too large
Load Diff
@@ -24,6 +24,7 @@
|
|||||||
"react": "^19.2.3",
|
"react": "^19.2.3",
|
||||||
"react-dom": "^19.2.3",
|
"react-dom": "^19.2.3",
|
||||||
"react-icons": "^5.5.0",
|
"react-icons": "^5.5.0",
|
||||||
|
"react-markdown": "^10.1.0",
|
||||||
"react-simple-maps": "^3.0.0",
|
"react-simple-maps": "^3.0.0",
|
||||||
"recharts": "^2.15.0",
|
"recharts": "^2.15.0",
|
||||||
"sonner": "^2.0.7",
|
"sonner": "^2.0.7",
|
||||||
|
|||||||
31
scripts/check-changelog.sh
Executable file
31
scripts/check-changelog.sh
Executable file
@@ -0,0 +1,31 @@
|
|||||||
|
#!/usr/bin/env bash
|
||||||
|
# * Verifies that CHANGELOG.md has an entry for the given version (e.g. 0.1.0 or v0.1.0).
|
||||||
|
# * Use before tagging a release; can be wired into CI.
|
||||||
|
# * Usage: ./scripts/check-changelog.sh <version>
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
VERSION="${1:-}"
|
||||||
|
CHANGELOG="${CHANGELOG:-CHANGELOG.md}"
|
||||||
|
|
||||||
|
if [ -z "$VERSION" ]; then
|
||||||
|
echo "Usage: $0 <version> (e.g. 0.1.0 or v0.1.0)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Strip leading 'v' if present for consistent matching
|
||||||
|
NORMALIZED="${VERSION#v}"
|
||||||
|
|
||||||
|
if [ ! -f "$CHANGELOG" ]; then
|
||||||
|
echo "Error: $CHANGELOG not found (run from repo root)" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Keep a Changelog style: ## [1.0.0] or ## [1.0.0] - 2026-02-09
|
||||||
|
if grep -qE "^## \[${NORMALIZED}\]" "$CHANGELOG"; then
|
||||||
|
echo "OK: CHANGELOG has an entry for version $NORMALIZED"
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo "Error: CHANGELOG.md has no entry for version $NORMALIZED (expected a line like '## [$NORMALIZED] - YYYY-MM-DD')" >&2
|
||||||
|
exit 1
|
||||||
Reference in New Issue
Block a user