docs: update README with token configuration and Docker development instructions
This commit is contained in:
@@ -104,11 +104,14 @@ All credentials are configured via environment variables — see [Deploy](#deplo
|
||||
|
||||
### GitHub
|
||||
|
||||
**Fine-grained token (recommended):**
|
||||
1. Go to **Settings → Developer settings → Personal access tokens → Fine-grained tokens**
|
||||
2. Set **Resource owner** to your account
|
||||
3. Under **Permissions → Account permissions**, set **Contribution activity** → Read-only
|
||||
4. Generate and copy the token
|
||||
|
||||
**Classic token:** create a token with the `read:user` scope.
|
||||
|
||||
### GitLab
|
||||
|
||||
1. Go to **User Settings → Access Tokens**
|
||||
@@ -125,6 +128,8 @@ All credentials are configured via environment variables — see [Deploy](#deplo
|
||||
|
||||
## Development
|
||||
|
||||
### Local (PHP)
|
||||
|
||||
```bash
|
||||
# Install deps
|
||||
composer install
|
||||
@@ -136,24 +141,76 @@ APP_ENV=dev php -S localhost:8080 -t public
|
||||
curl "http://localhost:8080/graph.svg" -o graph.svg
|
||||
```
|
||||
|
||||
### Docker (recommended)
|
||||
|
||||
`docker-compose.override.yml` is picked up automatically and targets the `dev` stage (Xdebug enabled, source mounted).
|
||||
|
||||
```bash
|
||||
# Start dev container
|
||||
docker compose up -d --build
|
||||
|
||||
# Shell into the container
|
||||
docker compose exec graph sh
|
||||
|
||||
# Run tests inside the container
|
||||
docker compose exec graph php bin/phpunit
|
||||
|
||||
# Disable Xdebug for faster test runs
|
||||
XDEBUG_MODE=off docker compose up -d
|
||||
```
|
||||
|
||||
Xdebug listens on port **9003**. On Linux, `host.docker.internal` is resolved via `host-gateway`.
|
||||
|
||||
To run with production config only (no override):
|
||||
|
||||
```bash
|
||||
docker compose -f docker-compose.yml up -d --build
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Testing
|
||||
|
||||
```bash
|
||||
# Run full suite
|
||||
php bin/phpunit
|
||||
|
||||
# Human-readable output
|
||||
php bin/phpunit --testdox
|
||||
|
||||
# Single file
|
||||
php bin/phpunit tests/Unit/Service/SvgRendererTest.php
|
||||
|
||||
# Filter by name
|
||||
php bin/phpunit --filter it_renders
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Architecture
|
||||
|
||||
```
|
||||
GET /graph.svg
|
||||
│
|
||||
├─ GitHubProvider → GitHub GraphQL API (contributionCalendar)
|
||||
├─ GitLabProvider → GitLab REST API (/users/:id/events)
|
||||
└─ GiteaProvider → Gitea REST API (/users/:user/heatmap)
|
||||
│
|
||||
merge by date (sum counts)
|
||||
│
|
||||
SvgRenderer
|
||||
│
|
||||
image/svg+xml (cached 1h)
|
||||
GET /graph.svg?theme=dark|light
|
||||
└─ GraphController
|
||||
├─ host check (ALLOWED_HOSTS env, optional)
|
||||
├─ cache lookup (filesystem, 1h TTL, key = "graph_{theme}")
|
||||
│ └─ on miss:
|
||||
│ ├─ GitHubProvider → GitHub GraphQL API (contributionCalendar)
|
||||
│ ├─ GitLabProvider → GitLab REST API (/users/:id/events, paginated)
|
||||
│ └─ GiteaProvider → Gitea REST API (/users/:user/heatmap)
|
||||
│ each returns array<string, int> (Y-m-d => count)
|
||||
│ failures are caught and logged; remaining providers still render
|
||||
│ └─ merge by date (sum counts across providers)
|
||||
│ └─ SvgRenderer::render()
|
||||
└─ Response: image/svg+xml, Cache-Control: public max-age=3600
|
||||
```
|
||||
|
||||
**Provider activation:** a provider only runs when its env vars are non-empty. GitHub and GitLab require `_USER` + `_TOKEN`; Gitea additionally requires `_URL`. GitLab resolves a numeric user ID from the username via a `/api/v4/users?username=` lookup before fetching events.
|
||||
|
||||
**SvgRenderer:** builds a 53-column × 7-row grid aligned so the last column always ends on the Saturday of the current week. Five intensity levels (0 → level 0, 1–3 → 1, 4–6 → 2, 7–9 → 3, 10+ → 4) mapped to GitHub's colour tokens. No external assets — the SVG is fully self-contained.
|
||||
|
||||
**Cache:** filesystem adapter (`var/cache/`), mounted as a Docker volume to survive container restarts. Theme is part of the cache key so dark and light are cached independently.
|
||||
|
||||
---
|
||||
|
||||
## License
|
||||
|
||||
Reference in New Issue
Block a user