From 1611b33e4adfe468457e8a65f7dbfdcadab0f645 Mon Sep 17 00:00:00 2001 From: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> Date: Tue, 2 Jun 2026 19:28:39 +0300 Subject: [PATCH 1/6] Updated 8.8 GA test image (#1679) --- .github/workflows/tests.yml | 2 +- CHANGELOG.md | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 542979c0..2e68612f 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -42,7 +42,7 @@ jobs: run: | # Mapping of original redis versions to client test containers declare -A redis_clients_version_mapping=( - ["8.8"]="custom-26235535976-debian" + ["8.8"]="8.8.0" ["8.6"]="8.6.1" ["8.4"]="8.4.0" ["8.2"]="8.2.2" diff --git a/CHANGELOG.md b/CHANGELOG.md index 18ae327d..10e0ede6 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -15,6 +15,7 @@ - Include command name in unsupported container command error messages (#1653) - Updated arguments name for GCRA command (#1667) - Updated INCREX arguments (#1677) +- Updated 8.8 GA test image (#1679) ### Fixed - Fixed handling of gap slots in `SlotMap::offsetUnset()` (#1660) From 135b405eae3b7f29716e6031865d558dfc110b1f Mon Sep 17 00:00:00 2001 From: Vladyslav Vildanov <117659936+vladvildanov@users.noreply.github.com> Date: Tue, 2 Jun 2026 19:28:57 +0300 Subject: [PATCH 2/6] Added support for UNLINK command (#1680) --- CHANGELOG.md | 1 + src/ClientContextInterface.php | 1 + src/ClientInterface.php | 1 + src/Cluster/ClusterStrategy.php | 1 + src/Command/Redis/UNLINK.php | 34 ++++++ tests/Predis/Cluster/PredisStrategyTest.php | 1 + tests/Predis/Cluster/RedisStrategyTest.php | 1 + tests/Predis/Command/Redis/UNLINK_Test.php | 120 ++++++++++++++++++++ 8 files changed, 160 insertions(+) create mode 100644 src/Command/Redis/UNLINK.php create mode 100644 tests/Predis/Command/Redis/UNLINK_Test.php diff --git a/CHANGELOG.md b/CHANGELOG.md index 10e0ede6..3afe75cf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -10,6 +10,7 @@ - Added testing for subkey notification channels (#1671) - Added support for new array commands (#1672) - Added support for INCREX command (#1674) +- Added support for UNLINK command (#1680) ### Changed - Include command name in unsupported container command error messages (#1653) diff --git a/src/ClientContextInterface.php b/src/ClientContextInterface.php index d3eada45..0425ef2d 100644 --- a/src/ClientContextInterface.php +++ b/src/ClientContextInterface.php @@ -77,6 +77,7 @@ use Predis\Command\Redis\VADD; * @method $this sort_ro(string $key, ?string $byPattern = null, ?LimitOffsetCount $limit = null, array $getPatterns = [], ?string $sorting = null, bool $alpha = false) * @method $this ttl($key) * @method $this type($key) + * @method $this unlink(string ...$keys) * @method $this append($key, $value) * @method $this arcount(string $key) * @method $this ardel(string $key, int ...$index) diff --git a/src/ClientInterface.php b/src/ClientInterface.php index ceadec02..1a3fd8e1 100644 --- a/src/ClientInterface.php +++ b/src/ClientInterface.php @@ -87,6 +87,7 @@ use Predis\Response\Status; * @method array sort_ro(string $key, ?string $byPattern = null, ?LimitOffsetCount $limit = null, array $getPatterns = [], ?string $sorting = null, bool $alpha = false) * @method int ttl(string $key) * @method mixed type(string $key) + * @method int unlink(string ...$keys) * @method int append(string $key, $value) * @method int arcount(string $key) * @method int ardel(string $key, int ...$index) diff --git a/src/Cluster/ClusterStrategy.php b/src/Cluster/ClusterStrategy.php index 6ed3a8d8..16064b06 100644 --- a/src/Cluster/ClusterStrategy.php +++ b/src/Cluster/ClusterStrategy.php @@ -42,6 +42,7 @@ abstract class ClusterStrategy implements StrategyInterface /* commands operating on the key space */ 'EXISTS' => $getKeyFromAllArguments, 'DEL' => $getKeyFromAllArguments, + 'UNLINK' => $getKeyFromAllArguments, 'TYPE' => $getKeyFromFirstArgument, 'EXPIRE' => $getKeyFromFirstArgument, 'EXPIREAT' => $getKeyFromFirstArgument, diff --git a/src/Command/Redis/UNLINK.php b/src/Command/Redis/UNLINK.php new file mode 100644 index 00000000..c9c0fd07 --- /dev/null +++ b/src/Command/Redis/UNLINK.php @@ -0,0 +1,34 @@ +applyPrefixForAllArguments($prefix); + } +} diff --git a/tests/Predis/Cluster/PredisStrategyTest.php b/tests/Predis/Cluster/PredisStrategyTest.php index 3be751e5..1679f210 100644 --- a/tests/Predis/Cluster/PredisStrategyTest.php +++ b/tests/Predis/Cluster/PredisStrategyTest.php @@ -369,6 +369,7 @@ class PredisStrategyTest extends PredisTestCase /* commands operating on the key space */ 'EXISTS' => 'keys-all', 'DEL' => 'keys-all', + 'UNLINK' => 'keys-all', 'TYPE' => 'keys-first', 'EXPIRE' => 'keys-first', 'EXPIREAT' => 'keys-first', diff --git a/tests/Predis/Cluster/RedisStrategyTest.php b/tests/Predis/Cluster/RedisStrategyTest.php index 9e4a9595..d23b53c3 100644 --- a/tests/Predis/Cluster/RedisStrategyTest.php +++ b/tests/Predis/Cluster/RedisStrategyTest.php @@ -392,6 +392,7 @@ class RedisStrategyTest extends PredisTestCase /* commands operating on the key space */ 'EXISTS' => 'keys-all', 'DEL' => 'keys-all', + 'UNLINK' => 'keys-all', 'TYPE' => 'keys-first', 'EXPIRE' => 'keys-first', 'EXPIREAT' => 'keys-first', diff --git a/tests/Predis/Command/Redis/UNLINK_Test.php b/tests/Predis/Command/Redis/UNLINK_Test.php new file mode 100644 index 00000000..6122ff27 --- /dev/null +++ b/tests/Predis/Command/Redis/UNLINK_Test.php @@ -0,0 +1,120 @@ +getCommand(); + $command->setArguments($arguments); + $this->assertSame($expected, $command->getArguments()); + } + + /** + * @group disconnected + */ + public function testParseResponse(): void + { + $command = $this->getCommand(); + + $this->assertSame(10, $command->parseResponse(10)); + } + + /** + * @group disconnected + */ + public function testPrefixKeys(): void + { + /** @var PrefixableCommand $command */ + $command = $this->getCommand(); + $actualArguments = ['arg1', 'arg2', 'arg3', 'arg4']; + $prefix = 'prefix:'; + $expectedArguments = ['prefix:arg1', 'prefix:arg2', 'prefix:arg3', 'prefix:arg4']; + + $command->setArguments($actualArguments); + $command->prefixKeys($prefix); + + $this->assertSame($expectedArguments, $command->getArguments()); + } + + /** + * @group connected + * @requiresRedisVersion >= 4.0.0 + */ + public function testReturnsNumberOfUnlinkedKeys(): void + { + $redis = $this->getClient(); + + $this->assertSame(0, $redis->unlink('foo')); + + $redis->set('foo', 'bar'); + $this->assertSame(1, $redis->unlink('foo')); + + $redis->set('foo', 'bar'); + $this->assertSame(1, $redis->unlink('foo', 'hoge')); + + $redis->set('foo', 'bar'); + $redis->set('hoge', 'piyo'); + $this->assertSame(2, $redis->unlink('foo', 'hoge')); + } + + /** + * @group connected + * @requiresRedisVersion >= 6.0.0 + */ + public function testReturnsNumberOfUnlinkedKeysResp3(): void + { + $redis = $this->getResp3Client(); + + $this->assertSame(0, $redis->unlink('foo')); + + $redis->set('foo', 'bar'); + $this->assertSame(1, $redis->unlink('foo')); + + $redis->set('foo', 'bar'); + $this->assertSame(1, $redis->unlink('foo', 'hoge')); + + $redis->set('foo', 'bar'); + $redis->set('hoge', 'piyo'); + $this->assertSame(2, $redis->unlink('foo', 'hoge')); + } +} From 5d1d9fdf11bd2e74b998b79f6016e376ed483218 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Till=20Kr=C3=BCss?= Date: Tue, 2 Jun 2026 10:18:37 -0700 Subject: [PATCH 3/6] Add dependabot configuration for GitHub Actions and Composer --- .github/.github/dependabot.yml | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 .github/.github/dependabot.yml diff --git a/.github/.github/dependabot.yml b/.github/.github/dependabot.yml new file mode 100644 index 00000000..b9d8ebea --- /dev/null +++ b/.github/.github/dependabot.yml @@ -0,0 +1,20 @@ +version: 2 +updates: + - package-ecosystem: "github-actions" + directory: / + schedule: + interval: "monthly" + groups: + github-actions: + patterns: + - "*" + + - package-ecosystem: "composer" + directory: / + schedule: + interval: "monthly" + groups: + composer-minor: + update-types: + - "minor" + - "patch" From 3da5d996bd2839f229db41d71f86db2a080a1ea9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Till=20Kr=C3=BCss?= Date: Tue, 2 Jun 2026 10:20:38 -0700 Subject: [PATCH 4/6] move file --- .github/{.github => }/dependabot.yml | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename .github/{.github => }/dependabot.yml (100%) diff --git a/.github/.github/dependabot.yml b/.github/dependabot.yml similarity index 100% rename from .github/.github/dependabot.yml rename to .github/dependabot.yml From 84c77ea460e974745c9a753e2ea518983a5f7767 Mon Sep 17 00:00:00 2001 From: "dependabot[bot]" <49699333+dependabot[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 10:32:02 -0700 Subject: [PATCH 5/6] Bump the github-actions group with 5 updates (#1683) --- .github/workflows/linters.yml | 16 ++++++++-------- .github/workflows/release-drafter.yml | 2 +- .github/workflows/spellcheck.yml | 4 ++-- .github/workflows/tests.yml | 14 +++++++------- 4 files changed, 18 insertions(+), 18 deletions(-) diff --git a/.github/workflows/linters.yml b/.github/workflows/linters.yml index 72a72ac6..9b8cde24 100644 --- a/.github/workflows/linters.yml +++ b/.github/workflows/linters.yml @@ -24,7 +24,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Check file permissions run: test "$(find . -type f -not -path './.git/*' -executable)" = "./bin/create-command-test" @@ -47,7 +47,7 @@ jobs: tools: parallel-lint - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Check source code for syntax errors run: composer exec -- parallel-lint bin/ examples/ src/ tests/ @@ -67,13 +67,13 @@ jobs: coverage: none - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Validate Composer configuration run: composer validate --no-interaction --strict - name: Install dependencies - uses: ramsey/composer-install@v2 + uses: ramsey/composer-install@v4 with: dependency-versions: highest @@ -101,7 +101,7 @@ jobs: coverage: none - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Check EditorConfig configuration run: test -f .editorconfig @@ -110,7 +110,7 @@ jobs: uses: greut/eclint-action@v0 - name: Install dependencies - uses: ramsey/composer-install@v2 + uses: ramsey/composer-install@v4 with: dependency-versions: highest @@ -130,7 +130,7 @@ jobs: steps: - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Check exported files run: | @@ -159,7 +159,7 @@ jobs: steps: - name: Checkout - uses: actions/checkout@v4 + uses: actions/checkout@v6 with: fetch-depth: 0 diff --git a/.github/workflows/release-drafter.yml b/.github/workflows/release-drafter.yml index f66dd94e..c16798ae 100644 --- a/.github/workflows/release-drafter.yml +++ b/.github/workflows/release-drafter.yml @@ -27,7 +27,7 @@ jobs: steps: - - uses: release-drafter/release-drafter@v5 + - uses: release-drafter/release-drafter@v7 with: config-name: release-drafter-config.yml env: diff --git a/.github/workflows/spellcheck.yml b/.github/workflows/spellcheck.yml index e1528415..989149a5 100644 --- a/.github/workflows/spellcheck.yml +++ b/.github/workflows/spellcheck.yml @@ -6,9 +6,9 @@ jobs: runs-on: ubuntu-latest steps: - name: Checkout - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Check Spelling - uses: rojopolis/spellcheck-github-actions@0.33.1 + uses: rojopolis/spellcheck-github-actions@0.60.0 with: config_path: .github/spellcheck-settings.yml task_name: Markdown diff --git a/.github/workflows/tests.yml b/.github/workflows/tests.yml index 2e68612f..d1980285 100644 --- a/.github/workflows/tests.yml +++ b/.github/workflows/tests.yml @@ -78,16 +78,16 @@ jobs: fi - name: Checkout repository - uses: actions/checkout@v3 + uses: actions/checkout@v6 - name: Start Redis standalone image - uses: hoverkraft-tech/compose-action@v2.0.1 + uses: hoverkraft-tech/compose-action@v2.6.0 with: compose-file: .github/docker-compose.yml services: ${{ env.DOCKER_SERVICE }} - name: Start Redis unprotected image - uses: hoverkraft-tech/compose-action@v2.0.1 + uses: hoverkraft-tech/compose-action@v2.6.0 if: ${{ matrix.redis > '4.0' }} with: compose-file: .github/docker-compose.yml @@ -95,7 +95,7 @@ jobs: - name: Start Redis stack image id: stack_infra - uses: hoverkraft-tech/compose-action@v2.0.1 + uses: hoverkraft-tech/compose-action@v2.6.0 if: ${{ matrix.redis >= '7.2' && matrix.redis < '8.0' }} with: compose-file: .github/docker-compose.yml @@ -103,7 +103,7 @@ jobs: - name: Start Redis cluster image id: cluster_infra - uses: hoverkraft-tech/compose-action@v2.0.1 + uses: hoverkraft-tech/compose-action@v2.6.0 if: ${{ matrix.redis > '4.0' }} with: compose-file: .github/docker-compose.yml @@ -111,7 +111,7 @@ jobs: - name: Start Redis sentinels image id: sentinel_infra - uses: hoverkraft-tech/compose-action@v2.0.1 + uses: hoverkraft-tech/compose-action@v2.6.0 if: ${{ matrix.redis > '4.0' }} with: compose-file: .github/docker-compose.yml @@ -125,7 +125,7 @@ jobs: coverage: ${{ (matrix.php == '8.4' && matrix.redis == '8.0') && 'xdebug' || 'none' }} - name: Install Composer dependencies - uses: ramsey/composer-install@v2 + uses: ramsey/composer-install@v4 with: dependency-versions: highest composer-options: ${{ matrix.php == '8.0' && '--ignore-platform-reqs' || '' }} From 8cc4319c06924c8ff0c5c7eec4243a19e3be32f1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Till=20Kr=C3=BCss?= Date: Tue, 2 Jun 2026 12:25:56 -0700 Subject: [PATCH 6/6] Prepare 3.5.0 (#1682) --- CHANGELOG.md | 26 +++++++++++--------------- VERSION | 2 +- src/Client.php | 2 +- 3 files changed, 13 insertions(+), 17 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3afe75cf..d9bde89b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,28 +1,24 @@ ## Changelog -## Unreleased +## v3.5.0 (2026-06-02) ### Added +- Added support for `XNACK` command (#1666) +- Added support for `INCREX` command (#1674) +- Added support for `UNLINK` command (#1680) +- Added support for `AR*` array commands (#1672) - Handle Redis Cluster `-READONLY` responses failover events (#1656) -- Added FPHA argument for JSON.SET command (#1661) -- Added new COUNT aggregator for Sorted Set commands (#1668) -- Added XNACK support (#1666) -- Added support for multiple aggregators for TS range commands (#1670) -- Added testing for subkey notification channels (#1671) -- Added support for new array commands (#1672) -- Added support for INCREX command (#1674) -- Added support for UNLINK command (#1680) +- Added `FPHA` argument for `JSON.SET` command (#1661) +- Added new `COUNT` aggregator for Sorted Set commands (#1668) +- Added support for multiple aggregators for `TS.range` commands (#1670) ### Changed - Include command name in unsupported container command error messages (#1653) -- Updated arguments name for GCRA command (#1667) -- Updated INCREX arguments (#1677) -- Updated 8.8 GA test image (#1679) ### Fixed - Fixed handling of gap slots in `SlotMap::offsetUnset()` (#1660) -- Fixed ZRANGE to include 6.2 arguments (#1662) -- Fixed Sentinel retry to narrow retryable exceptions to CommunicationException (#1665) -- Fixed SENTINEL SLAVES RESP3 incompatible response (#1676) +- Fixed `ZRANGE` to include 6.2 arguments (#1662) +- Fixed Sentinel retry to narrow retryable exceptions to `CommunicationException` (#1665) +- Fixed `SENTINEL SLAVES` RESP3 incompatible response (#1676) ## v3.4.2 (2026-03-09) ### Changed diff --git a/VERSION b/VERSION index 4f357096..e5b82034 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -3.4.3-dev \ No newline at end of file +3.5.0 \ No newline at end of file diff --git a/src/Client.php b/src/Client.php index f9bcdc9a..d11a677e 100644 --- a/src/Client.php +++ b/src/Client.php @@ -56,7 +56,7 @@ use Traversable; */ class Client implements ClientInterface, IteratorAggregate { - public const VERSION = '3.4.3-dev'; + public const VERSION = '3.5.0'; /** @var OptionsInterface */ private $options;