Skip to content

Commit 587ea9f

Browse files
committed
feat: fixup
Assisted-by: ClaudeCode:claude-opus-4-8 Signed-off-by: Ferdinand Thiessen <opensource@fthiessen.de>
1 parent 7d4b495 commit 587ea9f

12 files changed

Lines changed: 1154 additions & 185 deletions
Lines changed: 157 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,157 @@
1+
# This workflow is provided via the organization template repository
2+
#
3+
# https://github.com/nextcloud/.github
4+
# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization
5+
#
6+
# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
7+
# SPDX-License-Identifier: MIT
8+
9+
name: PHPUnit key-value store
10+
11+
on:
12+
pull_request:
13+
schedule:
14+
- cron: "5 2 * * *"
15+
16+
permissions:
17+
contents: read
18+
19+
concurrency:
20+
group: phpunit-kvstore-${{ github.head_ref || github.run_id }}
21+
cancel-in-progress: true
22+
23+
env:
24+
# Official Valkey image, see https://hub.docker.com/r/valkey/valkey
25+
VALKEY_IMAGE: valkey/valkey:8
26+
27+
jobs:
28+
changes:
29+
runs-on: ubuntu-latest-low
30+
31+
outputs:
32+
src: ${{ steps.changes.outputs.src}}
33+
34+
steps:
35+
- uses: dorny/paths-filter@fbd0ab8f3e69293af611ebaee6363fc25e6d187d # v4.0.1
36+
id: changes
37+
continue-on-error: true
38+
with:
39+
filters: |
40+
src:
41+
- '.github/workflows/**'
42+
- '3rdparty/**'
43+
- '**/appinfo/**'
44+
- '**/lib/**'
45+
- '**/templates/**'
46+
- '**/tests/**'
47+
- 'vendor/**'
48+
- 'vendor-bin/**'
49+
- '.php-cs-fixer.dist.php'
50+
- 'composer.json'
51+
- 'composer.lock'
52+
- '**.php'
53+
54+
phpunit-kvstore:
55+
runs-on: ubuntu-latest
56+
57+
needs: changes
58+
if: needs.changes.outputs.src != 'false'
59+
60+
strategy:
61+
fail-fast: false
62+
matrix:
63+
php-versions: ["8.3", "8.5"]
64+
# The three supported topologies for the key-value store cache
65+
topology: ["single", "cluster", "sentinel"]
66+
67+
name: KV store ${{ matrix.topology }} (PHP ${{ matrix.php-versions }})
68+
69+
steps:
70+
- name: Checkout server
71+
uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0
72+
with:
73+
persist-credentials: false
74+
submodules: true
75+
76+
- name: Set up php ${{ matrix.php-versions }}
77+
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 #v2.37.2
78+
timeout-minutes: 5
79+
with:
80+
php-version: ${{ matrix.php-versions }}
81+
# https://docs.nextcloud.com/server/stable/admin_manual/installation/source_installation.html#prerequisites-for-manual-installation
82+
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, pdo_sqlite, posix, session, simplexml, sqlite, xmlreader, xmlwriter, zip, zlib
83+
coverage: none
84+
ini-file: development
85+
ini-values: disable_functions=""
86+
env:
87+
fail-fast: true
88+
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
89+
90+
- name: Start Valkey (single server)
91+
if: matrix.topology == 'single'
92+
run: |
93+
docker run -d --name kv-single -p 6379:6379 "${VALKEY_IMAGE}"
94+
timeout 60 sh -c 'until docker exec kv-single valkey-cli ping | grep -q PONG; do sleep 1; done'
95+
96+
- name: Start Valkey (cluster)
97+
if: matrix.topology == 'cluster'
98+
run: |
99+
for port in 7000 7001 7002 7003 7004 7005; do
100+
docker run -d --name "kv-cluster-$port" --network host "${VALKEY_IMAGE}" \
101+
valkey-server --port "$port" --cluster-enabled yes \
102+
--cluster-config-file "nodes-$port.conf" --cluster-node-timeout 5000 \
103+
--appendonly no --save ""
104+
done
105+
# Wait for every node to answer before forming the cluster
106+
for port in 7000 7001 7002 7003 7004 7005; do
107+
timeout 60 sh -c "until docker exec kv-cluster-$port valkey-cli -p $port ping | grep -q PONG; do sleep 1; done"
108+
done
109+
docker exec kv-cluster-7000 valkey-cli --cluster create \
110+
127.0.0.1:7000 127.0.0.1:7001 127.0.0.1:7002 \
111+
127.0.0.1:7003 127.0.0.1:7004 127.0.0.1:7005 \
112+
--cluster-replicas 1 --cluster-yes
113+
114+
- name: Start Valkey (sentinel)
115+
if: matrix.topology == 'sentinel'
116+
run: |
117+
docker run -d --name kv-master --network host "${VALKEY_IMAGE}" \
118+
valkey-server --port 6379
119+
docker run -d --name kv-replica --network host "${VALKEY_IMAGE}" \
120+
valkey-server --port 6380 --replicaof 127.0.0.1 6379
121+
printf 'port 26379\nsentinel monitor mymaster 127.0.0.1 6379 1\nsentinel down-after-milliseconds mymaster 5000\nsentinel failover-timeout mymaster 10000\n' > sentinel.conf
122+
docker run -d --name kv-sentinel --network host -v "$PWD/sentinel.conf:/etc/valkey/sentinel.conf" \
123+
"${VALKEY_IMAGE}" valkey-sentinel /etc/valkey/sentinel.conf
124+
timeout 60 sh -c 'until docker exec kv-sentinel valkey-cli -p 26379 ping | grep -q PONG; do sleep 1; done'
125+
126+
- name: Set up dependencies
127+
run: composer i
128+
129+
- name: Set up Nextcloud
130+
run: |
131+
mkdir data
132+
cp tests/kvstore-${{ matrix.topology }}.config.php config/
133+
cp tests/preseed-config.php config/config.php
134+
./occ maintenance:install --verbose --database=sqlite --database-name=nextcloud --database-user=root --database-pass=rootpassword --admin-user admin --admin-pass admin
135+
php -f tests/enable_all.php
136+
137+
- name: PHPUnit key-value store tests
138+
run: composer run test -- --group KeyValueCache --log-junit junit.xml
139+
140+
- name: Print logs
141+
if: always()
142+
run: |
143+
cat data/nextcloud.log
144+
145+
summary:
146+
permissions:
147+
contents: none
148+
runs-on: ubuntu-latest-low
149+
needs: [changes, phpunit-kvstore]
150+
151+
if: always()
152+
153+
name: phpunit-kvstore-summary
154+
155+
steps:
156+
- name: Summary status
157+
run: if ${{ needs.changes.outputs.src != 'false' && needs.phpunit-kvstore.result != 'success' }}; then exit 1; fi

config/config.sample.php

Lines changed: 71 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1769,28 +1769,84 @@
17691769
'memcache_customprefix' => 'mycustomprefix',
17701770

17711771
/**
1772-
* Connection details for the Key-Value store used for in-memory caching.
1773-
* For example when using Redis or Valkey.
1772+
* Connection details for the Key-Value store used for in-memory caching,
1773+
* for example when using Valkey or Redis.
1774+
*
1775+
* This is the brand-independent successor of the ``redis`` and
1776+
* ``redis.cluster`` options below and supports the latest Valkey and Redis
1777+
* releases through the bundled ``predis`` client. Three topologies are
1778+
* supported: a single server, a Sentinel managed replication set, and a
1779+
* server cluster. Configure exactly one of ``server``, ``sentinel`` or
1780+
* ``seeds``.
17741781
*
17751782
* For enhanced security, it is recommended to configure ACLs in
1776-
* the cache server and configure the user and password (or TLS certificate).
1777-
* Alternatively, you can also configure the cache server to just use a password.
1783+
* the cache server and configure the ``user`` and ``password`` (or a TLS
1784+
* client certificate). Alternatively, you can also configure the cache
1785+
* server to just use a ``password``.
17781786
* See https://valkey.io/topics/security/ for more information when using Valkey.
17791787
*/
17801788
'memcache.kvstore' => [
1781-
// Server setup when using a single server or Sentinel setup
1789+
/**
1790+
* Single server setup.
1791+
*
1792+
* Also used as the connection template for the ``sentinel`` managed
1793+
* primary / replica connections.
1794+
*/
17821795
'server' => [
17831796
'host' => 'localhost', // can also be a Unix domain socket: '/tmp/cache.sock'
1784-
'port' => 6379, // not used for Unix domain sockets
1785-
// The protocol used for connecting to the cache server. Supported values are 'tcp', 'tls', and 'unix'.
1797+
'port' => 6379, // ignored for Unix domain sockets
1798+
// Protocol used to connect. One of 'tcp', 'tls' or 'unix'.
1799+
// When omitted it is derived from the host (a leading '/' means 'unix').
17861800
'protocol' => 'tcp',
17871801
],
1788-
// When using a server cluster the seed servers to use.
1789-
// The format of each seed entry is the same as the `server` entry above.
1790-
'seeds' => [
1791-
[],
1792-
[],
1793-
]
1802+
1803+
/**
1804+
* Sentinel managed replication setup.
1805+
*
1806+
* Provide the name of the monitored service and one entry per Sentinel
1807+
* node. Each seed uses the same format as the ``server`` entry above.
1808+
* Uncomment to enable and remove the ``server`` / ``seeds`` entries.
1809+
*/
1810+
//'sentinel' => [
1811+
// 'service' => 'mymaster',
1812+
// 'seeds' => [
1813+
// ['host' => 'localhost', 'port' => 26379],
1814+
// ['host' => 'localhost', 'port' => 26380],
1815+
// ],
1816+
//],
1817+
1818+
/**
1819+
* Cluster setup.
1820+
*
1821+
* Provide some or all of the cluster nodes to bootstrap discovery.
1822+
* Each seed uses the same format as the ``server`` entry above.
1823+
* Uncomment to enable and remove the ``server`` / ``sentinel`` entries.
1824+
*/
1825+
//'seeds' => [
1826+
// ['host' => 'localhost', 'port' => 7000],
1827+
// ['host' => 'localhost', 'port' => 7001],
1828+
//],
1829+
1830+
// Optional: username, only sent when the cache server uses ACLs.
1831+
'user' => '',
1832+
// Optional: if not defined, no password will be used.
1833+
'password' => '',
1834+
// Optional: select a numbered database. Only supported for single
1835+
// servers and Sentinel setups, clusters always use database 0.
1836+
'dbindex' => 0,
1837+
// Optional: connection timeout in seconds (float). 0 means no timeout.
1838+
'timeout' => 0.0,
1839+
// Optional: read/write timeout in seconds (float). 0 means no timeout.
1840+
'read_timeout' => 0.0,
1841+
// Optional: keep the connection open across requests. Defaults to false.
1842+
'persistent' => false,
1843+
// Optional: when the 'tls' protocol is used, provide the SSL context.
1844+
// SSL context options, see https://www.php.net/manual/en/context.ssl.php
1845+
//'ssl_context' => [
1846+
// 'local_cert' => '/certs/cache.crt',
1847+
// 'local_pk' => '/certs/cache.key',
1848+
// 'cafile' => '/certs/ca.crt',
1849+
//],
17941850
],
17951851

17961852
/**
@@ -1843,6 +1899,8 @@
18431899
*
18441900
* Authentication works with phpredis version 4.2.1+. See
18451901
* https://github.com/phpredis/phpredis/commit/c5994f2a42b8a348af92d3acb4edff1328ad8ce1
1902+
*
1903+
* @deprecated 34.0.0 use `memcache.kvstore` instead which supports also Valkey.
18461904
*/
18471905
'redis.cluster' => [
18481906
'seeds' => [ // provide some or all of the cluster servers to bootstrap discovery, port required

0 commit comments

Comments
 (0)