Skip to content

feat(roadmap): /roadmap generated from the engine repo's GitHub milestones - #122

Merged
eaitbrahim merged 1 commit into
mainfrom
feat/roadmap-page
Aug 28, 2026
Merged

feat(roadmap): /roadmap generated from the engine repo's GitHub milestones#122
eaitbrahim merged 1 commit into
mainfrom
feat/roadmap-page

Conversation

@eaitbrahim

Copy link
Copy Markdown
Contributor

Closes #117

What

A generated Roadmap page — the page from Jesse's Resources menu, not the paid mechanism (no voting allowances, no accounts, no sponsorship queue). The keel repo's own milestones already are the roadmap and are actively maintained; the site reads them like it reads News: read-only presentation, interaction stays on GitHub.

How

  • scripts/fetch-milestones.mjs — new fetch pipeline alongside fetch-release.mjs / fetch-discussions.mjs: public REST endpoints, GITHUB_TOKEN honored when present, writes gitignored data/milestones.json. Open milestones (dated nearest-first, undated after — a milestone without a date is an intention, not a schedule) + the 5 most recently closed, each with title/description/state, open/closed issue counts, due_on/closed_at when set, and up to 30 issues/PRs (full counts travel along so the page can say "and N more on GitHub" instead of hiding overflow). Chained into npm run fetch in package.json.
  • /{en,ar,fr}/roadmap/ — page + component + i18n structure (src/i18n/pages/roadmap.ts, all revs 2026-08-28.1, translations fresh so translatedFromRev matches), roadmap PageKey, nav entry after Community (Header + ui.ts chrome ×3; the footer doesn't enumerate pages, checked).
  • Rendering — open → recently shipped; closed milestones marked shipped with GitHub's own closed_at; every item a plain link to its issue with an open/done marker and a PR chip; progress as "N of M items closed" straight from the repo's counts. No vote, no subscribe, no comment affordances.

Honesty (the issue's core requirement)

  • Intro says it once, plainly: an open milestone is an intention, not a commitment, and a date on one is a target, not a promise (FR-9: no features-promised-by-dates).
  • Undated milestones render "No date set" — never an invented date.
  • A doc-meta line notes the roadmap is read from the repo's GitHub milestones at build time and refreshes hourly.

Failure policy (same risk policy as News/Changelog)

A failed fetch never breaks the build:

  1. Network fine → data/milestones.json written (verified: 11 open + 5 recently closed).
  2. Fetch fails with last-known data present → keeps it (WARN: milestones fetch failed (simulated offline); keeping last-known 16 milestones).
  3. Fetch fails with no data → empty stub, page degrades to a plain link to the GitHub milestones page (dist verified: fallback copy renders, build exits 0).

Verification

  • npx astro check (fresh .astro cache): 0 errors, 0 warnings (5 pre-existing hints, none in new files); full npm run check passes.
  • npm run build: 63 pages; dist/{en,ar,fr}/roadmap/index.html all present with 104 unique issue links + 16 milestone links; hreflang alternates ×3.
  • Sitemap: https://keeltrading.com/{en,ar,fr}/roadmap/ present.
  • Degradation path tested by monkey-patching fetch to throw — both branches above exercised.
  • Mobile: puppeteer-core (Chrome, /Applications/Google Chrome.app/...) at 390px on /en/roadmap/ and /ar/roadmap/: scrollWidth 390 == viewport on both, zero horizontal overflow. The only off-viewport element is the site-wide .skip-link (off-screen by design; identical on /en/news/ and /en/community/).

Not done (on purpose)

  • No RSS/OG additions for roadmap (og script doesn't enumerate pages — checked).
  • Item cap 30/milestone and 5 closed milestones — enough for the repo's real shape (max milestone today holds 15 items) with honest overflow links.

…tones

Takes the page and not the mechanism from Jesse's Resources menu: the
keel repo's milestones already are the real roadmap and are actively
maintained, so the site reads them — no voting, no accounts, no
sponsorship queue, none of which exist for a 3-star project whose pitch
is that it tells you the truth.

- scripts/fetch-milestones.mjs reads open + recently closed milestones
  and their issues/PRs via the public REST endpoints (GITHUB_TOKEN
  honoured for rate-limit headroom), writing gitignored
  data/milestones.json; chained into the fetch script. Same failure
  policy as fetch-release/fetch-discussions: a failed fetch never breaks
  the build — it degrades to last-known data and finally to a plain link
  to the GitHub milestones page.
- /{en,ar,fr}/roadmap/ follows the page+component+i18n structure; nav
  entry after Community in all three locales. Milestones render open →
  recently shipped, every item links to its issue, closed milestones
  marked shipped with GitHub's own closed date.
- Honesty: an open milestone is an intention, not a commitment, and a
  due date is a target, not a promise (FR-9); undated milestones say
  "no date set" instead of inventing one; a doc-meta line notes the
  roadmap is read from the repo and refreshes hourly.

Closes #117
@sonarqubecloud

Copy link
Copy Markdown

@eaitbrahim
eaitbrahim merged commit 8cf15d6 into main Aug 28, 2026
2 checks passed
@eaitbrahim
eaitbrahim deleted the feat/roadmap-page branch August 28, 2026 23:55
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Roadmap page — generated from GitHub milestones, no voting, no accounts

1 participant