• 0.2.0 fb8f25d5ff

    haylan released this 2026-07-12 21:55:28 +00:00 | 4 commits to main since this release

    Added

    • Contribution history store (SQLite)ContributionStore persists each provider's daily counts in var/data/contributions.db; ContributionAggregator now fetches only the window since each provider's last stored date (plus a 3-day trailing overlap for late corrections), merges the result into the store, and prunes rows older than CONTRIBUTIONS_RETENTION_DAYS
    • graph:contributions:refetch console command — forces a full or explicit-range re-fetch of contribution history, chunked into ≤365-day windows, for one, several, or all configured providers
    • Concurrent, non-blocking provider fetchesProviderInterface::fetch() split into startFetch()/resolveFetch() so GitHub, GitLab, and Gitea requests are in flight simultaneously instead of one after another
    • Bounded fetch windowsstartFetch()/resolveFetch() accept optional $since/$until bounds, used by both the incremental aggregator and the refetch command
    • PHPStan static analysis — level 8 over src/ and tests/, run via composer phpstan
    • Contribution and ContributionCollection typed entities
    • CONTRIBUTIONS_RETENTION_DAYS environment variable

    Changed

    • Namespace renamed from App to GitContributionGraph across the codebase, Composer autoloading, and routing config
    • Removed the Guzzle and GraphQL client bundles — GitHub requests now go through Symfony's HttpClientInterface directly, the same as GitLab and Gitea
    • HTTP client requests are capped (10s connect/first-byte timeout, 15s max duration) so a slow provider can no longer stall the render path
    • docker-compose.yml and docker-compose.prod.yml mount a data volume for the SQLite store and pass through CONTRIBUTIONS_RETENTION_DAYS
    • Dev Docker Compose override targets the dev build stage explicitly and mounts vendor read-write instead of as an anonymous volume

    Fixed

    • ContributionCollection's variadic constructor now re-indexes its arguments with array_values(), avoiding non-sequential keys that didn't match its declared property type
    • SvgRenderer coerces strtotime() results to int before formatting dates
    • docker-compose.prod.yml was missing the data volume and CONTRIBUTIONS_RETENTION_DAYS env var present in docker-compose.yml, so contribution history would not survive a container recreate on that deployment path
    • composer phpstan no longer crashes with an out-of-memory error under the default 128M limit

    Documentation

    • README and CLAUDE.md updated to describe the SQLite store, incremental fetch, refetch command, and PHPStan setup; corrected several stale examples (test path, /health sample response, Docker volume mounts)
    • Added PHPDoc to the remaining public methods across src/

    Tests

    • Added tests for ContributionStore, Contribution, ContributionCollection, and RefetchContributionsCommand
    • Extended provider and aggregator tests to cover $since/$until windowing, concurrent-fetch failure modes, and store interactions
    Downloads