Skip to content
Draft
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
22 changes: 16 additions & 6 deletions .github/workflows/nextjs.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: CI / Deploy

on:
push:
branches: ["main"]
branches: ["main", "redesign"] # TEMP(redesign): "redesign" is fork-preview only — revert to ["main"] before upstream merge
pull_request:
branches: ["main"]
workflow_dispatch:
Expand Down Expand Up @@ -82,6 +82,11 @@ jobs:
${{ runner.os }}-nextjs-${{ hashFiles('**/package-lock.json') }}-
- run: npm ci
- run: npm run build
# TEMP(redesign): basePath for fork Pages preview at /mellea-website.
# On main this resolves to empty, so it is a no-op there. Remove this
# env block before upstream merge.
env:
NEXT_PUBLIC_BASE_PATH: ${{ github.ref == 'refs/heads/redesign' && '/mellea-website' || '' }}
- uses: actions/upload-artifact@v7
with:
name: website
Expand Down Expand Up @@ -113,12 +118,17 @@ jobs:
path: playwright-report/
retention-days: 7

# TEMP(redesign): preview deploy for the fork. Gated on build only —
# test-e2e and link-check still run and report status on the PR, but they
# assume root-path serving / a live URL and so don't fit an in-progress
# basePath preview. Before upstream merge, revert BOTH lines below to:
# needs: [test-unit, test-e2e, link-check]
# if: |
# github.ref == 'refs/heads/main' &&
# (needs.link-check.result == 'success' || needs.link-check.result == 'skipped')
deploy:
needs: [test-unit, test-e2e, link-check]
# Allow deploy when link-check was skipped via the override mechanisms above.
if: |
github.ref == 'refs/heads/main' &&
(needs.link-check.result == 'success' || needs.link-check.result == 'skipped')
needs: [test-unit, build]
if: github.ref == 'refs/heads/redesign'
runs-on: ubuntu-latest
environment:
name: github-pages
Expand Down
60 changes: 20 additions & 40 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,8 +10,6 @@ This is the **Next.js website** for Mellea — the landing page and developer bl

