Skip to content

Commit

Permalink
prepare 6.0.0 release (#183)
Browse files Browse the repository at this point in the history
## [6.0.0] - 2023-10-23
The latest version of this SDK supports the ability to manage migrations
or modernizations, using migration flags. You might use this
functionality if you are optimizing queries, upgrading to new tech
stacks, migrating from one database to another, or other similar
technology changes. Migration flags are part of LaunchDarkly's Early
Access Program. This feature is available to all LaunchDarkly customers
but may undergo additional changes before it is finalized.

For detailed information about this version, refer to the list below.
For information on how to upgrade from the previous version, read the
[migration
guide](https://docs.launchdarkly.com/sdk/server-side/php/migration-5-to-6).

### Added:
- A new `Migrator` type which provides an out-of-the-box configurable
migration framework.
- For more advanced use cases, added new `migrationVariation` and
`trackMigrationOperation` methods on `LDClient`.

### Removed:
- PHP 8.0 support was removed.
- The legacy user format for contexts is no longer supported. To learn
more, read the [Contexts
documentation](https://docs.launchdarkly.com/guides/flags/intro-contexts).
- Methods which originally took an `LDContext` or an `LDUser` now only
accept an `LDContext`.
- Previously deprecated test data flag builder methods
`variationForAllUsers`, `valueForAllUsers`, and `clearUserTargets` have
been removed.

---------

Co-authored-by: Eli Bishop <eli@launchdarkly.com>
Co-authored-by: LaunchDarklyCI <dev@launchdarkly.com>
Co-authored-by: Ben Woskow <48036130+bwoskow-ld@users.noreply.github.com>
Co-authored-by: Ben Woskow <bwoskow@launchdarkly.com>
Co-authored-by: Gavin Whelan <gwhelan@launchdarkly.com>
Co-authored-by: elliot <elliot@debian.elliot>
Co-authored-by: Elliot Haisley <35050275+Apache-HB@users.noreply.github.com>
Co-authored-by: Harpo Roeder <hroeder@launchdarkly.com>
Co-authored-by: LaunchDarklyReleaseBot <launchdarklyreleasebot@launchdarkly.com>
Co-authored-by: Ember Stevens <ember.stevens@launchdarkly.com>
Co-authored-by: ember-stevens <79482775+ember-stevens@users.noreply.github.com>
Co-authored-by: Matthew M. Keeler <keelerm84@gmail.com>
Co-authored-by: charukiewicz <charukiewicz@protonmail.com>
Co-authored-by: Joey Malinowski <joemalin95@gmail.com>
Co-authored-by: Christian Charukiewicz <christian@foxhound.systems>
Co-authored-by: Matthew M. Keeler <mkeeler@launchdarkly.com>
Co-authored-by: Colin Henwood <aretenz@users.noreply.github.com>
Co-authored-by: Colin Henwood <colin.henwood@xero.com>
Co-authored-by: Eli Bishop <35503443+eli-darkly@users.noreply.github.com>
Co-authored-by: hroederld <46500128+hroederld@users.noreply.github.com>
Co-authored-by: Louis Chan <lchan@launchdarkly.com>
Co-authored-by: ld-repository-standards[bot] <113625520+ld-repository-standards[bot]@users.noreply.github.com>
Co-authored-by: Kane Parkinson <93555788+kparkinson-ld@users.noreply.github.com>
Co-authored-by: Michiel Devriese <michieldevriese@gmail.com>
  • Loading branch information
25 people authored Oct 23, 2023
1 parent fa74322 commit cb0deb8
Show file tree
Hide file tree
Showing 47 changed files with 2,460 additions and 1,063 deletions.
2 changes: 1 addition & 1 deletion .circleci/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ workflows:
- test-on-linux:
matrix:
parameters:
php-version: ["8.0", "8.1"]
php-version: ["8.1", "8.2"]
composer-dependencies: ["lowest", "highest"]
- test-on-windows

Expand Down
5 changes: 3 additions & 2 deletions .ldrelease/config.yml
Original file line number Diff line number Diff line change
Expand Up @@ -10,12 +10,13 @@ publications:

branches:
- name: main
description: 5.x
description: 6.x
- name: 5.x
- name: 4.x

jobs:
- docker:
image: ldcircleci/php-sdk-release:4 # Releaser's default for PHP is still php-sdk-release:3, which is PHP 7.x
image: ldcircleci/php-sdk-release:5 # Releaser's default for PHP is still php-sdk-release:3, which is PHP 7.x
template:
name: php

Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@

## Supported PHP versions

This version of the LaunchDarkly SDK is compatible with PHP 8.0 and higher.
This version of the LaunchDarkly SDK is compatible with PHP 8.1 and higher.

## Getting started

Expand Down
25 changes: 0 additions & 25 deletions baseline.xml

This file was deleted.

6 changes: 3 additions & 3 deletions composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -14,17 +14,17 @@
}
],
"require": {
"php": ">=8.0",
"php": ">=8.1",
"monolog/monolog": "^2.0|^3.0",
"psr/log": "^1.0|^2.0|^3.0"
},
"require-dev": {
"friendsofphp/php-cs-fixer": "^3.12.0",
"friendsofphp/php-cs-fixer": "^3.15.0",
"guzzlehttp/guzzle": "^7",
"kevinrob/guzzle-cache-middleware": "^4.0",
"phpunit/php-code-coverage": "^9",
"phpunit/phpunit": "^9",
"vimeo/psalm": "^4.9"
"vimeo/psalm": "^5.15"
},
"suggest": {
"guzzlehttp/guzzle": "(^6.3 | ^7) Required when using GuzzleEventPublisher or the default FeatureRequester",
Expand Down
2 changes: 1 addition & 1 deletion phpunit.xml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
<?xml version="1.0"?>
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="tests/bootstrap.php" colors="true" beStrictAboutChangesToGlobalState="true" beStrictAboutOutputDuringTests="true" beStrictAboutResourceUsageDuringSmallTests="true" beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutTodoAnnotatedTests="true" verbose="true" defaultTimeLimit="10">
<phpunit xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:noNamespaceSchemaLocation="https://schema.phpunit.de/9.3/phpunit.xsd" bootstrap="vendor/autoload.php" colors="true" beStrictAboutChangesToGlobalState="true" beStrictAboutOutputDuringTests="true" beStrictAboutResourceUsageDuringSmallTests="true" beStrictAboutTestsThatDoNotTestAnything="true" beStrictAboutTodoAnnotatedTests="true" verbose="true" defaultTimeLimit="10">

<logging>
<junit outputFile="build/phpunit/junit.xml"/>
Expand Down
1 change: 0 additions & 1 deletion psalm.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns="https://getpsalm.org/schema/config"
xsi:schemaLocation="https://getpsalm.org/schema/config vendor/vimeo/psalm/config.xsd"
errorBaseline="baseline.xml"
>
<projectFiles>
<directory name="src" />
Expand Down
7 changes: 7 additions & 0 deletions src/LaunchDarkly/EvaluationReason.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,13 @@ class EvaluationReason implements \JsonSerializable
*/
const EXCEPTION_ERROR = 'EXCEPTION';

/**
* A possible value for getErrorKind(): indicates the value of the
* evaluation did not match the PHP type expected.
*/

const WRONG_TYPE_ERROR = 'WRONG_TYPE';

private string $_kind;
private ?string $_errorKind;
private ?int $_ruleIndex;
Expand Down
36 changes: 8 additions & 28 deletions src/LaunchDarkly/Impl/Events/EventFactory.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,14 @@ public function newEvalEvent(
'default' => $default,
'version' => $flag->getVersion()
];

// the following properties are handled separately so we don't waste bandwidth on unused keys
if ($flag->getExcludeFromSummaries()) {
$e['excludeFromSummaries'] = true;
}
if ($flag->getSamplingRatio() !== 1) {
$e['samplingRatio'] = $flag->getSamplingRatio();
}
if ($forceReasonTracking || $flag->isTrackEvents()) {
$e['trackEvents'] = true;
}
Expand All @@ -66,33 +73,6 @@ public function newEvalEvent(
return $e;
}

/**
* @return mixed[]
*/
public function newDefaultEvent(FeatureFlag $flag, LDContext $context, EvaluationDetail $detail): array
{
$e = [
'kind' => 'feature',
'creationDate' => Util::currentTimeUnixMillis(),
'key' => $flag->getKey(),
'context' => $context,
'value' => $detail->getValue(),
'default' => $detail->getValue(),
'version' => $flag->getVersion()
];
// the following properties are handled separately so we don't waste bandwidth on unused keys
if ($flag->isTrackEvents()) {
$e['trackEvents'] = true;
}
if ($flag->getDebugEventsUntilDate()) {
$e['debugEventsUntilDate'] = $flag->getDebugEventsUntilDate();
}
if ($this->_withReasons) {
$e['reason'] = $detail->getReason()->jsonSerialize();
}
return $e;
}

/**
* @return mixed[]
*/
Expand Down Expand Up @@ -124,7 +104,7 @@ public function newIdentifyEvent(LDContext $context): array
'context' => $context
];
}

