feat: FrankenPHP runtime, per-provider health probes, and ContributionAggregator #2

Merged
haylan merged 15 commits from feat/frankenphp into main 2026-05-30 12:32:11 +00:00
Owner

[0.1.0] - 2026-05-30

Added

  • FrankenPHP runtime — base image migrated from php-cli to FrankenPHP Alpine for better performance and built-in web server support
  • FrankenPHP worker mode — Symfony worker script (public/worker.php) with request reuse and graceful reload
  • Caddy configurationdocker/frankenphp/Caddyfile and Caddyfile.dev for production and development setups
  • Provider health probesProviderInterface extended with ping() and probe() methods; ProbeTrait provides the shared implementation
  • Per-provider status on /health — the health endpoint now reports ok, degraded, or down for each configured provider (GitHub, GitLab, Gitea), along with an error code and latency
  • Supporting value objectsProviderStatus, ProviderStatusType, ProviderErrorCode, and ProviderHealthChecker service
  • ContributionAggregator service — contribution merging logic extracted from GraphController into a dedicated, testable service

Fixed

  • Optional environment variables (GITLAB_URL, ALLOWED_HOSTS, etc.) now have explicit empty default values in docker-compose.yml, preventing Docker Compose warnings on startup

Changed

  • SvgRenderer is now final and declares strict_types=1

Tests

  • Unit tests added for ProbeTrait, ProviderHealthChecker, ProviderStatus, ContributionAggregator, and all three provider probes (GitHubProvider, GitLabProvider, GiteaProvider)
  • SvgRendererTest refactored to follow project PHPUnit conventions (#[Test] attribute, it_ prefix, Arrange/Act/Assert structure)
## [0.1.0] - 2026-05-30 ### Added - **FrankenPHP runtime** — base image migrated from `php-cli` to FrankenPHP Alpine for better performance and built-in web server support - **FrankenPHP worker mode** — Symfony worker script (`public/worker.php`) with request reuse and graceful reload - **Caddy configuration** — `docker/frankenphp/Caddyfile` and `Caddyfile.dev` for production and development setups - **Provider health probes** — `ProviderInterface` extended with `ping()` and `probe()` methods; `ProbeTrait` provides the shared implementation - **Per-provider status on `/health`** — the health endpoint now reports `ok`, `degraded`, or `down` for each configured provider (GitHub, GitLab, Gitea), along with an error code and latency - **Supporting value objects** — `ProviderStatus`, `ProviderStatusType`, `ProviderErrorCode`, and `ProviderHealthChecker` service - **`ContributionAggregator` service** — contribution merging logic extracted from `GraphController` into a dedicated, testable service ### Fixed - Optional environment variables (`GITLAB_URL`, `ALLOWED_HOSTS`, etc.) now have explicit empty default values in `docker-compose.yml`, preventing Docker Compose warnings on startup ### Changed - `SvgRenderer` is now `final` and declares `strict_types=1` ### Tests - Unit tests added for `ProbeTrait`, `ProviderHealthChecker`, `ProviderStatus`, `ContributionAggregator`, and all three provider probes (`GitHubProvider`, `GitLabProvider`, `GiteaProvider`) - `SvgRendererTest` refactored to follow project PHPUnit conventions (`#[Test]` attribute, `it_` prefix, Arrange/Act/Assert structure)
haylan added 15 commits 2026-05-30 12:30:26 +00:00
Add production and dev Caddyfiles for FrankenPHP:
- Caddyfile: HTTP-only on :8080, auto_https off, worker mode
- Caddyfile.dev: same but without worker directive so Xdebug
  step-debugging remains functional; Caddy debug logging enabled

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Boot the Symfony kernel once at startup, then loop with
frankenphp_handle_request() to handle every incoming request without
re-bootstrapping the framework. Supports MAX_REQUESTS env var for
graceful worker restarts.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace php:8.4-cli-alpine3.21 with dunglas/frankenphp:1-php8.4-alpine.
No Go toolchain required — the official image ships as a pre-compiled
Alpine binary.

- Drop docker-php-ext-install opcache (FrankenPHP enables it by default)
- Both dev and final stages run frankenphp run --config /etc/caddy/Caddyfile
- Dev stage bakes in Caddyfile.dev (no worker mode, Xdebug compatible)
- Final stage bakes in production Caddyfile

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Declare empty-string defaults for all optional env vars as Symfony
parameters so the container compiles without errors when GITHUB_USER,
GITLAB_TOKEN, GITEA_URL, etc. are not set in the environment.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Replace the clone-and-build workflow with a docker-compose snippet
that pulls the image directly from the Gitea container registry.
Add semver tag reference and rename steps to match the new flow.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
The PostToolUse hook called php bin/phpunit directly, which does not
work inside the Docker-based dev setup. Remove it; tests should be
run via docker compose exec graph vendor/bin/phpunit as documented.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Move fetchAllContributions and merge logic from GraphController into a new
ContributionAggregator service. Replace deprecated TaggedIterator with
AutowireIterator throughout.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
- Replace setUp() factory with direct instantiation (zero-param constructor)
- Add AAA blank-line separators to all test methods
- Consolidate theme + fallback tests behind a DataProvider
- Consolidate day-of-week label tests behind a DataProvider
- Split multi-assertion tests to one assertion per test

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add getName(), ping(), and probe() to ProviderInterface. Introduce
ProbeTrait to classify HTTP/transport exceptions into typed error codes,
ProviderStatus as the result value object, and ProviderStatusType /
ProviderErrorCode as backing enums.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Add getName() and ping() to each provider and wire ProbeTrait. Make
all classes final, add strict_types declarations, and replace generic
RuntimeException with typed HTTP exceptions so probe() can classify
auth failures and unreachable endpoints correctly.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Introduce ProviderHealthChecker which probes each configured provider
via AutowireIterator. Wire it into GraphController so /health returns
detailed per-provider status and responds 503 when any provider is
in a degraded state.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Fix "Prever" typo, add Windows WSL test runner command, and align
Markdown table columns for readability.

Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
haylan self-assigned this 2026-05-30 12:30:46 +00:00
haylan scheduled this pull request to auto merge when all checks succeed 2026-05-30 12:31:19 +00:00
haylan merged commit 2f66c65b30 into main 2026-05-30 12:32:11 +00:00
haylan deleted branch feat/frankenphp 2026-05-30 12:32:13 +00:00
Sign in to join this conversation.
No Reviewers
No labels
1 Participants
Notifications
Due Date
No due date set.
Dependencies

No dependencies set.

Reference: haylan/git-contribution-graph#2