-
[0.2.0] - 2026-07-12 Stable
released this
2026-07-12 21:55:28 +00:00 | 4 commits to main since this releaseAdded
- Contribution history store (SQLite) —
ContributionStorepersists each provider's daily counts invar/data/contributions.db;ContributionAggregatornow 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 thanCONTRIBUTIONS_RETENTION_DAYS graph:contributions:refetchconsole 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 fetches —
ProviderInterface::fetch()split intostartFetch()/resolveFetch()so GitHub, GitLab, and Gitea requests are in flight simultaneously instead of one after another - Bounded fetch windows —
startFetch()/resolveFetch()accept optional$since/$untilbounds, used by both the incremental aggregator and the refetch command - PHPStan static analysis — level 8 over
src/andtests/, run viacomposer phpstan ContributionandContributionCollectiontyped entitiesCONTRIBUTIONS_RETENTION_DAYSenvironment variable
Changed
- Namespace renamed from
ApptoGitContributionGraphacross the codebase, Composer autoloading, and routing config - Removed the Guzzle and GraphQL client bundles — GitHub requests now go through Symfony's
HttpClientInterfacedirectly, 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.ymlanddocker-compose.prod.ymlmount adatavolume for the SQLite store and pass throughCONTRIBUTIONS_RETENTION_DAYS- Dev Docker Compose override targets the
devbuild stage explicitly and mountsvendorread-write instead of as an anonymous volume
Fixed
ContributionCollection's variadic constructor now re-indexes its arguments witharray_values(), avoiding non-sequential keys that didn't match its declared property typeSvgRenderercoercesstrtotime()results tointbefore formatting datesdocker-compose.prod.ymlwas missing thedatavolume andCONTRIBUTIONS_RETENTION_DAYSenv var present indocker-compose.yml, so contribution history would not survive a container recreate on that deployment pathcomposer phpstanno longer crashes with an out-of-memory error under the default 128M limit
Documentation
- README and
CLAUDE.mdupdated to describe the SQLite store, incremental fetch, refetch command, and PHPStan setup; corrected several stale examples (test path,/healthsample response, Docker volume mounts) - Added PHPDoc to the remaining public methods across
src/
Tests
- Added tests for
ContributionStore,Contribution,ContributionCollection, andRefetchContributionsCommand - Extended provider and aggregator tests to cover
$since/$untilwindowing, concurrent-fetch failure modes, and store interactions
Downloads
- Contribution history store (SQLite) —