Skip to content

feat(packagist): add PHP packages from Packagist as a fifth registry - #14

Merged
fleizean merged 2 commits into
developfrom
gsd/quick-261021-packagist-registry
Oct 21, 2026
Merged

fleizean merged 2 commits into
developfrom
gsd/quick-261021-packagist-registry

Conversation

@fleizean

@fleizean fleizean commented Oct 21, 2026 •

Copy link
Copy Markdown
Member

Summary

Adds Packagist (PHP / Composer) as a fifth registry next to NuGet, npm, PyPI and pub.dev. You can compare versions of vendor/package packages (laravel/framework, symfony/console, ...), see their advisories, and audit a composer.json or composer.lock.

Why

PHP is one of the largest ecosystems without coverage on pkgdiff. Packagist publishes no release notes of its own, but almost every package lives on GitHub. This is the same situation as PyPI, so the existing GitHub-first pipeline fits without new scraping code.

Changes

  • Registry client: PackagistService reads the Composer v2 metadata (repo.packagist.org/p2/{vendor}/{package}.json). This is a static, CDN-served file with no documented rate limit. The service expands its minified format (later entries only list changed fields; __unset removes one) and reads it once per request scope, because an analysis asks for many versions of the same package. PackagistRegistryClient uses GitHubFirstScrapingStrategy with PublishesReleaseNotes = false, like PyPI.
  • Versioning: new VersionScheme.Composer and ComposerVersion. They order versions the way Composer does: dev < alpha < beta < RC < stable < patch, up to four numeric segments, and trailing zeros ignored. Versions are exposed without their leading v (v6.4.1 becomes 6.4.1), so they match composer.json constraints and OSV ranges. The GitHub readers already strip v when matching tags.
  • Names: RegistryNames.Packagist = "packagist" with the alias composer. PackageIdRules gains a linear-time vendor/name grammar (lower case, as Packagist requires).
  • HTTP: a PackagistRepository named client with the registry size cap and a User-Agent that names the site, which Packagist asks API clients to send.
  • Security: OSV ecosystem Packagist. deps.dev and Socket do not cover Packagist; their clients already return nothing for unknown registries. The health panel therefore falls back to the OpenSSF Scorecard of the GitHub repository, as it does for pub.dev.
  • Audit: ManifestParser reads composer.json (require, require-dev) and composer.lock (packages, packages-dev). It skips platform requirements (php, ext-*, lib-*, composer-plugin-api) and treats dev-* branches as "latest is checked".
  • Registry row: DatabaseSeeder adds a packagist row at start-up when no spelling of it exists yet, so the registry appears without a manual admin step.
  • Frontend:
    • Install snippets (composer require) and a Packagist link.
    • Orange badges and the packagist.svg icon.
    • Home examples, and lower-casing of a typed Packagist name.
    • Audit wizard entry for PHP.
    • Route parsing: /package/packagist/symfony/console (the canonical URL the SEO service emits) resolves to symfony/console instead of package symfony with version console.
    • Trust-panel and behaviour texts no longer assume pub.dev is the only registry without deps.dev or Socket.
    • Registry lists in the SEO, privacy and terms copy.

Notes for reviewers

  • No migration: the registry row is data and is inserted by the seeder on the next start-up.
  • Not verified locally: no build, test or live request against Packagist was run. CI is the check.
  • Known gap: Symfony components are read-only splits of symfony/symfony and have no GitHub releases of their own. Their notes may come back empty until a monorepo changelog fallback is added. laravel/framework, guzzlehttp/guzzle and most packages publish GitHub releases.
  • packagist.svg is a simple placeholder package icon, not the official Packagist logo.

Checklist

  • The pull request targets develop and is about one thing
  • Commit messages follow Conventional Commits (feat(scope): ..., fix(scope): ...)
  • CI is green (backend tests, frontend build and tests, dependency gate)
  • Schema changes are EF Core migrations generated by the tool, not hand-edited
  • A changed backend DTO has its TypeScript twin updated in src/frontend/src/app/core/models
  • New dependencies are justified and their lock files are updated in the same commit
  • No secrets, tokens or personal data in code, logs or this description
  • Code comments are kept to a minimum; the reasoning lives in this description

Enes Yağız and others added 2 commits October 21, 2026 21:34
Versions come from the Composer v2 metadata on repo.packagist.org,
ordered by Composer's own rules; release notes come from GitHub like
PyPI. OSV covers Packagist advisories, the audit reads composer.json
and composer.lock, and the registry row is added on start-up.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…e page copy

The registry tests build their own client list and checked a package
id that is not a vendor/name; the SSR smoke test and index.html still
named four registries.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
@fleizean
fleizean merged commit 4deca6e into develop Oct 21, 2026
5 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant