Skip to content

Comments

v1.0.0 Release - PHP 8.2+ with Full Feature Parity#42

Merged
MarketDataApp merged 184 commits intomainfrom
update/php-8.2-8.5
Feb 20, 2026
Merged

v1.0.0 Release - PHP 8.2+ with Full Feature Parity#42
MarketDataApp merged 184 commits intomainfrom
update/php-8.2-8.5

Conversation

@MarketDataApp
Copy link
Owner

v1.0.0 Release - PHP 8.2+ with Full Feature Parity

Summary

This PR prepares the PHP SDK for its 1.0.0 stable release. This is a major upgrade from v0.6.2-beta representing 172 commits, 245 files changed, and ~30,000 lines of new code. The SDK now has full feature parity with the Python SDK and 100% test coverage.


TL;DR for Review

Aspect Status
Tests ✅ 741 tests, 2353 assertions, all passing
Coverage ✅ 100% (no uncovered lines)
PHP Versions ✅ 8.2, 8.3, 8.4, 8.5 all tested
Feature Parity ✅ Full parity with Python SDK
Breaking Changes ⚠️ Yes - documented in CHANGELOG.md

Key files to review:

  • CHANGELOG.md - Release notes and migration guide
  • SDK_FEATURE_COMPARISON.md - Feature parity documentation

Breaking Changes (from v0.6.2-beta)

1. PHP Version Requirement

  • Was: PHP ^8.1
  • Now: PHP ^8.2+

2. Removed: bulkQuotes Method

// Before (v0.6.x)
$bulkQuotes = $client->stocks->bulkQuotes(['AAPL', 'MSFT']);

// After (v1.0.0)
$quotes = $client->stocks->quotes(['AAPL', 'MSFT']);

3. Options Quote Class Consolidation

  • Quote and OptionChainStrike classes merged into unified OptionQuote class

4. Client Constructor Changes

  • Token parameter now optional (auto-resolves from MARKETDATA_TOKEN env var or .env file)
  • Invalid tokens throw UnauthorizedException during construction (not on first API call)
  • New optional $logger parameter for custom PSR-3 logger injection

New Features

Core Infrastructure

Feature Description
PSR-3 Logging Full logging system with DefaultLogger, LoggerFactory, configurable via MARKETDATA_LOGGING_LEVEL
Settings Class Centralized config with .env file support (searches up to 5 directories)
Retry Logic RetryConfig with exponential backoff (3 attempts, 0.5-5s)
Rate Limit Tracking Automatic tracking via $client->rate_limits after each request
Concurrent Requests Up to 50 parallel requests for bulk operations

New Source Files Added (17 files)

src/Logging/DefaultLogger.php
src/Logging/LoggerFactory.php
src/Logging/LoggingUtilities.php
src/Settings.php
src/RateLimits.php
src/Retry/RetryConfig.php
src/Exceptions/BadStatusCodeError.php
src/Exceptions/RequestError.php
src/Exceptions/UnauthorizedException.php
src/Enums/ApiStatusResult.php
src/Enums/DateFormat.php
src/Enums/Mode.php
src/Traits/FormatsForDisplay.php
src/Traits/ValidatesInputs.php
src/Endpoints/Responses/Stocks/Prices.php
src/Endpoints/Responses/Utilities/ApiStatusData.php
src/Endpoints/Responses/Utilities/User.php

New Endpoints/Methods

  • $client->stocks->prices() - SmartMid model prices
  • $client->options->quotes() - Now supports multiple symbols with concurrent fetching
  • $client->utilities->user() - User account information

New Exception Hierarchy

use MarketDataApp\Exceptions\UnauthorizedException;  // 401 errors
use MarketDataApp\Exceptions\BadStatusCodeError;     // Other 4xx errors
use MarketDataApp\Exceptions\RequestError;           // Network errors

Response Enhancements

  • All response objects implement __toString() for human-readable output
  • FormatsForDisplay trait for currency, percent, volume formatting
  • ValidatesInputs trait for comprehensive input validation

OptionChains Convenience Methods

$chain->toQuotes();           $chain->getCalls();
$chain->getAllQuotes();       $chain->getPuts();
$chain->getExpirationDates(); $chain->getByStrike(200.0);
$chain->count();              $chain->getStrikes();

Test Coverage Summary

Metric Value
Total Tests 741
Assertions 2,353
Coverage 100%
Test Files 77
New Test Files 50+

The test suite now includes comprehensive tests for:

  • All endpoints (unit + integration)
  • Concurrent request handling
  • Retry logic and error handling
  • Rate limit tracking
  • Settings and environment variable resolution
  • Input validation
  • Response formatting and __toString() methods

Changes by Category

Category Files Changed Lines Added
Source (src/) 53 files ~5,000
Tests (tests/) 77 files ~20,000
Config/Docs 15 files ~2,500
Total 245 files ~29,500

Checklist

  • Version numbers updated to 1.0.0 (ClientBase, README, phpdoc)
  • CHANGELOG.md has comprehensive release notes with migration guide
  • Breaking changes documented with code examples
  • New features documented
  • All 741 tests passing
  • 100% code coverage maintained
  • Feature parity with Python SDK achieved and documented
  • PHPUnit deprecation warnings addressed (doc-comment metadata)

Post-Merge Release Steps

  1. Create GitHub release tagged v1.0.0 on main branch
  2. Write release notes (can use CHANGELOG.md content)
  3. Verify Packagist picks up v1.0.0
  4. Test: composer require marketdataapp/sdk-php ^1.0

Questions for Your Review

  1. Is the migration guide in CHANGELOG.md clear enough for existing users?
  2. Any concerns about the breaking changes?
  3. Ready to tag v1.0.0 after merge, or prefer a release candidate first?

MarketDataApp and others added 30 commits January 24, 2026 11:21
- Update composer.json PHP requirement from ^8.1 to ^8.2
- Update test matrix in run-tests.yml to [8.4, 8.3, 8.2]
- Update phpdoc.yml PHP version to 8.2
- Update actions/checkout to v4 and create-pull-request to v7 in phpdoc.yml
Updates the requirements on [phpunit/phpunit](https://github.com/sebastianbergmann/phpunit) to permit the latest version.
- [Release notes](https://github.com/sebastianbergmann/phpunit/releases)
- [Changelog](https://github.com/sebastianbergmann/phpunit/blob/11.4.0/ChangeLog-11.4.md)
- [Commits](sebastianbergmann/phpunit@10.3.2...11.4.0)

---
updated-dependencies:
- dependency-name: phpunit/phpunit
  dependency-type: direct:development
...

Signed-off-by: dependabot[bot] <support@github.com>
- Fix earnings currency: Make Earning::$currency nullable (string|null) and update Earnings.php to use null coalescing for currency to handle API returning null for future earnings reports
- Fix expired option tests: Update option symbol to AAPL281215C00400000 (expires 2028-12-15) and expiration date to 2028-12-15 for long-term test validity
- Remove rho property: Remove rho from all option models (Quote, OptionChainStrike) and all tests as it's no longer supported by the API
- Fix utilities service count: Change assertion from assertCount(4) to assertGreaterThanOrEqual(4) since API now returns 12 services
- Update all integration tests: Update setUp() methods to use MARKETDATA_TOKEN environment variable and skip tests if not set
- Update StocksTest: Update currency assertion to handle nullable type
- Update OptionsTest: Remove rho assertions and update to use valid option contracts
- Update Unit/OptionsTest: Remove rho from mocks and assertions

All tests now pass (82 tests, 814 assertions)
- Remove bulkQuotes() method from Stocks endpoint
- Delete BulkQuotes and BulkQuote response classes
- Remove all bulkQuotes test methods from unit and integration tests
- Update README.md to remove bulkQuotes example
- Update CHANGELOG.md to document bulkQuotes removal

BREAKING CHANGE: The bulkQuotes endpoint has been removed as it is no longer supported by the API.
Retry Logic Implementation:
- Added RetryConfig class with configurable retry attempts and exponential backoff
- Implemented retry logic in ClientBase for both sync (execute) and async (async) requests
- Added RequestError and BadStatusCodeError exception classes
- Retry logic matches Python SDK behavior:
  - 3 max retry attempts
  - Exponential backoff: 0.5s → 1s → 2s (max 5s)
  - Retries on status codes > 500 and network errors
  - No retry on 4xx errors (except 404 special case)

Test Fixes:
- Modified testParallelRetryOnServerError_mixedResults to verify behavior
  (all symbols present) rather than implementation details (response ordering)
- Test now uses order-independent symbol verification to avoid race conditions
  with MockHandler's FIFO queue
- Fixed testExceptionHandling_throwsGuzzleException to account for retry
  logic requiring 3 mock responses to exhaust retries
- Added comprehensive retry test suite (21 tests covering sync, async, and parallel scenarios)

All tests passing (85/85)
- Add RateLimits value object for reusable rate limit data structure
- Add extractRateLimitsFromResponse() method to ClientBase for modular header extraction
- Add User response class wrapping RateLimits
- Add user() method to Utilities class calling /user/ endpoint
- Add makeRawRequest() helper method to ClientBase for accessing response headers
- Add comprehensive unit tests covering edge cases and failure paths:
  - Missing headers, partial headers, invalid values, empty values
  - Case-insensitive matching, numeric formats, invalid timestamps, boundary values
- Add integration tests:
  - Test to determine if /user/ endpoint consumes requests
  - Test verifying rate limits after real SPY quote API call
- Update documentation to clarify consumed is per-request (not cumulative)
- All 97 tests passing with 727 assertions
- Create UnauthorizedException class extending BadStatusCodeError
- Update ClientBase to detect 401 status codes and throw UnauthorizedException
- Add unit tests for 401 UnauthorizedException handling
- Add integration tests for /user/ endpoint with invalid token
- Add integration test for SPY quote with no token
- Update makeRawRequest() to handle 401 errors for /user/ endpoint

All tests passing (103 tests, 753 assertions)
- Add public rate_limits property to ClientBase that automatically tracks rate limits
- Initialize rate limits during client construction via /user/ endpoint
- Automatically update rate limits after every successful API request
- Gracefully handle missing rate limit headers (no update, no error)
- Add comprehensive unit tests (8 tests) with mocked responses
- Add comprehensive integration tests (6 tests) with real API calls
- All 117 existing tests pass, no regressions
- Change rate limit property names to match API header names:
  - credits_limit -> limit (x-api-ratelimit-limit)
  - credits_remaining -> remaining (x-api-ratelimit-remaining)
  - credits_reset -> reset (x-api-ratelimit-reset)
  - credits_consumed -> consumed (x-api-ratelimit-consumed)
- Update all documentation to clarify that rate limits track credits, not requests
- Add examples directory with rate_limit_tracking.php example demonstrating automatic rate limit tracking
- Add examples/README.md with documentation for examples
- Update all tests to use new property names
- All 117 tests pass, no regressions
- Prevent client initialization with invalid tokens by validating via /user endpoint
- Allow empty token for free symbols like AAPL (skips validation)
- Throw UnauthorizedException during construction if token is invalid
- Update all unit tests to use empty tokens (they use mocks anyway)
- Add comprehensive integration tests for token validation scenarios
- Update existing tests to reflect new behavior

All tests pass (123 tests, 874 assertions)
- Add vlucas/phpdotenv dependency for .env file support
- Create Settings class with automatic token resolution from:
  1. Explicit token (constructor parameter) - highest priority
  2. MARKETDATA_TOKEN environment variable
  3. .env file (MARKETDATA_TOKEN)
  4. Empty string fallback (for free symbols)
- Make token parameter optional in Client and ClientBase constructors
- Update documentation with Configuration section matching Python SDK
- Update examples to show automatic env var support
- Add comprehensive tests for token resolution and env var support
- Maintain backward compatibility (explicit tokens still work)

Matches Python SDK developer experience for token configuration.
- Updated GitHub Actions workflow to test PHP 8.2, 8.3, 8.4, and 8.5
- Updated README badge to include PHP 8.5
- Created TESTING_STRATEGY.md with comprehensive testing documentation
- Updated CHANGELOG.md with PHP 8.5 support (v0.8.0-beta)
- Fixed integration test skipping issue (environment variable cleanup in SettingsTest)
- All PHP 8.5 compatibility fixes from 8.5-tests branch included
- Renamed branch from update/php-8.2-8.4 to update/php-8.2-8.5

All tests pass on PHP 8.5.2: 164 tests, 1165 assertions, 0 skipped
- Add script to run GitHub Actions tests locally using act
- Support testing all PHP versions (default) or a specific version
- Quick test mode: when a PHP version is specified, runs only 1 job (prefer-stable)
- Full test mode: when no version is specified, runs all 8 jobs (4 versions × 2 stability options)
- Includes Docker caching optimization (--pull=false) for faster subsequent runs
- Validates test results and fails if any tests are skipped
- Properly passes MARKETDATA_TOKEN environment variable for integration tests
- Add Mode enum with LIVE, CACHED, DELAYED values
- Add mode parameter to Parameters class (nullable, optional)
- Update UniversalParameters trait to handle mode in execute() and execute_in_parallel()
- Add unit tests for mode parameter (5 tests)
- Add integration tests for mode parameter using stockquote endpoint (3 tests)
- Update README with documentation for PHP version testing script
- All tests pass on PHP 8.2, 8.3, 8.4, and 8.5

Implements medium priority feature from universal parameters comparison document.
- Add DateFormat enum with TIMESTAMP, UNIX, and SPREADSHEET values
- Add date_format parameter to Parameters class (CSV-only restriction)
- Update UniversalParameters trait to pass dateformat query parameter
- Add comprehensive unit tests for parameter validation
- Add integration tests for all date formats across endpoints
- All 208 tests passing (1314 assertions)
- Updated Parameters class validation to allow date_format with both CSV and HTML formats
- Updated UniversalParameters trait to pass dateformat parameter for HTML format
- Added unit tests to validate HTML format with date_format
- Updated all error messages to reflect CSV/HTML support

All 210 tests passing (1323 assertions)
- Add columns parameter to Parameters class with CSV/HTML-only validation
- Update UniversalParameters trait to pass columns parameter to API requests
- Add comprehensive unit tests for columns parameter validation
- Add integration tests using quote endpoint to verify CSV column filtering
- All 225 tests passing (21 new unit tests, 3 new integration tests)
- Add add_headers parameter to Parameters class with CSV/HTML-only validation
- Update UniversalParameters trait to pass headers parameter to API in both execute() and execute_in_parallel() methods
- Fix execute_in_parallel() to properly handle CSV/HTML responses (was incorrectly trying to json_decode plain text)
- Fix Quotes class to handle null responses gracefully and initialize quotes array
- Add comprehensive unit tests for add_headers parameter validation (7 tests)
- Add integration tests for CSV output with add_headers=true/false using stocks/quotes endpoint (4 tests)
- All tests passing (236 tests, 1422 assertions, 0 skipped)

This fix also enables parallel requests to work correctly with CSV/HTML formats,
which was previously broken due to incorrect response parsing.
- Add optional filename parameter to Parameters class
- Validates filename extension matches format (.csv or .html)
- Validates that at least one parent directory exists (nested subdirectories created automatically)
- Prevents overwriting existing files
- Disallows filename with parallel requests (throws exception)
- Implements file writing in processResponse when filename provided
- Adds saveToFile() convenience method to ResponseBase
- Maintains backward compatibility (filename is optional)
- Returns response object with CSV/HTML string even when file is saved
- Supports both relative and absolute paths
- Handles multi-level nested directory creation
- Comprehensive unit and integration test coverage

All tests pass (257 tests, 1484 assertions, 0 skipped)
- Add Prices response class supporting JSON, CSV, HTML, and human-readable formats
- Add prices() method to Stocks class supporting single symbol (path) and multiple symbols (query) formats
- Support extended parameter (boolean, defaults to true)
- Add comprehensive unit tests (8 tests) covering all scenarios
- Add integration tests (6 tests) making real API calls
- All 271 tests pass with no regressions
- Created ValidatesInputs trait with reusable validation methods
- Added date range validation (only when both dates are parseable)
- Added numeric range validation (positive integers, min/max)
- Added string/array validation (non-empty, symbols)
- Added format validation (resolution, country codes)
- Follows Python SDK approach: allows relative dates and option expiration dates
- Added validation to all endpoint methods (Stocks, Options, Markets, MutualFunds)
- Added comprehensive test coverage (38 trait tests + 25 endpoint tests)
- All 334 tests passing, no regressions
- Backward compatible, no breaking changes
- Add default_params property to ClientBase for client-level parameter defaults
- Implement three-level configuration hierarchy: env vars → client defaults → method params
- Add Settings::getDefaultParameters() to read universal params from environment
- Update UniversalParameters trait with mergeParameters() and validation
- Add comprehensive test suite (77 tests, 113 assertions) with environment isolation
- Validate CSV-only parameters cannot be used with JSON format after merging
- Support .env file loading with parent directory search (up to 5 levels)
- Maintain backward compatibility with existing code patterns
- Introduced a new `test.sh` script to streamline test execution, allowing for unit and integration tests to be run with configurable options.
- Updated `phpunit.xml.dist` to define separate test suites for Unit, Integration, and All tests, enhancing clarity and control over test execution.
- The new script supports logging, PHP version selection, and provides real-time output to both console and log files.

All tests remain passing with the new structure in place.
- Add VERSION constant (0.8.0) to ClientBase class
- Update headers() method to include User-Agent: marketdata-sdk-php/0.8.0
- Follow RFC 7231 format: product/product-version (with slash separator)
- Add comprehensive test suite (8 tests) for User-Agent functionality
- All tests passing (325 tests total)

This implementation uses the correct RFC 7231 format, unlike the Python SDK
which uses marketdata-sdk-py-1.1.0 (missing slash separator).
…ecking

- Add ApiStatusResult enum (ONLINE, OFFLINE, UNKNOWN)
- Add online boolean field to ServiceStatus class
- Update ApiStatus to parse online field from API response
- Create ApiStatusData class with smart caching:
  * 5-minute cache validity
  * 4min30sec refresh trigger window
  * Async refresh in refresh window
  * Blocking refresh when cache is stale
- Add getServiceStatus() method to check specific service status
- Add refreshApiStatus() method for manual cache refresh
- Add constants for refresh interval and cache validity
- Add comprehensive unit and integration tests
- Failed refreshes don't overwrite existing cache
- Backward compatible with missing online field
- Add getServicePath() helper method with hardcoded mapping from method paths to service paths
- Integrate API status checking into execute() and async() retry logic
- Skip retries when service is known to be offline (matches Python SDK behavior)
- Continue retries when service is online or unknown
- Handle status endpoint special case (skip checking its own status)
- Add unit tests for intelligent retry behavior with different service statuses
- Add integration test for real API service status detection
- Optimize getApiStatus() to skip blocking refresh during retry logic

This matches the Python SDK's @api_error_handler decorator functionality.
- Update actions/checkout from v4 to v6 in all workflows
- Update codecov/codecov-action from v4 to v5 in run-tests.yml
- Update peter-evans/create-pull-request from v7 to v8 in phpdoc.yml
- Update stefanzweifel/git-auto-commit-action from v5 to v7 in update-changelog.yml
- Remove deprecated ReflectionMethod::setAccessible() call in ValidatesInputsTest.php
  (deprecated in PHP 8.5, no longer needed since PHP 8.1)
- Changed code block syntax from triple backticks to triple tildes for markdown formatting in comment templates.
- Ensured consistency in formatting across user error, works as designed, and fixed comment templates.
- Added a new section in CONTRIBUTING.md outlining a systematic bug finding workflow.
- Introduced .github/BUG_FINDING.md to provide detailed instructions for proactive bug discovery, including exploration areas and test scenarios.
- Updated CONTRIBUTING.md to reference the new bug finding document, improving clarity on how to report and document bugs.
- Added entry for 50+ bug fixes addressing various edge cases and API compatibility.
- Documented parameter changes for `option_chain()` and `expirations()` methods.
- Introduced new features including cache freshness control and extended hours control.
- Updated examples and API documentation links across multiple endpoints for clarity and usability.
…response

- Introduced a new test to verify that the application gracefully handles empty Symbol arrays in the human-readable news format.
- Ensured that defaults are returned when the API response contains empty arrays, preventing potential errors and maintaining stability.
Add comprehensive example applications demonstrating SDK usage:
- portfolio-tracker: Track portfolio value with real-time P&L
- earnings-calendar: Generate earnings calendar for watchlists
- options-screener: Screen for covered calls and cash-secured puts
- historical-data-exporter: Download multi-year data for backtesting
- market-hours-scheduler: Schedule tasks around market sessions
- news-sentiment-monitor: Monitor and aggregate stock news
- api-health-dashboard: Monitor API health and rate limits

Each example includes plan.md documentation and sample data files.
Add required checkboxes to bug template forcing reporters to confirm
they've reviewed the API docs and that the reported behavior differs
from documented behavior. This prevents false bug reports for cases
where the SDK correctly returns API data (e.g., percentages as decimals).

Updates ISSUE_WORKFLOW.md with corresponding validation criteria,
comment template, and example for "Expected API Behavior" cases.
Add explicit requirements throughout BUG_FINDING.md to ensure that
discovered bugs are submitted as actual GitHub issues, not just
documented in markdown files:

- Add prominent callout at document top requiring GitHub issues
- Update workflow line to mark issue creation as REQUIRED
- Expand Bug Documentation section with CLI command template
- Add Completion Checklist at end to verify issues were created
The human-readable format now properly handles missing or empty arrays
for all fields except Symbol. This prevents "Undefined array key 0"
errors when the API returns partial data.
…ess (closes #45)

Both human-readable and regular formats now calculate the minimum length
across all required arrays (Open/High/Low/Close/Volume/Date) before
iterating. This prevents "Undefined array key" errors when the API
returns mismatched array lengths.
…s access (closes #46)

Both human-readable and regular formats now calculate the minimum length
across all required arrays before iterating. This prevents "Undefined
array key" errors when the API returns mismatched array lengths.
- Added null-coalescing for nullable EPS fields in both human-readable
  and regular formats (reported_eps, estimated_eps, surprise_eps,
  surprise_eps_pct)
- Added minimum array length calculation to prevent out-of-bounds access
  when API returns mismatched array lengths
This issue was already fixed by the min() array length calculation
added in the Issue #47 fix. Adding explicit test coverage.
This issue was already fixed by the min() array length calculation
added in the Issue #45 fix. Adding explicit test coverage.
This issue was already fixed by the min() array length calculation
added in the Issue #46 fix. Adding explicit test coverage.
…a (closes #51)

Both human-readable and regular formats now validate that keys match
the YYYY-MM-DD date pattern before adding them to the dates array.
This prevents unknown metadata fields from being incorrectly treated
as date entries.
…n (closes #63)

Header deduplication in concurrent CSV responses now uses trim() on both
strings before comparison to handle potential whitespace variations.
…oses #53)

The execute_in_parallel() method now determines failure tolerance based
on whether a non-null array reference is provided, rather than checking
if any second argument was passed. This makes the behavior consistent
and predictable.
…ses #54)

The Stocks endpoint now uses array_unique() to deduplicate symbols,
matching the behavior of the Options endpoint. This prevents redundant
API calls when duplicate symbols are provided.
…y (closes #55)

The Stocks.quotes() method now delegates single-symbol arrays to the
more efficient single-symbol API path, matching the Options endpoint
behavior.
…sitives (closes #56)

The canParseAsDate() function now uses regex patterns to identify actual
date strings instead of accepting any string with '-' or '/'. This
prevents stock symbols like "AAPL-WKS" from being misidentified as dates.
Symbols are now uppercased during deduplication to ensure that
'AAPL', 'aapl', and 'AaPl' are treated as the same symbol,
preventing redundant API calls.
Updated canParseAsDate() to properly recognize all relative date formats
documented at marketdata.app/docs/api/dates-and-times:

- Relative keywords: today, yesterday, tomorrow, now
- Relative offsets: -5 days, +1 week, -30 minutes
- Relative past: "X days ago", "X weeks ago"
- Option expiration: "this month's expiration", "next week's expiration"
- Option expiration: "expiration in X weeks"

This allows proper date range validation while still permitting
flexible relative date inputs that the API accepts.
Bump PHPUnit to a patched version, make act-wrapper failure detection robust, and make permission-path tests pass in non-applicable root/container contexts.
Updated PHPUnit from ^11.4.0 to ^11.5.50 in the CHANGELOG. Corrected the README example for bulkCandles to use separate array elements for symbols instead of a single string.
Switch phpdoc workflow to GitHub Pages Actions deploy, update template links to the repository Pages URL, and ignore local release-readiness artifacts.
Ignore docs output and keep only docs/.nojekyll tracked so local/generated phpdoc files no longer create commit noise.
Add a manual release workflow that runs full validation and test matrix before creating the version tag and GitHub Release, preventing bad tags from reaching Packagist.
@MarketDataApp MarketDataApp merged commit 772a11a into main Feb 20, 2026
19 checks passed
@MarketDataApp MarketDataApp deleted the update/php-8.2-8.5 branch February 20, 2026 17:40
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.

3 participants