/**
* @return mixed[]
*/
Expand Down
10 changes: 9 additions & 1 deletion src/LaunchDarkly/Impl/Events/EventProcessor.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

namespace LaunchDarkly\Impl\Events;

use LaunchDarkly\Impl\Util;
use LaunchDarkly\Integrations\Curl;
use LaunchDarkly\Subsystems\EventPublisher;

Expand All @@ -21,7 +22,7 @@ class EventProcessor
private int $_capacity;

/**
* @psalm-param array{capacity: int} $options
* @param array<string, mixed> $options
*/
public function __construct(string $sdkKey, array $options)
{
Expand Down Expand Up @@ -50,6 +51,13 @@ public function enqueue(array $event): bool
return false;
}

if (isset($event['samplingRatio'])) {
$samplingRatio = $event['samplingRatio'];
if (is_int($samplingRatio) && !Util::sample($samplingRatio)) {
return false;
}
}

$this->_queue[] = $event;

return true;
Expand Down
56 changes: 56 additions & 0 deletions src/LaunchDarkly/Impl/Migrations/Executor.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
<?php

declare(strict_types=1);

namespace LaunchDarkly\Impl\Migrations;

use Closure;
use Exception;
use LaunchDarkly\Impl\Util;
use LaunchDarkly\Migrations\OperationResult;
use LaunchDarkly\Migrations\OpTracker;
use LaunchDarkly\Migrations\Origin;
use LaunchDarkly\Types\Result;

