Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
143 changes: 143 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ on:
permissions:
contents: read

env:
FRANKENPHP_VERSION: v1.11.2
ROADRUNNER_VERSION: v2025.1.7

# Cancel in progress workflows on pull_requests.
# https://docs.github.com/en/actions/using-jobs/using-concurrency#example-using-a-fallback-value
concurrency:
Expand Down Expand Up @@ -71,6 +75,10 @@ jobs:
- name: Remove unused dependencies
run: composer remove vimeo/psalm phpstan/phpstan friendsofphp/php-cs-fixer --dev --no-interaction --no-update

- name: Remove RoadRunner dependencies on unsupported PHP versions
if: ${{ matrix.os == 'windows-latest' || matrix.php.version == '7.2' || matrix.php.version == '7.3' || matrix.php.version == '7.4' || matrix.php.version == '8.0' }}
run: composer remove spiral/roadrunner-http spiral/roadrunner-worker --dev --no-interaction --no-update

- name: Set phpunit/phpunit version constraint
run: composer require phpunit/phpunit:'${{ matrix.php.phpunit }}' --dev --no-interaction --no-update

Expand All @@ -96,3 +104,138 @@ jobs:
- name: Check benchmarks
run: vendor/bin/phpbench run --revs=1 --iterations=1
if: ${{ matrix.dependencies == 'highest' && matrix.php.version == '8.4' }}

runtime-tests-frankenphp:
name: Runtime tests (FrankenPHP)
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 2

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
coverage: none

- name: Determine Composer cache directory
id: composer-cache
run: echo "directory=$(composer config cache-dir)" >> "$GITHUB_OUTPUT"
shell: bash

- name: Cache Composer dependencies
uses: actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.directory }}
key: ${{ runner.os }}-runtime-frankenphp-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-runtime-frankenphp-composer-

- name: Install dependencies
run: composer install --no-progress --no-interaction --prefer-dist

- name: Install FrankenPHP
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail

case "$(uname -m)" in
x86_64) asset="frankenphp-linux-x86_64" ;;
aarch64|arm64) asset="frankenphp-linux-aarch64" ;;
*) echo "Unsupported architecture: $(uname -m)"; exit 1 ;;
esac

digest="$(gh api "repos/php/frankenphp/releases/tags/${FRANKENPHP_VERSION}" --jq ".assets[] | select(.name == \"${asset}\") | .digest")"

if [ -z "${digest}" ]; then
echo "Unable to resolve digest for ${asset} (${FRANKENPHP_VERSION})."
exit 1
fi

gh release download "${FRANKENPHP_VERSION}" \
--repo php/frankenphp \
--pattern "${asset}" \
--output "${asset}"

echo "${digest#sha256:} ${asset}" | sha256sum --check --
mkdir -p "${RUNNER_TEMP}/bin"
install -m 0755 "${asset}" "${RUNNER_TEMP}/bin/frankenphp"
echo "${RUNNER_TEMP}/bin" >> "${GITHUB_PATH}"
"${RUNNER_TEMP}/bin/frankenphp" version
shell: bash

- name: Run PHPUnit tests (excluding PHPT)
run: vendor/bin/phpunit tests --test-suffix Test.php --verbose

runtime-tests-roadrunner:
name: Runtime tests (RoadRunner)
runs-on: ubuntu-latest

steps:
- name: Checkout
uses: actions/checkout@v6
with:
fetch-depth: 2

- name: Setup PHP
uses: shivammathur/setup-php@v2
with:
php-version: '8.4'
coverage: none

- name: Determine Composer cache directory
id: composer-cache
run: echo "directory=$(composer config cache-dir)" >> "$GITHUB_OUTPUT"
shell: bash

- name: Cache Composer dependencies
uses: actions/cache@v5
with:
path: ${{ steps.composer-cache.outputs.directory }}
key: ${{ runner.os }}-runtime-roadrunner-composer-${{ hashFiles('**/composer.lock') }}
restore-keys: ${{ runner.os }}-runtime-roadrunner-composer-

- name: Install dependencies
run: composer install --no-progress --no-interaction --prefer-dist

