Mirror the GitHub profile cards onto Forgejo #1

Open
opened 2026-08-19 16:13:51 +00:00 by Phil · 1 comment
Owner

The GitHub profile at github.com/PhilflowIO/PhilflowIO renders six generated graphics: contribution snake, 3D contribution graph, a metrics card, an activity card, streak stats and an activity graph. All six are produced by Actions bound to GitHub's GraphQL API (Platane/snk, yoshi389111/github-profile-3d-contrib, lowlighter/metrics) or by hosted services that only accept GitHub usernames (github-readme-streak-stats, github-readme-activity-graph). None of them work against a Forgejo instance.

What Forgejo does give us

  • GET /api/v1/users/{user}/heatmap — 15-minute contribution buckets. Everything except the language breakdown derives from this.
  • GET /user/repos, GET /repos/{owner}/{repo}/languages — repository and language statistics.
  • Profile READMEs via a .profile repository.
  • Forgejo Actions with cron, for the daily refresh.

Acceptance criteria

  • Five cards generated from the Forgejo API: snake, streaks, activity graph, isometric contribution landscape, metrics/languages.
  • Light and dark variant for each, embedded via <picture> in the profile README.
  • Heatmap is read with a token. Anonymous reads only cover public repositories, which on this instance reports 280 instead of 22,979 contributions — a visually empty year.
  • Daily refresh via Forgejo Actions, published to an output branch.
  • Generator is typechecked and runnable locally.

Notes

Platane/snk v3.5 ships a Forgejo source, but it fetches the heatmap anonymously and has no token option. Its solver and SVG writer are reusable as-is, so we vendor the repository at a pinned commit and feed it our own authenticated cell grid rather than patching it. Worth upstreaming a --forgejo_token flag separately.

The GitHub profile at github.com/PhilflowIO/PhilflowIO renders six generated graphics: contribution snake, 3D contribution graph, a metrics card, an activity card, streak stats and an activity graph. All six are produced by Actions bound to GitHub's GraphQL API (`Platane/snk`, `yoshi389111/github-profile-3d-contrib`, `lowlighter/metrics`) or by hosted services that only accept GitHub usernames (`github-readme-streak-stats`, `github-readme-activity-graph`). None of them work against a Forgejo instance. ## What Forgejo does give us - `GET /api/v1/users/{user}/heatmap` — 15-minute contribution buckets. Everything except the language breakdown derives from this. - `GET /user/repos`, `GET /repos/{owner}/{repo}/languages` — repository and language statistics. - Profile READMEs via a `.profile` repository. - Forgejo Actions with cron, for the daily refresh. ## Acceptance criteria - [ ] Five cards generated from the Forgejo API: snake, streaks, activity graph, isometric contribution landscape, metrics/languages. - [ ] Light and dark variant for each, embedded via `<picture>` in the profile README. - [ ] Heatmap is read **with a token**. Anonymous reads only cover public repositories, which on this instance reports 280 instead of 22,979 contributions — a visually empty year. - [ ] Daily refresh via Forgejo Actions, published to an `output` branch. - [ ] Generator is typechecked and runnable locally. ## Notes `Platane/snk` v3.5 ships a Forgejo source, but it fetches the heatmap anonymously and has no token option. Its solver and SVG writer are reusable as-is, so we vendor the repository at a pinned commit and feed it our own authenticated cell grid rather than patching it. Worth upstreaming a `--forgejo_token` flag separately.
Phil closed this issue 2026-08-19 16:14:04 +00:00
Phil reopened this issue 2026-08-19 16:20:54 +00:00
Author
Owner

Cards are live on https://forgejo.philflow.me/Phil — the output branch was published by hand from a local run, so the profile renders now.

Two things changed against the plan above:

Single file per card instead of a light/dark pair. Forgejo's markdown sanitizer strips <picture> and <source>, so a pair collapses to whichever file the fallback <img> points at and the profile rendered light cards on a dark page. Each card now draws against CSS variables and carries both palettes behind a prefers-color-scheme query, the same way snk does.

Runner. flow-raven-staging-ci is registered on the Philflow org and never picks up a job in a user-owned repository — run 2 sat in waiting. Only flow-raven-eval and flow-raven-e2e-prod are instance-scoped; the workflow runs on the former. That runner also resolves actions against this instance (Phil/checkout, not actions/checkout) and runs steps as non-root, so bun installs into $HOME.

Remaining, and the only thing blocking the daily refresh: PROFILE_TOKEN is not set. Run 5 gets all the way through checkout, typecheck, snk vendoring and into the generator, then dies on GET /user/repos → 401 token is required. Needs a personal access token with read:user + read:repository stored as an Actions secret on this repo. Everything before and after that step is verified working.

Cards are live on https://forgejo.philflow.me/Phil — the `output` branch was published by hand from a local run, so the profile renders now. Two things changed against the plan above: **Single file per card instead of a light/dark pair.** Forgejo's markdown sanitizer strips `<picture>` and `<source>`, so a pair collapses to whichever file the fallback `<img>` points at and the profile rendered light cards on a dark page. Each card now draws against CSS variables and carries both palettes behind a `prefers-color-scheme` query, the same way snk does. **Runner.** `flow-raven-staging-ci` is registered on the `Philflow` org and never picks up a job in a user-owned repository — run 2 sat in `waiting`. Only `flow-raven-eval` and `flow-raven-e2e-prod` are instance-scoped; the workflow runs on the former. That runner also resolves actions against this instance (`Phil/checkout`, not `actions/checkout`) and runs steps as non-root, so bun installs into `$HOME`. Remaining, and the only thing blocking the daily refresh: **`PROFILE_TOKEN` is not set.** Run 5 gets all the way through checkout, typecheck, snk vendoring and into the generator, then dies on `GET /user/repos → 401 token is required`. Needs a personal access token with `read:user` + `read:repository` stored as an Actions secret on this repo. Everything before and after that step is verified working.
Sign in to join this conversation.
No labels
No milestone
No project
No assignees
1 participant
Notifications
Due date
The due date is invalid or out of range. Please use the format "yyyy-mm-dd".

No due date set.

Dependencies

No dependencies set.

Reference
Phil/.profile#1
No description provided.