diff --git a/.github/scripts/build-roadmap.mjs b/.github/scripts/build-roadmap.mjs deleted file mode 100644 index b82f05d..0000000 --- a/.github/scripts/build-roadmap.mjs +++ /dev/null @@ -1,63 +0,0 @@ -// Fetches open issues from the public repo and writes a static snapshot to -// web/public/roadmap.json. Shape matches the old /api/roadmap response so the -// /roadmap page can read the static file with no runtime token or rate limit. -// -// Run in CI (uses the built-in GITHUB_TOKEN) or locally: -// GITHUB_TOKEN=ghp_xxx node .github/scripts/build-roadmap.mjs -import { writeFile, mkdir } from "node:fs/promises"; -import { dirname, resolve } from "node:path"; - -const REPO = process.env.ROADMAP_REPO || "engmung/PatternFlow"; -const PER_PAGE = 30; -const OUT = resolve(process.cwd(), "web/public/roadmap.json"); - -const headers = { - Accept: "application/vnd.github+json", - "X-GitHub-Api-Version": "2022-11-28", - "User-Agent": "patternflow-roadmap-snapshot", -}; -if (process.env.GITHUB_TOKEN) { - headers.Authorization = `Bearer ${process.env.GITHUB_TOKEN}`; -} - -const res = await fetch( - `https://api.github.com/repos/${REPO}/issues?state=open&per_page=${PER_PAGE}&sort=updated&direction=desc`, - { headers }, -); -if (!res.ok) { - throw new Error(`GitHub responded ${res.status}: ${await res.text()}`); -} - -const raw = await res.json(); -const issues = raw - // The issues endpoint also returns pull requests — drop them. - .filter((item) => !item.pull_request) - .map((item) => ({ - number: item.number, - title: item.title, - url: item.html_url, - state: item.state, - updatedAt: item.updated_at, - comments: item.comments, - labels: (item.labels ?? []) - .map((label) => - typeof label === "string" - ? { name: label, color: "888888" } - : { name: label.name, color: label.color || "888888" }, - ) - .filter((label) => label.name), - subIssues: - item.sub_issues_summary && item.sub_issues_summary.total > 0 - ? { - total: item.sub_issues_summary.total, - completed: item.sub_issues_summary.completed, - percent: item.sub_issues_summary.percent_completed, - } - : null, - })); - -const payload = { repo: REPO, fetchedAt: new Date().toISOString(), issues }; - -await mkdir(dirname(OUT), { recursive: true }); -await writeFile(OUT, JSON.stringify(payload, null, 2) + "\n"); -console.log(`Wrote ${issues.length} issues to ${OUT}`); diff --git a/.github/workflows/roadmap-snapshot.yml b/.github/workflows/roadmap-snapshot.yml deleted file mode 100644 index 0cb0e2b..0000000 --- a/.github/workflows/roadmap-snapshot.yml +++ /dev/null @@ -1,45 +0,0 @@ -name: Roadmap snapshot - -# Regenerates web/public/roadmap.json from open issues so the /roadmap page -# reads a static file (no runtime GitHub token, no rate limit). Runs every few -# hours, whenever issues change, and on manual dispatch. -on: - schedule: - - cron: "0 */6 * * *" # every 6 hours - issues: - types: [opened, closed, reopened, edited, labeled, unlabeled] - workflow_dispatch: - -# Only one snapshot at a time; let the newest win. -concurrency: - group: roadmap-snapshot - cancel-in-progress: true - -jobs: - snapshot: - runs-on: ubuntu-latest - permissions: - contents: write - steps: - - uses: actions/checkout@v4 - - - uses: actions/setup-node@v4 - with: - node-version: 20 - - - name: Build roadmap.json - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: node .github/scripts/build-roadmap.mjs - - - name: Commit if changed - run: | - git config user.name "github-actions[bot]" - git config user.email "41898282+github-actions[bot]@users.noreply.github.com" - if git diff --quiet -- web/public/roadmap.json; then - echo "No changes to roadmap.json." - exit 0 - fi - git add web/public/roadmap.json - git commit -m "chore(roadmap): refresh snapshot [skip ci]" - git push diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index ec97c55..7a017a3 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -36,6 +36,30 @@ Common areas: `web`, `firmware`, `pcb`, `enclosure`, `docs`, `pattern`. Use tooling enforces it, it just keeps the history (and the Discord dev-log) readable. +## Development workflow + +Work happens on `dev`, then lands on `main` through a pull request. + +``` +work on dev → commit early and often → open a PR into main → merge +``` + +- **Commit freely on `dev`.** Commits are cheap save points; small and frequent + is good. Keep throwaway `wip:` commits here rather than on `main`. +- **Code changes go through a PR** (anything under `web/` or `firmware/`). A PR + runs CI (`web/` PRs must pass `next build`) and groups the change into one + clean Discord dev-log post. Trivial doc/typo fixes can be committed directly. +- **Bigger or riskier work** gets its own branch (`feat/…`, `fix/…`) off `dev`. +- **After a PR merges**, pull `main` back into `dev` so the branches don't + drift apart over time: + + ``` + git checkout dev && git merge origin/main && git push origin dev + ``` + +Releases are published from `main` (GitHub → Releases → *Generate release +notes*), which posts an announcement to Discord. + ## Project Rules Project rules and guidelines are currently under consideration and will be finalized in the future. diff --git a/web/public/roadmap.json b/web/public/roadmap.json deleted file mode 100644 index 0a22a5b..0000000 --- a/web/public/roadmap.json +++ /dev/null @@ -1,212 +0,0 @@ -{ - "repo": "engmung/PatternFlow", - "fetchedAt": "2026-06-25T04:14:21.843Z", - "issues": [ - { - "number": 140, - "title": "Pattern Lab: proper AI agent integration (multi-model)", - "url": "https://github.com/engmung/PatternFlow/issues/140", - "state": "open", - "updatedAt": "2026-06-24T23:24:45Z", - "comments": 1, - "labels": [ - { - "name": "area:web", - "color": "868e5f" - }, - { - "name": "type:feature", - "color": "5b6776" - } - ], - "subIssues": null - }, - { - "number": 113, - "title": "Enclosure for mass production", - "url": "https://github.com/engmung/PatternFlow/issues/113", - "state": "open", - "updatedAt": "2026-06-24T14:45:01Z", - "comments": 4, - "labels": [ - { - "name": "area:enclosure", - "color": "15ac9f" - }, - { - "name": "type:improvement", - "color": "6e7a89" - } - ], - "subIssues": null - }, - { - "number": 123, - "title": "Laser-cut enclosure version + guide (post-launch)", - "url": "https://github.com/engmung/PatternFlow/issues/123", - "state": "open", - "updatedAt": "2026-06-24T05:50:57Z", - "comments": 1, - "labels": [ - { - "name": "area:enclosure", - "color": "15ac9f" - }, - { - "name": "type:feature", - "color": "5b6776" - } - ], - "subIssues": null - }, - { - "number": 139, - "title": "Community engagement & retention mechanics (Discord gamification + activity pressure)", - "url": "https://github.com/engmung/PatternFlow/issues/139", - "state": "open", - "updatedAt": "2026-06-23T13:40:24Z", - "comments": 0, - "labels": [ - { - "name": "area:community", - "color": "32b3ca" - }, - { - "name": "type:improvement", - "color": "6e7a89" - }, - { - "name": "type:question", - "color": "97a1ae" - } - ], - "subIssues": null - }, - { - "number": 131, - "title": "Guide: creating and applying your own patterns", - "url": "https://github.com/engmung/PatternFlow/issues/131", - "state": "open", - "updatedAt": "2026-06-22T13:38:36Z", - "comments": 0, - "labels": [ - { - "name": "area:docs", - "color": "d522b4" - }, - { - "name": "type:feature", - "color": "5b6776" - } - ], - "subIssues": null - }, - { - "number": 127, - "title": "Set up GitHub Actions automation", - "url": "https://github.com/engmung/PatternFlow/issues/127", - "state": "open", - "updatedAt": "2026-06-22T13:38:22Z", - "comments": 0, - "labels": [ - { - "name": "area:web", - "color": "868e5f" - }, - { - "name": "type:feature", - "color": "5b6776" - } - ], - "subIssues": null - }, - { - "number": 118, - "title": "Build guides (\"easy to build\")", - "url": "https://github.com/engmung/PatternFlow/issues/118", - "state": "open", - "updatedAt": "2026-06-21T09:55:07Z", - "comments": 0, - "labels": [ - { - "name": "area:docs", - "color": "d522b4" - }, - { - "name": "type:improvement", - "color": "6e7a89" - }, - { - "name": "type:epic", - "color": "0d1117" - } - ], - "subIssues": { - "total": 2, - "completed": 0, - "percent": 0 - } - }, - { - "number": 121, - "title": "Breadboard-only version (no custom PCB) + guide (post-launch)", - "url": "https://github.com/engmung/PatternFlow/issues/121", - "state": "open", - "updatedAt": "2026-06-21T07:47:44Z", - "comments": 0, - "labels": [ - { - "name": "area:pcb", - "color": "8f1463" - }, - { - "name": "area:docs", - "color": "d522b4" - }, - { - "name": "type:improvement", - "color": "6e7a89" - } - ], - "subIssues": null - }, - { - "number": 114, - "title": "PCB reliability + production", - "url": "https://github.com/engmung/PatternFlow/issues/114", - "state": "open", - "updatedAt": "2026-06-18T02:35:24Z", - "comments": 1, - "labels": [ - { - "name": "area:pcb", - "color": "8f1463" - }, - { - "name": "type:improvement", - "color": "6e7a89" - } - ], - "subIssues": null - }, - { - "number": 117, - "title": "Community + contribution", - "url": "https://github.com/engmung/PatternFlow/issues/117", - "state": "open", - "updatedAt": "2026-06-17T13:35:19Z", - "comments": 0, - "labels": [ - { - "name": "area:community", - "color": "32b3ca" - }, - { - "name": "type:improvement", - "color": "6e7a89" - } - ], - "subIssues": null - } - ] -} diff --git a/web/src/app/roadmap/page.tsx b/web/src/app/roadmap/page.tsx index 1e8749c..ba1ca3d 100644 --- a/web/src/app/roadmap/page.tsx +++ b/web/src/app/roadmap/page.tsx @@ -24,12 +24,8 @@ export default function RoadmapPage() { useEffect(() => { let active = true; - // Prefer the static snapshot committed by the roadmap-snapshot Action - // (no runtime token, no rate limit). Fall back to the live API route if - // the snapshot hasn't been generated yet. - fetch('/roadmap.json', { cache: 'no-cache' }) - .then((res) => (res.ok ? res.json() : Promise.reject(new Error('no snapshot')))) - .catch(() => fetch('/api/roadmap').then((res) => res.json())) + fetch('/api/roadmap') + .then((res) => res.json()) .then((payload: RoadmapData) => { if (active) setData(payload); })