/**
* Utility class for executing migration operations while also tracking our
* built-in migration measurements.
*/
class Executor
{
/**
* @param Closure(mixed): Result $fn
*/
public function __construct(
public readonly Origin $origin,
private Closure $fn,
private OpTracker $tracker,
private bool $trackLatency,
private bool $trackErrors,
private mixed $payload,
) {
}

public function run(): OperationResult
{
$start = Util::currentTimeUnixMillis();

try {
$result = ($this->fn)($this->payload);
} catch (Exception $e) {
$result = Result::error($e->getMessage(), $e);
}

if ($this->trackLatency) {
$this->tracker->latency($this->origin, Util::currentTimeUnixMillis() - $start);
}

if ($this->trackErrors && !$result->isSuccessful()) {
$this->tracker->error($this->origin);
}

$this->tracker->invoked($this->origin);

return new OperationResult($this->origin, $result);
}
}
42 changes: 38 additions & 4 deletions src/LaunchDarkly/Impl/Model/FeatureFlag.php
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ class FeatureFlag
protected bool $_trackEventsFallthrough = false;
protected ?int $_debugEventsUntilDate = null;
protected bool $_clientSide = false;
protected ?int $_samplingRatio = null;
protected bool $_excludeFromSummaries = false;
protected ?MigrationSettings $_migrationSettings = null;

