studio-design/gesso
Gesso is a Laravel package for building responsive, email-safe templates with Tailwind CSS. It provides Blade components and helpers to assemble transactional emails quickly, keeping markup consistent and compatible across common email clients.
Gesso is a spec-driven contract testing toolkit for Laravel/PHP projects: you point it at an OpenAPI/JSON Schema spec and it validates requests/responses, generates consumer-side fakes, and gates CI on contract coverage.
composer require --dev studio-design/gesso
vendor/bin/gesso doctor
vendor/bin/gesso doctor --emit-config # 2.7.0+
--emit-config writes a gesso.php that is equivalent to whatever PHPUnit/Laravel wiring it detected. That generated file is the best documentation of your current setup and the ideal starting point for editing.gesso.php (shared configuration). Resist the urge to keep parallel phpunit.xml env vars and a Laravel config — put the spec list, adapter choices and exclusions in gesso.php only.Contract tests in the test suite. Named contract checks now live in the Contract namespace. Write them as ordinary tests so they run under php artisan test, Pest, and CI without special invocation.
Consumer-side fakes (2.7.0). For services that call an API rather than expose one, use the spec-driven HTTP client fakes to stand in for the upstream. This keeps consumer tests honest — the fake is generated from the same spec the provider validates against, so drift shows up as a failing fake rather than a production surprise.
CI coverage gate. Merge per-suite coverage and enforce a threshold as two steps, both now defaulting from gesso.php so you don't repeat flags:
vendor/bin/gesso coverage:merge --config=gesso.php
vendor/bin/gesso coverage:gate --config=gesso.php --format=github --output-file=coverage/gesso.md
Every subcommand accepts --format and --output-file in 2.7.0 — wire --format=github for annotations and write the long form to a build artifact for reviewers.
Adapter configuration. If you use the Symfony or PSR-7 adapters, their policy hooks now default from the shared config instead of per-adapter setup. Define policies once in gesso.php and let both adapters inherit; only override where an adapter genuinely differs.
Laravel route parity. Route-side parity exclusions and the spec list are read from config as of 2.7.0. Keep exclusions beside the routes they excuse (or in a dedicated parity.exclusions block) so reviewers see the blast radius of a new exclusion in the diff.
Enum drift. Drift evaluation runs once per Paratest run, not once per worker. Treat the drift report as a single CI artifact; don't try to shard it.
Explicit request prefixes in stubs. Use these when your app mounts the same controller under several prefixes — declare the prefix explicitly instead of relying on inference.
Fuzz is deprecated. Named contract checks moved to the Contract namespace behind a deprecated Fuzz alias. The alias will disappear; do a repo-wide search/replace on imports now rather than after the next major.{} is no longer read as []. If you have assertions written against array access on an empty object, they will fail — switch to assertJsonPath/assertEquals((object) [], ...) style checks. This is the most likely source of upgrade breakage in existing suites.style, explode, and per-part headers, and preserves body boundaries across adapters and the doctor. If you previously worked around multipart validation with hand-built payloads, delete those workarounds — they now produce double-encoded bodies.--emit-config and diff the generated file against yours; a stale config is the usual culprit.ext-mbstring, and gesso.php enum values are normalised like extension parameters. Prefer lowercase string literals in config; mixed-case enums that "worked" before may now normalise differently on machines without mbstring.--parallel. The orchestrator tolerates a sealed event facade. If you registered custom listeners or resolved the event dispatcher inside a test, they may be silent under parallel runs — assert on the CLI output/artifacts rather than on dispatched events.doctor --emit-config output is the canonical, version-matched template — use it to discover supported config keys rather than reading source.How can I help you explore Laravel packages today?