Skip to content

v6.0.0

Choose a tag to compare

@CarlosGude CarlosGude released this 21 Sep 08:19
· 83 commits to main since this release

Webhooks pared back to what works for any provider. The bundle stops shipping integrations it cannot keep stable, and stops shipping ports nothing ever called.

Cuerpo

The bundle shipped two kinds of code under the same roof: mechanism that knows nobody, and integrations that name one vendor. 6.0 keeps the first and drops the second.

Breaking

Vendor integrations are gone — ShopifyHmacSignatureVerifier, WooCommerceHmacSignatureVerifier, two Shopify parsers, six mappers, six event DTOs, ShopifyWebhookController, and the multi-platform set (MultiPlatformWebhookController, deprecated in 5.4.0, plus WebhookPlatform, WebhookPlatformConfig, WebhookPlatformRegistry).

A shipped mapper is a promise the bundle cannot keep: six fields of one version of someone else's payload, a release owed every time they move it, and a fork needed for a seventh field. make:webhook writes those classes into your application, where you can edit them.

The scaffolding that only declared intentions is gone — WebhookDlqPort, WebhookEventAuditPort, WebhookMapperResolverPort, WebhookFailure, WebhookEventState, WebhookEventStateTransition, WebhookEventRegistry, ProcessWebhookMessage, ProcessWebhookHandler. Ports nothing called, value objects nothing produced, and a Messenger handler that contradicted ADR 0008. Symfony's Messenger failure transport already is a dead-letter queue.

Migration: UPGRADE-6.0.md. Reasoning: ADR 0014.

What stays, and what got better

  • Three signature schemes, named after the scheme instead of the vendor: HmacSha256SignatureVerifier (hex behind a prefix), the new Base64HmacSignatureVerifier (raw digest in base64 — the two removed verifiers were this class twice), TimestampedHmacSignatureVerifier.
  • make:webhook generates the consumer too. It was the one piece nobody could avoid writing by hand, always the same twelve lines. The routing key, the URL segment and the #[AsRemoteEventConsumer] name are now one string the generator writes in all three places.
  • The generated parser has no constructor. The signing secret comes from framework.webhook.routing.<key>.secret, which Symfony already passes to parse(), so the parser is autowired as it stands: no services.yaml entry per event type.
  • ConsumesWebhookEvents carries consume() and the check that skips events of another type reaching the same URL. Override handles() when the provider names the event somewhere else.

Fixed

  • IntegrationWebhookRequestParser no longer maps the payload while parsing. It called the mapper and threw the result away. A provider posting several event types to one URL made the mapper fail inside the parser: 500 instead of 406, and the consumer's own type check never ran.
  • An event name with a slash (products/update) produced class names like Products/updateConsumer.
  • WEBHOOK.md told Symfony 6.4 users to import a routing file that only exists from 7.3.

Quality

620 tests, 100% covered MSI over 755 mutants, PHPStan level max over src and tests, and the full CI matrix green: PHP 8.2/8.3/8.4 × Symfony 6.4/7.4/8, lowest and stable.