- name: Install RoadRunner
env:
GH_TOKEN: ${{ github.token }}
run: |
set -euo pipefail

case "$(uname -m)" in
x86_64) arch="amd64" ;;
aarch64|arm64) arch="arm64" ;;
*) echo "Unsupported architecture: $(uname -m)"; exit 1 ;;
esac

version_no_prefix="${ROADRUNNER_VERSION#v}"
asset="roadrunner-${version_no_prefix}-linux-${arch}.tar.gz"

digest="$(gh api "repos/roadrunner-server/roadrunner/releases/tags/${ROADRUNNER_VERSION}" --jq ".assets[] | select(.name == \"${asset}\") | .digest")"

if [ -z "${digest}" ]; then
echo "Unable to resolve digest for ${asset} (${ROADRUNNER_VERSION})."
exit 1
fi

gh release download "${ROADRUNNER_VERSION}" \
--repo roadrunner-server/roadrunner \
--pattern "${asset}" \
--output "${asset}"

echo "${digest#sha256:} ${asset}" | sha256sum --check --
tar -xzf "${asset}" --strip-components=1 "${asset%.tar.gz}/rr"
mkdir -p "${RUNNER_TEMP}/bin"
install -m 0755 rr "${RUNNER_TEMP}/bin/rr"
echo "${RUNNER_TEMP}/bin" >> "${GITHUB_PATH}"
"${RUNNER_TEMP}/bin/rr" --version
shell: bash

- name: Run PHPUnit tests (excluding PHPT)
run: vendor/bin/phpunit tests --test-suffix Test.php --verbose

2 changes: 1 addition & 1 deletion .github/workflows/publish-release.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,7 @@ jobs:
fetch-depth: 0

- name: Prepare release
uses: getsentry/craft@c6e2f04939b6ee67030588afbb5af76b127d8203
uses: getsentry/craft@d630201930c7fe5aee6366ebee19ebb681128512
env:
GITHUB_TOKEN: ${{ steps.token.outputs.token }}
with:
Expand Down
106 changes: 106 additions & 0 deletions AGENTS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,106 @@
# AGENTS.md

## Overview

- `sentry/sentry` is the core PHP SDK, not an application or framework bundle.
- Public entry points include the autoloaded global helpers in
`src/functions.php` and the public classes and interfaces under `src/`.
- Use this file for repo-specific constraints that are easy to miss, and
explore the codebase for current implementation details.

## Compatibility Rules

- The minimum supported PHP version for shipped code is `7.2`.
`composer.json` requires `^7.2|^8.0`, so shipped code must remain valid on
PHP `7.2` unless support policy is intentionally being changed.
- This SDK has a broad public API surface. Treat changes to global helpers,
`Options`, `ClientBuilder`, `ClientInterface`, `HubInterface`,
`TransportInterface`, `IntegrationInterface`, tracing/logs/metrics types, and
Monolog handlers as BC-sensitive.
- Preserve the existing cross-version compatibility style. This repo supports
multiple `psr/log`, `symfony/options-resolver`, `guzzlehttp/psr7`, and
`monolog/monolog` major versions.
- Do not assume optional packages or binaries are available. Monolog is only a
suggested dependency, and FrankenPHP/RoadRunner worker coverage depends on
optional binaries and dev dependencies.
- `Spotlight` is treated as an active send path alongside DSN-based delivery.
Do not gate runtime setup or transport behavior on DSN alone.

## Editing Guidance

