Skip to content

fix: Correct package metadata and bring tooling to parity with the other SDKs - #459

Open
razor-x wants to merge 7 commits into
mainfrom
claude/php-tooling-parity-rzbrw1
Open

fix: Correct package metadata and bring tooling to parity with the other SDKs#459
razor-x wants to merge 7 commits into
mainfrom
claude/php-tooling-parity-rzbrw1

Conversation

@razor-x

@razor-x razor-x commented Jul 29, 2026

Copy link
Copy Markdown
Member

The Ruby and Python SDKs share a common project, packaging and CI layer that
this repository never received. The codegen half was already at parity, so
this brings the language-side tooling up with it.

Packaging

  • Add the description, license, homepage, keywords, support links and
    "php": "^8.0" constraint missing from composer.json, and point authors
    at Seam Labs rather than a personal address.

  • Move the Tests\ PSR-4 mapping from autoload to autoload-dev, so the
    test namespace is no longer registered in consumer projects.

  • Add archive.exclude so a built package ships only runtime files.
    package.json is deliberately kept, because Seam\Utils\PackageVersion
    reads it at runtime to set the seam-sdk-version header.

  • Add LICENSE.txt (MIT, matching the other SDKs) and phpunit.xml.dist.

  • Define the primary development tasks as Composer scripts:

    Task Command
    Run the tests composer test
    Lint composer lint
    Format npm run format
    Build the package composer build

Continuous integration

  • Replace the bespoke test.yml with check.yml, modelled on the other SDKs:
    test / lint / build / install jobs, running on pushes to main as
    well as pull requests, with job timeouts.
  • Test a PHP 8.0 and 8.5 matrix, covering both ends of the supported range.
    The previous workflow pinned 8.0 only, and composer.json declared no
    constraint at all.
  • Drop the SEAM_API_KEY secret, which the suite does not need, so checks now
    run on forks. The previous skip ci guard read github.event.head_commit,
    which is always null on pull_request events, so it never fired.
  • Add a real PHP setup composite action (setup-php, lockfile validation,
    cached composer install). The existing action only set up Node.js, so it is
    renamed setup-node and the generate and version workflows point at it.
  • Add _build.yml, which packages the library with composer build and
    uploads the archive, and an install job that requires that archive from a
    path repository and constructs a SeamClient. This also guards the
    package.json runtime dependency described above.
  • Wire the archive into publish.yml, which previously created a release with
    files: ''.
  • Add format.yml, so pushes are formatted with Prettier and committed. Until
    now formatting only ran as a postgenerate step, so hand-written commits
    were never formatted by CI.
  • Widen Semantic Release to all branches, so the next / beta / alpha
    prerelease branches declared in .releaserc.json can actually release.
  • Remove renovate.json, which used the deprecated config:base preset and
    only enabled @seamapi/types, already covered by Dependabot. Composer
    dependencies stay under manual control.
  • Set CODEOWNERS to @seamapi/sdk.

Prettier was a no-op on every non-PHP file

.prettierrc.json set "parser": "php" at the top level, which forces that
parser on all files rather than setting a default. Non-PHP files were
parsed as inline HTML and written back byte-identical, so Prettier silently did
nothing for TypeScript, JSON, YAML and Markdown, and prettier --check passed
vacuously. The overrides block only adjusted options the PHP parser ignores.