// Note, trackEvents and debugEventsUntilDate are not used in EventProcessor, because
// the PHP client doesn't do summary events. However, we need to capture them in case
Expand All @@ -55,7 +58,10 @@ public function __construct(
bool $trackEvents,
bool $trackEventsFallthrough,
?int $debugEventsUntilDate,
bool $clientSide
bool $clientSide,
?int $samplingRatio,
bool $excludeFromSummaries,
?MigrationSettings $migrationSettings,
) {
$this->_key = $key;
$this->_version = $version;
Expand All @@ -73,6 +79,9 @@ public function __construct(
$this->_trackEventsFallthrough = $trackEventsFallthrough;
$this->_debugEventsUntilDate = $debugEventsUntilDate;
$this->_clientSide = $clientSide;
$this->_samplingRatio = $samplingRatio;
$this->_excludeFromSummaries = $excludeFromSummaries;
$this->_migrationSettings = $migrationSettings;
}

/**
Expand All @@ -82,8 +91,14 @@ public function __construct(
*/
public static function getDecoder(): \Closure
{
return fn ($v) =>
new FeatureFlag(
return function ($v) {
$migrationSettings = null;

if (is_array($v['migration'] ?? null)) {
$migrationSettings = call_user_func(MigrationSettings::getDecoder(), $v['migration']);
}

return new FeatureFlag(
$v['key'],
$v['version'],
$v['on'],
Expand All @@ -99,8 +114,12 @@ public static function getDecoder(): \Closure
!!($v['trackEvents'] ?? false),
!!($v['trackEventsFallthrough'] ?? false),
$v['debugEventsUntilDate'] ?? null,
!!($v['clientSide'] ?? false)
!!($v['clientSide'] ?? false),
$v['samplingRatio'] ?? null,
!!($v['excludeFromSummaries'] ?? false),
$migrationSettings,
);
};
}

public static function decode(array $v): self
Expand Down Expand Up @@ -192,4 +211,19 @@ public function getVersion(): int
{
return $this->_version;
}

public function getSamplingRatio(): int
{
return $this->_samplingRatio ?? 1;
}

public function getExcludeFromSummaries(): bool
{
return $this->_excludeFromSummaries;
}

public function getMigrationSettings(): ?MigrationSettings
{
return $this->_migrationSettings;
}
}
30 changes: 30 additions & 0 deletions src/LaunchDarkly/Impl/Model/MigrationSettings.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
<?php

declare(strict_types=1);

namespace LaunchDarkly\Impl\Model;

/**
* Internal data model class that describes a feature flag's migration settings.
*
* Application code should never need to reference the data model directly.
*
* @ignore
* @internal
*/
class MigrationSettings
{
public function __construct(private readonly ?int $checkRatio = null)
{
}

public function getCheckRatio(): int
{
return $this->checkRatio ?? 1;
}

public static function getDecoder(): \Closure
{
return fn (array $v) => new MigrationSettings($v['checkRatio'] ?? null);
}
}
4 changes: 2 additions & 2 deletions src/LaunchDarkly/Impl/SemanticVersion.php
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
*/
class SemanticVersion
{
private static string $REGEX = '/^(?<major>0|[1-9]\d*)(\.(?<minor>0|[1-9]\d*))?(\.(?<patch>0|[1-9]\d*))?(\-(?<prerel>[0-9A-Za-z\-\.]+))?(\+(?<build>[0-9A-Za-z\-\.]+))?$/';
private const REGEX = '/^(?<major>0|[1-9]\d*)(\.(?<minor>0|[1-9]\d*))?(\.(?<patch>0|[1-9]\d*))?(\-(?<prerel>[0-9A-Za-z\-\.]+))?(\+(?<build>[0-9A-Za-z\-\.]+))?$/';

public int $major;
public int $minor;
Expand Down Expand Up @@ -47,7 +47,7 @@ public function __construct(
*/
public static function parse(string $input, bool $loose = false): SemanticVersion
{
if (!preg_match(self::$REGEX, $input, $matches)) {
if (!preg_match(self::REGEX, $input, $matches)) {
throw new \InvalidArgumentException("not a valid semantic version");
}
$major = intval($matches['major']);
Expand Down
Loading

0 comments on commit cb0deb8

Please sign in to comment.