- Keep `declare(strict_types=1);` in PHP files.
- Follow the existing formatting rules from `.php-cs-fixer.dist.php`.
- If you add or change an SDK option, update the resolver/defaults in
`Options`, the relevant getters and setters, the `init()` option array-shape
docs in `src/functions.php`, and the affected tests.
- `src/functions.php` is autoloaded and part of the public API. Keep helper
signatures, phpdoc, and runtime behavior synchronized with the underlying
client, hub, and runtime-context implementation. Functions in
`src/functions.php` should use camelCase naming.
- `IntegrationRegistry` intentionally calls `setupOnce()` only once per
integration class during the process lifetime. Preserve de-duplication and
default-integration gating when changing integration setup behavior.
- `ErrorHandler` has fragile register-once, previous-handler chaining, reserved
memory, and out-of-memory behavior. Preserve that lifecycle carefully and add
PHPT coverage when changing fatal or silenced error handling.
- `SentrySdk::startContext()`, `endContext()`, and `withContext()` must keep
runtime-context isolation and best-effort flushing intact for logs, metrics,
and transport in long-running worker scenarios.
- `HttpTransport` and `PayloadSerializer` are tightly coupled. Preserve the
envelope item selection, Spotlight delivery path, dynamic sampling context,
and the transaction/profile relationship when changing transport or
serialization behavior.
- Monolog support spans multiple Monolog major versions through the
compatibility traits and handlers under `src/Monolog/`. Preserve that
compatibility style when changing logging integrations.
- `Client::SDK_VERSION` is updated by the release action via
`scripts/bump-version.sh`. Do not modify it manually as part of normal
development changes.

## Test Expectations

- Add tests with every behavior change. This is a library repo with broad
compatibility and regression coverage.
- New tests belong under `tests/`.
- `phpunit.xml.dist` defines a `unit` suite that includes both PHPUnit tests
and `tests/phpt`, plus a separate `oom` suite for `tests/phpt-oom`.
- Prefer targeted PHPUnit runs while iterating.
- After editing files, run the relevant formatting, lint, and test commands for
the code you changed.
- Before handing back substantive code changes, run `composer check` when
feasible and call out anything you could not run.
- If you change error handling, fatal error capture, or PHP-version-specific
behavior, add or update PHPT coverage.
- If you change runtime-context or worker-mode behavior, add or update focused
coverage for the FrankenPHP or RoadRunner paths as appropriate.

## Tools And Commands

- `phpstan.neon` only analyzes `src`, uses `phpstan-baseline.neon`, and will
not catch behavior regressions in `tests/` or PHPT coverage.
- `phpunit.xml.dist` is strict about unexpected output, so noisy debug output
will fail tests.
- This repo is a library, so do not expect a runnable application entrypoint.

## Docs And Release Notes

- `README.md` and `CHANGELOG.md` are updated manually during releases, so do
not modify them as part of normal development changes.
- If a change may require updates in the separate documentation repo, ask the
user whether to review `../sentry-docs` if that sibling checkout exists. If
it does not exist, ask the user for the local docs path first. If they opt
in, update that repo's `master` branch when safe, use git worktrees to
inspect the relevant docs, and suggest any needed changes to avoid stale
documentation.
- If a change affects installation, configuration, error handling, tracing,
profiling, metrics, logs, or worker-mode behavior, call out the likely
README or release-note follow-up in your summary instead of editing those
files automatically.

## CI Notes

- `.github/workflows/ci.yml` runs the PHPUnit compatibility matrix across
Ubuntu and Windows, lowest and highest dependencies, and separate runtime
jobs for FrankenPHP and RoadRunner.
- `.github/workflows/static-analysis.yaml` runs PHP-CS-Fixer, PHPStan, and
Psalm on single recent PHP versions rather than across the full test matrix.
73 changes: 73 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,78 @@
# CHANGELOG

## 4.22.0

The Sentry SDK team is happy to announce the immediate availability of Sentry PHP SDK v4.22.0.

### Features