**Adding or editing a blog post** → go to [§ Adding Blog Posts](#8-adding-blog-posts). No dev environment, no code changes needed.

**Adding a news highlight** → go to [§ Adding News Items](#9-adding-news-items). No dev environment, no code changes needed.

**Changing the site** (UI, components, CI, dependencies) → read everything below.

---
Expand Down Expand Up @@ -40,7 +38,6 @@ npm run build # Static export to ./out/
| `src/lib/` | Server-side utilities (blog parsing, etc.) |
| `src/config/` | Site-wide configuration (`site.ts`) |
| `content/blogs/` | Markdown blog posts with YAML front matter |
| `content/news/` | Markdown news/highlights items with YAML front matter |
| `public/` | Static assets (images, CNAME) |
| `tests/unit/` | Vitest unit tests |
| `tests/e2e/` | Playwright E2E tests |
Expand All @@ -55,15 +52,28 @@ npm run build # Static export to ./out/
- No CSS modules, no Tailwind — all styles in `src/app/globals.css`
- `src/config/site.ts` is the single source of truth for URLs and repo slug

## 4. Attribution
## 4. AI Coding Assistants

AI-assisted development is welcome. You are responsible for reviewing and understanding every change before submitting.

AI coding assistants following project guidelines add an `Assisted-by:` trailer to commit messages by default, identifying which tool was used:

```text
Assisted-by: Claude Code
Assisted-by: IBM Bob
```

Do **not** add AI assistant attribution to commits, PRs, code, or documentation unless explicitly asked. No `Co-Authored-By` lines, no AI-generated footers.
Add one line per tool used, using its common name (GitHub Copilot, Cursor, etc.). Do not add `Co-Authored-By` lines for AI tools.

## 5. Commits

Plain descriptive messages: `fix: nav link selector in E2E tests`, `feat: add tags filter to blog listing`, `docs: update CONTRIBUTING.md`.
Follow [Angular commit format](https://github.com/angular/angular/blob/main/CONTRIBUTING.md#commit), matching the [mellea repo](https://github.com/generative-computing/mellea): `<type>: <subject>`, with an optional body and footer.

No Angular-style mandatory types required, but keep messages short and imperative.
**Types:** `feat`, `fix`, `docs`, `test`, `refactor`, `ci`, `chore`, `release`.

Examples: `fix: nav link selector in E2E tests`, `feat: add tags filter to blog listing`, `docs: update CONTRIBUTING.md`.

**Sign off every commit** with `git commit -s` (DCO is enforced in CI).

## 6. Pre-commit Checklist (mandatory — do not skip)

Expand Down Expand Up @@ -100,8 +110,8 @@ If you rename or remove a CSS class, check `tests/e2e/` for selectors that refer

### Data flow

- **Build-time** (Server Components): `getAllBlogs()` → landing page + blog listing; `getAllBlogSlugs()` + `getBlog(slug)` → individual post pages; `getAllNews()` → landing page news highlights
- **Client-side** (Client Components): GitHub API stats via `useGitHubStats` hook on mount; image compare slider via `react-compare-slider`
- **Build-time** (Server Components): `getAllBlogs()` → landing page + blog listing; `getAllBlogSlugs()` + `getBlog(slug)` → individual post pages
- **Client-side**: GitHub star count via the `GitHubStarsInit` component on mount; landing-page interactions (cursor, hero, compare slider, code panel) via vanilla ES modules in `public/js/`

### Styling

Expand Down Expand Up @@ -158,37 +168,7 @@ A workflow runs daily at ~9am Eastern and posts a reminder comment on the PR onc

Verify with `npm run build` — no config changes or code edits needed.

## 9. Adding News Items

Drop a `.md` file in `content/news/`. News items appear in the "Latest News" highlights strip on the landing page hero section, sorted by date descending. Unlike blog posts, news items link to an external URL (opened in a new tab) — they do not have their own page on the site.

Required front matter:

```md
---
title: "Short Headline"
date: "YYYY-MM-DD"
category: "Release"
excerpt: "One sentence description shown on the card."
url: "https://example.com/full-link"
source: "GitHub"
---
```

| Field | Required | Notes |
| ---------- | -------- | ---------------------------------------------------------------------------- |
| `title` | Yes | Short headline for the card |
| `date` | Yes | `YYYY-MM-DD`, used for sorting |
| `category` | Yes | One of: `Release`, `Event`, `Integration`, `Community`, `Feature` |
| `excerpt` | Yes | One sentence shown on the card |
| `url` | Yes | External link (must be a full URL) |
| `source` | No | Display label for the link (e.g. "GitHub", "PyCon"); defaults to "Read more" |

The `category` field controls the visual styling — each category gets a distinct accent color on the card's left border and category badge. No markdown body content is needed (only frontmatter is used).

Verify with `npm run build` — no config changes or code edits needed.

## 10. Common Issues
## 9. Common Issues

| Problem | Fix |
| --- | --- |
Expand Down
74 changes: 4 additions & 70 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
@@ -1,9 +1,8 @@
# Contributing

There are three ways to contribute:
There are two ways to contribute:

- **Writing a blog post** — add a Markdown file and verify it renders. [Jump to that section.](#adding-a-blog-post)
- **Adding a news highlight** — add a short Markdown file to surface events, releases, or features. [Jump to that section.](#adding-a-news-item)
- **Changing the site** — UI, CI, or dependencies. Requires a full dev setup. [Jump to that section.](#development-setup)

All contributions must be signed off under the [Developer Certificate of Origin](#developer-certificate-of-origin-dco) — use `git commit -s` on every commit.
Expand Down Expand Up @@ -80,74 +79,9 @@ No config changes or code edits are needed — just the Markdown file and any im

---

## Adding a news item

News items are short highlights that appear on the landing page to draw attention to things that matter to users — upcoming events (conferences, meetups, webinars), new releases, notable integrations or features, community milestones, or any other timely announcement. Unlike blog posts, news items link out to an external URL and do not have their own page on the site.

### Steps

1. Fork the repository.

2. Create a new file in `content/news/news-n.md`.
The filename is internal only (not a public URL), to make it easier and only update the frontmatter content, keep the name pattern to `news-n.md`.

3. Fill in the YAML front matter:

```md
---
title: "Short Headline"
date: "YYYY-MM-DD"
category: "Release"
excerpt: "One sentence description shown on the card."
url: "https://example.com/full-link"
source: "GitHub"
---
```

No markdown body content is needed — only the front matter is used.

4. Verify locally:

```bash
npm install
npm run build # must succeed with no errors
npm run dev # check the landing page at http://localhost:4000
```

5. Open a PR against `main`. A member of the **mellea-maintainers** team must approve before merge.

6. Once merged, the news item will appear in the "Latest News" section on the landing page within a few minutes.

### News front matter fields

| Field | Required | Description |
| ---------- | -------- | ---------------------------------------------------------------------------- |
| `title` | Yes | Short headline for the card |
| `date` | Yes | Date (`YYYY-MM-DD`), used for sort order |
| `category` | Yes | One of: `Release`, `Event`, `Integration`, `Community`, `Feature` |
| `excerpt` | Yes | One sentence shown on the card |
| `url` | Yes | External link target (must be a full URL starting with `https://`) |
| `source` | No | Label shown on the link (e.g. "GitHub", "PyCon"); defaults to "Read more" |

### Categories

Each category gets a distinct accent color on the card to help users scan at a glance:

| Category | Color | Use for |
| ------------- | ------ | ---------------------------------------------- |
| `Release` | Blue | New versions, changelogs |
| `Event` | Green | Conferences, meetups, webinars |
| `Integration` | Purple | New framework or tool integrations |
| `Community` | Cyan | Community milestones, spotlights |
| `Feature` | Blue | Notable new capabilities |

No config changes or code edits are needed — just the Markdown file.

---

## Developer Certificate of Origin (DCO)

All contributions to this repository — blog posts, news items, and code changes —
All contributions to this repository — blog posts and code changes —
must be signed off under the [Developer Certificate of Origin](https://developercertificate.org/),
which certifies that you have the right to submit your work under the project's
license. By signing off on a commit, you are agreeing to the terms of the DCO
Expand Down Expand Up @@ -311,7 +245,7 @@ On E2E failure, a `playwright-report` artifact is uploaded to the GitHub Actions
### Key constraints

- No `next/headers`, no route handlers, no server actions
- `Image` component uses `unoptimized: true` (required for static export)
- `images.unoptimized: true` is set in `next.config.mjs` (required for static export); components use plain `<img>` rather than `next/image`
- `trailingSlash: true` is set in `next.config.mjs`
- Blog data fetching uses Node.js `fs` inside Server Components only — `src/lib/blogs.ts` is **not** safe to import in Client Components

Expand All @@ -321,4 +255,4 @@ On E2E failure, a `playwright-report` artifact is uploaded to the GitHub Actions

### Styling

Single global CSS file: `src/app/globals.css`. IBM Plex fonts via Google Fonts. Dark/light theme via CSS custom properties and `@media (prefers-color-scheme: light)`. No CSS modules, no Tailwind.
Stylesheets under `public/css/` (`styles.css` plus `code-theme.css` for syntax highlighting), linked from `src/app/layout.tsx`. Self-hosted fonts (Aileron + JetBrains Mono) via `public/assets/fonts.css`. Light theme only (no dark mode / `prefers-color-scheme`). No CSS modules, no Tailwind. Landing-page interactions are plain ES modules in `public/js/`.
99 changes: 99 additions & 0 deletions REDESIGN-NOTES.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,99 @@
<!-- markdownlint-disable -->
# Redesign Branch Notes

This branch (`redesign`) on the fork `ajbozarth/mellea-website` hosts the new
site implementation that will replace the current code wholesale. It also serves
a **live preview** via GitHub Pages at:

> https://ajbozarth.github.io/mellea-website/

This doc tracks three things:

1. **Keep-list** — content/config that must survive the rewrite (do NOT delete).
2. **Revert-list** — temporary fork-preview hacks that must be undone before the
work is merged back upstream.
3. **Access & deploy** — how teammates push here and how the preview deploys.

---

## 1. Keep-list — files the rewrite must preserve

The redesign replaces the **site code** (`src/`, build/test config tied to the
current implementation). The following is **not** site code and must remain so
the new site keeps its content, assets, and CI:

| Path | Why it must stay |
|------|------------------|
| `content/blogs/` | ⭐ The entire editorial corpus — 17 blog posts. Irreplaceable. |
| `public/images/` | Images referenced by blog markdown via `/images/...`. Losing these breaks posts. |
| `public/llms.txt` | LLM crawler manifest (SEO). |
| `public/robots.txt` | Crawler rules. |
| `public/CNAME.sav` | Stashed upstream custom domain — restore to `CNAME` before upstream merge (see revert-list). |
| `public/mellea-logo.svg` / `.png` (under `public/images/`) | Brand assets used across content. |
| `templates/blog-post.md` | Blog authoring template that `AGENTS.md` directs authors to. |
| `lychee.toml` | Link-check config consumed by CI (`nextjs.yml`). |
| `.markdownlint-cli2.jsonc` | Markdown lint config used by `npm run lint:md` in CI. |
| `.github/` (workflows, CODEOWNERS, public templates) | CI + repo governance. *(author already aware)* |
| Root `*.md` — `README.md`, `AGENTS.md`, `CLAUDE.md`, `CONTRIBUTING.md`, `LICENSE` | Project docs/license. *(author already aware)* |

> Note: the new implementation is free to **change how `content/` is consumed**
> (loader, rendering, routing) — but the markdown and image files themselves
> must carry over intact. If image paths change, every blog's `/images/...`
> reference has to be updated in lockstep.

---

## 2. Revert-list — temporary fork-preview changes

These edits exist ONLY to serve the preview from this fork. They must be undone
before `redesign` is merged into upstream `generative-computing/mellea-website`.
Each is tagged with a `TEMP(redesign):` comment in the source.

| File | Change | Revert to |
|------|--------|-----------|
| `.github/workflows/nextjs.yml` | `push.branches` includes `"redesign"` | `["main"]` |
| `.github/workflows/nextjs.yml` | `build` step has `NEXT_PUBLIC_BASE_PATH` env block | remove the `env:` block (it is a no-op on main, but should not ship) |
| `.github/workflows/nextjs.yml` | `deploy` job `needs: [test-unit, build]` and gate `github.ref == 'refs/heads/redesign'` | restore `needs: [test-unit, test-e2e, link-check]` and the original main-gated `if` (full snippet is in the `TEMP(redesign)` comment above the job) |

> **Why deploy isn't gated on `test-e2e` / `link-check` on this branch:** the
> preview build uses `basePath=/mellea-website`, but the e2e tests serve `out/`
> at the server root and assert the *current* site's structure — so they 404 /
> fail against both the basePath and the upcoming wholesale rewrite. `link-check`
> also flags the preview URL until the first deploy publishes it. Both jobs still
> **run and report status on the PR**; they just don't block the preview. They
> return to blocking the deploy on `main` after the revert.
| `public/CNAME` → `public/CNAME.sav` | Renamed so Pages ignores it (the `mellea.ai` custom domain belongs to upstream and only works there) | `git mv public/CNAME.sav public/CNAME` before upstream merge |

Quick check before merging upstream:

```bash
grep -rn "TEMP(redesign)" .github/ # should return nothing after revert
git diff upstream/main -- .github/workflows/nextjs.yml public/CNAME
```

---

## 3. Access & deploy

### Teammate push access
Teammates are maintainers on **upstream**, which grants no access to this
personal fork. Access to this branch is granted via the **draft upstream PR**
(`ajbozarth:redesign` → `generative-computing:main`) with **"Allow edits by
maintainers"** enabled. That lets any upstream-write maintainer push directly to
`redesign` on this fork while the PR is open.

Push target for teammates:

```bash
git push https://github.com/ajbozarth/mellea-website.git HEAD:redesign
```

(Access ends when the PR is closed. Works only because the fork is owned by a
personal account.)

### Deploy
- Pushing to `redesign` runs `nextjs.yml`, which builds with
`NEXT_PUBLIC_BASE_PATH=/mellea-website` and deploys to GitHub Pages on the fork.
- The upstream PR's own checks run lint/build/tests but do **not** deploy
(fork PRs get a read-only token; the deploy gate also excludes PR refs).
- Preview URL: https://ajbozarth.github.io/mellea-website/
8 changes: 0 additions & 8 deletions content/news/news-1.md

This file was deleted.

8 changes: 0 additions & 8 deletions content/news/news-2.md

This file was deleted.

8 changes: 0 additions & 8 deletions content/news/news-3.md

This file was deleted.

Loading
Loading