The PHP parser now lives in an override on **/*.php with the plugin defaults
it was already producing, and Prettier infers the parser for everything else.
Embedded formatting is disabled for Markdown so the README examples keep the
style of the generated source. The codegen/lib changes in this PR are the
result of running the formatter over TypeScript for the first time; src/ is
unchanged.

Verification

Run locally: composer lint, composer validate --strict, npm run lint and
npm run typecheck all pass. The full build to install round trip was
exercised exactly as check.yml does it (archive, path repository,
composer install, construct a SeamClient). All workflow YAML parses and
every action and reusable-workflow reference resolves.

src/ was checked for post-8.0 syntax (readonly, enums, never,
first-class callables, intersection types) and is clean, and the tightest
floor in composer.lock is symfony/deprecation-contracts at php >=8.0.2,
which the latest 8.0.x satisfies.

Notes for review

  • This title will cut a patch release. That is intentional, since the
    corrected package metadata and the autoload-dev change are consumer
    visible. Retitle to chore: before merging if you would rather not release.
  • PHP 8.0 is EOL. Testing it is the honest consequence of the ^8.0
    constraint. Raising the floor is a one-line change but breaks existing
    consumers.
  • PHPUnit is pinned at ^9.5, a 2022 release, and phpunit.xml.dist sets
    failOnWarning="true". If PHP 8.5 surfaces deprecations through its error
    handler, that leg will go red and the fix is a manual PHPUnit bump.

Deferred to a follow-up: wiring @seamapi/fake-seam-connect into the test
harness and growing the suite beyond its single file, PHPStan and an enforced
phpcs ruleset, a devcontainer, .php-version, and a README rebuild with
badges and a table of contents.

🤖 Generated with Claude Code

https://claude.ai/code/session_01RFK47311nWtbd3gHmjdknR


Generated by Claude Code

claude added 6 commits July 29, 2026 17:16
Add the description, license, homepage, keywords, support links and PHP
version constraint that were missing from composer.json, and point the
authors entry at Seam Labs rather than a personal address.

Move the Tests\ PSR-4 mapping from autoload to autoload-dev so the test
namespace is no longer registered in consumer projects, and add an
archive exclude list so a built package ships only the runtime files.
package.json is deliberately kept in the archive because
Seam\Utils\PackageVersion reads it at runtime.

Define the primary development tasks as Composer scripts (build, test,
lint) and configure PHPUnit in phpunit.xml.dist so the suite is declared
rather than passed by path.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RFK47311nWtbd3gHmjdknR
renovate.json used the deprecated config:base preset and only enabled
updates for @seamapi/types, which Dependabot already covers, so it was
doing nothing that the npm ecosystem in dependabot.yml does not.
Composer dependencies stay under manual control.

Set CODEOWNERS to the sdk team to match the other SDK repositories.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RFK47311nWtbd3gHmjdknR
Replace the bespoke test workflow with a Check workflow modelled on the
Ruby and Python SDKs. It runs on pushes to main as well as pull
requests, has test, lint, build and install jobs, sets job timeouts and
drops the SEAM_API_KEY secret the suite no longer needs, so checks now
run on forks.

Add a real PHP setup composite action that installs PHP, validates the
lockfile and installs Composer dependencies from a cache. The existing
action only set up Node.js, so rename it to setup-node and repoint the
generate and version workflows at it.

Add a reusable build workflow that packages the library with
composer build and uploads the archive, an install job that requires
that archive from a path repository and constructs a SeamClient, and
wire the archive into the Publish workflow, which previously created a
release with no files.

Add a Format workflow so pushes are formatted with Prettier and
committed, and widen Semantic Release to all branches so the prerelease
branches declared in .releaserc.json can actually release.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RFK47311nWtbd3gHmjdknR
The top-level parser option forced the PHP parser onto every file in the
repository. Non-PHP files were parsed as inline HTML and written back
unchanged, so Prettier silently did nothing for TypeScript, JSON, YAML
and Markdown, and the overrides block only ever adjusted options that
the PHP parser ignored.

Move the PHP parser into an override on **/*.php with the plugin
defaults it was already producing, and let Prettier infer the parser for
everything else, which restores the shared options used by the Ruby and
Python SDKs. Disable embedded formatting in Markdown so the PHP examples
in the README keep the style of the generated source.

The codegen changes are the result of running the formatter over
TypeScript for the first time.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RFK47311nWtbd3gHmjdknR
Replace the development setup section, which referenced yarn and invoked
PHPUnit by path, with the Composer script tasks, the supported PHP
versions and how a release is cut.

Record why the package version lives in package.json: Composer has no
canonical place for it, Packagist derives it from the git tag, and
Seam\Utils\PackageVersion reads the field at runtime.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RFK47311nWtbd3gHmjdknR
Run the check matrix on PHP 8.0 and 8.5 rather than the latest two
releases, so continuous integration covers both ends of the range the
package declares support for.

Default the setup action and the build workflow to 8.5, matching the top
of the matrix as the Ruby and Python SDKs do.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RFK47311nWtbd3gHmjdknR
Seam\Utils\PackageVersion read package.json from the package root at
runtime to set the seam-sdk-version header, which forced a development
manifest into every published package.

Replace it with a VERSION constant, and inject that constant from
package.json in the version lifecycle script, which npm runs after the
bump but before the commit, so the value is part of the tagged commit.
Packagist publishes the tag with no build step in between, so unlike the
JavaScript SDK, which injects at pack time, the version has to be
committed before the tag, as the Ruby SDK does with lib/seam/version.rb.

Add export-ignore rules to .gitattributes so development files are kept
out of the archives Composer downloads as dist, which composer.json's
archive exclude list does not govern, and exclude package.json from
composer archive as well.

Cover the constant with tests asserting it matches package.json and is
what SeamClient sends, so a hand edit or a missed injection fails.

Removes Seam\Utils\PackageVersionException, which only signalled an
unreadable package.json and has no remaining purpose.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01RFK47311nWtbd3gHmjdknR
@razor-x
razor-x force-pushed the claude/php-tooling-parity-rzbrw1 branch from 5963ea9 to ec1e185 Compare July 29, 2026 20:37
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.

2 participants