- Add support for the client report protocol without collecting client reports yet. [(#1978)](https://github.com/getsentry/sentry-php/pull/1978)
- Add `strict_trace_continuation` support to only continue incoming traces when the upstream baggage `org_id` matches the SDK org ID. [(#2016)](https://github.com/getsentry/sentry-php/pull/2016)

Example:
```php
\Sentry\init([
'dsn' => '__YOUR_DSN__',
'strict_trace_continuation' => true,
]);
```

### Bug Fixes

- Preserve sub-second timestamps for Monolog breadcrumbs. [(#2018)](https://github.com/getsentry/sentry-php/pull/2018)

## 4.21.0

The Sentry SDK team is happy to announce the immediate availability of Sentry PHP SDK v4.21.0.

### Features

- Add `RuntimeContext` and context lifecycle helpers for long-lived runtimes such as FrankenPHP and RoadRunner. [(#2011)](https://github.com/getsentry/sentry-php/pull/2011)

Long-lived worker runtimes keep process memory between requests, which can cause scope data to leak from one request to the next.
`RuntimeContext` isolates SDK state per request and flushes buffered telemetry when the request context ends.
Data configured before a runtime context is started is copied into each new context as baseline scope data.

Example:

```php
\Sentry\init([
'dsn' => '__YOUR_DSN__',
]);

$handler = static function (): void {
\Sentry\withContext(static function (): void {
// Handle one request.
});
};

while (frankenphp_handle_request($handler)) {}
```

When using a runtime context, manual `\Sentry\flush()` calls are not needed for request teardown.
It is still necessary to finish transactions explicitly.

## 4.20.0

The Sentry SDK team is happy to announce the immediate availability of Sentry PHP SDK v4.20.0.

### Features

- Add a high-level `flush()` helper that flushes all buffered telemetry resources (logs and trace metrics). [(#1989)](https://github.com/getsentry/sentry-php/pull/1989)
- Add share handles to cURL (persistent for PHP >= 8.5, non-persistent otherwise). [(#1996)](https://github.com/getsentry/sentry-php/pull/1996)
- Handle HTTP 413 responses explicitly with a dedicated `content_too_large` status. [(#2008)](https://github.com/getsentry/sentry-php/pull/2008)

### Bug Fixes

- Normalize Spotlight URLs to optionally allow trailing `/stream`. [(#1984)](https://github.com/getsentry/sentry-php/pull/1984)
- Monolog messages are now filtered by their original Monolog level before being mapped to Sentry log levels. [(#1992)](https://github.com/getsentry/sentry-php/pull/1992)
- Handle bracketed IPv6 addresses (such as `[::1]`). [(#2007)](https://github.com/getsentry/sentry-php/pull/2007)
- Ignore propagated baggage `sample_rate` when no `sentry-trace` header is present. [(#2002)](https://github.com/getsentry/sentry-php/pull/2002)

### Misc

- Add the `traceMetrics()` helper and deprecate `trace_metrics()`. [(#1995)](https://github.com/getsentry/sentry-php/pull/1995)

## 4.19.1

The Sentry SDK team is happy to announce the immediate availability of Sentry PHP SDK v4.19.1.
Expand Down
1 change: 1 addition & 0 deletions CLAUDE.md
5 changes: 4 additions & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,9 +34,12 @@
"guzzlehttp/promises": "^2.0.3",
"guzzlehttp/psr7": "^1.8.4|^2.1.1",
"monolog/monolog": "^1.6|^2.0|^3.0",
"nyholm/psr7": "^1.8",
"phpbench/phpbench": "^1.0",
"phpstan/phpstan": "^1.3",
"phpunit/phpunit": "^8.5.52|^9.6.34",
"spiral/roadrunner-http": "^3.6",
"spiral/roadrunner-worker": "^3.6",
"vimeo/psalm": "^4.17"
},
"suggest": {
Expand Down Expand Up @@ -68,7 +71,7 @@
"tests": "vendor/bin/phpunit --verbose",
"cs-check": "vendor/bin/php-cs-fixer fix --verbose --diff --dry-run",
"cs-fix": "vendor/bin/php-cs-fixer fix --verbose --diff",
"phpstan": "vendor/bin/phpstan analyse",
"phpstan": "vendor/bin/phpstan analyse --memory-limit 1G",
"psalm": "vendor/bin/psalm"
},
"config": {
Expand Down
5 changes: 0 additions & 5 deletions phpstan-baseline.neon
Original file line number Diff line number Diff line change
Expand Up @@ -228,11 +228,6 @@ parameters:
count: 1
path: src/Options.php

-
message: "#^Method Sentry\\\\Options\\:\\:isStrictTracePropagationEnabled\\(\\) should return bool but returns mixed\\.$#"
count: 1
path: src/Options.php

-
message: "#^Method Sentry\\\\Options\\:\\:shouldAttachStacktrace\\(\\) should return bool but returns mixed\\.$#"
count: 1
Expand Down
Loading
Loading