Skip to content

Commit f1552c9

Browse files
authored
Merge pull request #217 from FoolCode/release/4.0.0
Release 4.0.0
2 parents c4f0b33 + be6ffa6 commit f1552c9

58 files changed

Lines changed: 7278 additions & 861 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
name: Buddy Integration
2+
3+
on:
4+
workflow_dispatch:
5+
6+
jobs:
7+
buddy-runtime:
8+
name: Buddy runtime smoke (manual)
9+
runs-on: ubuntu-22.04
10+
timeout-minutes: 20
11+
permissions:
12+
contents: read
13+
packages: read
14+
env:
15+
SEARCH_BUILD: MANTICORE
16+
MANTICORE_IMAGE: manticoresearch/manticore@sha256:24835e1b590a31da0f45809b032865b1caab0a1b58f4ed14da9128a338f2d365
17+
18+
steps:
19+
- name: Checkout
20+
uses: actions/checkout@v4
21+
22+
- name: Setup PHP
23+
uses: shivammathur/setup-php@v2
24+
with:
25+
php-version: "8.3"
26+
coverage: none
27+
extensions: mysqli, pdo_mysql, mbstring
28+
tools: composer:v2
29+
30+
- name: Start Manticore with Buddy extras
31+
run: |
32+
docker pull "$MANTICORE_IMAGE"
33+
docker run -d --name searchd \
34+
-e EXTRA=1 \
35+
-p 9307:9306 \
36+
-p 9312:9312 \
37+
"$MANTICORE_IMAGE"
38+
39+
- name: Wait for searchd
40+
run: |
41+
n=0
42+
while [ "$n" -lt 60 ]; do
43+
if php -r '
44+
try {
45+
$pdo = new PDO("mysql:host=127.0.0.1;port=9307", "", "");
46+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
47+
$pdo->query("SHOW TABLES");
48+
exit(0);
49+
} catch (Throwable $exception) {
50+
exit(1);
51+
}
52+
' >/dev/null 2>&1; then
53+
exit 0
54+
fi
55+
n=$((n + 1))
56+
sleep 1
57+
done
58+
echo "searchd did not become SQL-ready on 127.0.0.1:9307"
59+
docker logs searchd || true
60+
exit 1
61+
62+
- name: Seed runtime test table
63+
run: |
64+
cat > /tmp/seed-buddy-rt.php <<'PHP'
65+
<?php
66+
$pdo = new PDO('mysql:host=127.0.0.1;port=9307', '', '');
67+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
68+
$pdo->exec('CREATE TABLE IF NOT EXISTS rt(title text, content text, gid uint)');
69+
$pdo->exec('TRUNCATE TABLE rt');
70+
$pdo->exec("REPLACE INTO rt(id, title, content, gid) VALUES (1, 'test', 'teh words', 1)");
71+
PHP
72+
php /tmp/seed-buddy-rt.php
73+
74+
- name: Install dependencies
75+
run: composer install --prefer-dist --no-interaction --no-progress
76+
77+
- name: Run Buddy-specific runtime tests (must not skip)
78+
run: |
79+
./vendor/bin/phpunit \
80+
--configuration tests/travis/pdo.phpunit.xml \
81+
--filter '/(testQSuggestExecutionWhenBuddySupported|testAutocompleteExecutionWhenBuddySupported)/' \
82+
--fail-on-skipped
83+
84+
- name: Show searchd logs
85+
if: always()
86+
run: docker logs searchd || true
87+
88+
- name: Stop searchd container
89+
if: always()
90+
run: docker rm -f searchd || true

.github/workflows/ci.yml

Lines changed: 111 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -15,32 +15,44 @@ jobs:
1515
name: PHP ${{ matrix.php }} / ${{ matrix.driver }} / ${{ matrix.search_build }}
1616
runs-on: ubuntu-22.04
1717
timeout-minutes: 30
18-
continue-on-error: ${{ matrix.search_build == 'SPHINX3' }}
1918
permissions:
2019
contents: read
2120
packages: read
2221
strategy:
2322
fail-fast: false
2423
matrix:
25-
php: ['7.4', '8.0', '8.1']
24+
php: ['8.2', '8.3']
2625
driver: [mysqli, pdo]
2726
search_build: [SPHINX2, SPHINX3, MANTICORE]
2827
env:
2928
DRIVER: ${{ matrix.driver }}
3029
SEARCH_BUILD: ${{ matrix.search_build }}
30+
COVERAGE_LANE: ${{ matrix.php == '8.3' && matrix.driver == 'pdo' && matrix.search_build == 'MANTICORE' }}
3131

3232
steps:
3333
- name: Checkout
3434
uses: actions/checkout@v4
35+
with:
36+
fetch-depth: 0
3537

3638
- name: Setup PHP
39+
if: env.COVERAGE_LANE != 'true'
3740
uses: shivammathur/setup-php@v2
3841
with:
3942
php-version: ${{ matrix.php }}
4043
coverage: none
4144
extensions: mysqli, pdo_mysql, mbstring
4245
tools: composer:v2
4346

47+
- name: Setup PHP (coverage lane)
48+
if: env.COVERAGE_LANE == 'true'
49+
uses: shivammathur/setup-php@v2
50+
with:
51+
php-version: ${{ matrix.php }}
52+
coverage: xdebug
53+
extensions: mysqli, pdo_mysql, mbstring
54+
tools: composer:v2
55+
4456
- name: Resolve search image and group exclusions
4557
id: vars
4658
run: |
@@ -91,25 +103,118 @@ jobs:
91103
run: |
92104
n=0
93105
while [ "$n" -lt 60 ]; do
94-
if (echo > /dev/tcp/127.0.0.1/9307) >/dev/null 2>&1; then
106+
if php -r '
107+
try {
108+
$pdo = new PDO("mysql:host=127.0.0.1;port=9307", "", "");
109+
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
110+
$pdo->query("SHOW TABLES");
111+
exit(0);
112+
} catch (Throwable $exception) {
113+
exit(1);
114+
}
115+
' >/dev/null 2>&1; then
95116
exit 0
96117
fi
97118
n=$((n + 1))
98119
sleep 1
99120
done
100-
echo "searchd did not become ready on 127.0.0.1:9307"
121+
echo "searchd did not become SQL-ready on 127.0.0.1:9307"
101122
docker logs searchd || true
102123
exit 1
103124
125+
- name: Validate composer metadata
126+
run: composer validate --strict --no-check-publish
127+
104128
- name: Install dependencies
105-
run: composer update --prefer-dist --no-interaction
129+
run: composer install --prefer-dist --no-interaction --no-progress
106130

107131
- name: Prepare autoload
108132
run: composer dump-autoload
109133

134+
- name: Run PHPStan
135+
if: env.COVERAGE_LANE == 'true'
136+
run: |
137+
set -o pipefail
138+
mkdir -p static-analysis
139+
./vendor/bin/phpstan analyse --configuration phpstan.neon.dist --memory-limit=1G --no-progress --error-format=raw 2>&1 | tee static-analysis/phpstan.txt
140+
110141
- name: Run tests
111142
run: |
112-
./vendor/bin/phpunit --configuration "tests/travis/${DRIVER}.phpunit.xml" --coverage-text ${{ steps.vars.outputs.exclude_group }}
143+
if [ "${COVERAGE_LANE}" = "true" ]; then
144+
mkdir -p coverage
145+
./vendor/bin/phpunit --configuration "tests/travis/${DRIVER}.phpunit.xml" --coverage-text --coverage-clover coverage/clover.xml ${{ steps.vars.outputs.exclude_group }}
146+
else
147+
./vendor/bin/phpunit --configuration "tests/travis/${DRIVER}.phpunit.xml" --coverage-text ${{ steps.vars.outputs.exclude_group }}
148+
fi
149+
150+
- name: Build changed-line coverage artifact
151+
if: always() && env.COVERAGE_LANE == 'true'
152+
continue-on-error: true
153+
run: |
154+
mkdir -p coverage-artifact
155+
156+
BASE_SHA=""
157+
BASE_LABEL=""
158+
159+
if [ "${{ github.event_name }}" = "pull_request" ]; then
160+
BASE_SHA="${{ github.event.pull_request.base.sha }}"
161+
BASE_LABEL="PR base (${BASE_SHA})"
162+
else
163+
BASE_SHA="${{ github.event.before }}"
164+
BASE_LABEL="push before (${BASE_SHA})"
165+
fi
166+
167+
if [ -z "${BASE_SHA}" ] \
168+
|| [ "${BASE_SHA}" = "0000000000000000000000000000000000000000" ] \
169+
|| ! git cat-file -e "${BASE_SHA}^{commit}" 2>/dev/null; then
170+
DEFAULT_BRANCH="${{ github.event.repository.default_branch }}"
171+
if git show-ref --verify --quiet "refs/remotes/origin/${DEFAULT_BRANCH}"; then
172+
BASE_SHA="$(git merge-base "origin/${DEFAULT_BRANCH}" HEAD)"
173+
BASE_LABEL="merge-base (origin/${DEFAULT_BRANCH})"
174+
elif git cat-file -e "HEAD~1^{commit}" 2>/dev/null; then
175+
BASE_SHA="$(git rev-parse HEAD~1)"
176+
BASE_LABEL="fallback (HEAD~1)"
177+
else
178+
BASE_SHA="$(git rev-parse HEAD)"
179+
BASE_LABEL="fallback (HEAD)"
180+
fi
181+
fi
182+
183+
git diff --unified=0 "${BASE_SHA}"...HEAD > coverage-artifact/changed-lines.patch || true
184+
git diff --name-only "${BASE_SHA}"...HEAD > coverage-artifact/changed-files.txt || true
185+
186+
ADDED_LINES="$(git diff --numstat "${BASE_SHA}"...HEAD | awk '{a+=$1} END {print a+0}')"
187+
REMOVED_LINES="$(git diff --numstat "${BASE_SHA}"...HEAD | awk '{d+=$2} END {print d+0}')"
188+
CHANGED_FILES="$(wc -l < coverage-artifact/changed-files.txt | tr -d ' ')"
189+
190+
{
191+
echo "Changed-line coverage artifact summary"
192+
echo "Event: ${{ github.event_name }}"
193+
echo "Base: ${BASE_LABEL}"
194+
echo "Head: $(git rev-parse HEAD)"
195+
echo "Changed files: ${CHANGED_FILES}"
196+
echo "Added lines: ${ADDED_LINES}"
197+
echo "Removed lines: ${REMOVED_LINES}"
198+
if [ -f coverage/clover.xml ]; then
199+
echo "Clover XML: coverage/clover.xml"
200+
else
201+
echo "Clover XML: missing"
202+
fi
203+
} > coverage-artifact/summary.txt
204+
205+
- name: Upload changed-line coverage artifact
206+
if: always() && env.COVERAGE_LANE == 'true'
207+
continue-on-error: true
208+
uses: actions/upload-artifact@v4
209+
with:
210+
name: changed-line-coverage-php${{ matrix.php }}-${{ matrix.driver }}-${{ matrix.search_build }}
211+
if-no-files-found: warn
212+
path: |
213+
coverage/clover.xml
214+
static-analysis/phpstan.txt
215+
coverage-artifact/summary.txt
216+
coverage-artifact/changed-lines.patch
217+
coverage-artifact/changed-files.txt
113218
114219
- name: Upload debug artifacts on failure
115220
if: failure()

.github/workflows/docs.yml

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,76 @@
1+
name: Documentation
2+
3+
on:
4+
workflow_dispatch:
5+
pull_request:
6+
paths:
7+
- docs/**
8+
- README.md
9+
- .github/workflows/docs.yml
10+
push:
11+
paths:
12+
- docs/**
13+
- README.md
14+
- .github/workflows/docs.yml
15+
16+
permissions:
17+
contents: read
18+
19+
concurrency:
20+
group: docs-${{ github.workflow }}-${{ github.ref }}
21+
cancel-in-progress: true
22+
23+
jobs:
24+
build:
25+
runs-on: ubuntu-latest
26+
27+
steps:
28+
- name: Checkout
29+
uses: actions/checkout@v4
30+
31+
- name: Setup Python
32+
uses: actions/setup-python@v5
33+
with:
34+
python-version: "3.12"
35+
36+
- name: Configure GitHub Pages
37+
if: github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
38+
uses: actions/configure-pages@v5
39+
40+
- name: Install docs dependencies
41+
run: |
42+
python -m pip install --upgrade pip
43+
pip install -r docs/requirements.txt
44+
45+
- name: Build docs
46+
run: sphinx-build --fail-on-warning --keep-going -b html docs docs/_build/html
47+
48+
- name: Upload docs artifact (PR/debug)
49+
if: always()
50+
uses: actions/upload-artifact@v4
51+
with:
52+
name: docs-html
53+
path: docs/_build/html
54+
if-no-files-found: error
55+
56+
- name: Upload Pages artifact
57+
if: github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
58+
uses: actions/upload-pages-artifact@v3
59+
with:
60+
path: docs/_build/html
61+
62+
deploy:
63+
if: github.event_name == 'push' && github.ref == format('refs/heads/{0}', github.event.repository.default_branch)
64+
needs: build
65+
runs-on: ubuntu-latest
66+
permissions:
67+
pages: write
68+
id-token: write
69+
environment:
70+
name: github-pages
71+
url: ${{ steps.deployment.outputs.page_url }}
72+
73+
steps:
74+
- name: Deploy to GitHub Pages
75+
id: deployment
76+
uses: actions/deploy-pages@v4

.github/workflows/publish-search-images.yml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ on:
1111
- tests/sphinx.conf
1212
- tests/manticore.conf
1313
- tests/test_udf.c
14+
- tests/s3_test_udf.c
1415
- tests/ms_test_udf.c
1516

1617
permissions:

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ tests/searchd.pid
44
tests/data/rt.*
55
tests/data/test_udf.so
66
vendor/
7+
.phpstan/

CHANGELOG.md

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,30 @@
1+
#### 4.0.0
2+
* Dropped support for PHP 8.1 and lower (minimum PHP is now 8.2)
3+
* Updated CI PHP matrix to 8.2 and 8.3
4+
* Normalized MySQLi driver exception handling for modern PHP `mysqli_sql_exception` behavior
5+
* Hardened runtime validation for `SphinxQL`, `Facet`, `Helper`, and `Percolate` input contracts (fail-fast exceptions for invalid query-shape input)
6+
* Standardized driver exception message prefixes for better diagnostics (`[mysqli][...]`, `[pdo][...]`)
7+
* Expanded helper runtime API coverage (`SHOW WARNINGS`, `SHOW STATUS`, `SHOW INDEX STATUS`, `FLUSH RAMCHUNK`, `FLUSH RTINDEX`, `OPTIMIZE INDEX`, UDF lifecycle checks)
8+
* Added fluent boolean grouping APIs (`orWhere`, `whereOpen/whereClose`, `orHaving`, `havingOpen/havingClose`) and JOIN builders (`join`, `innerJoin`, `leftJoin`, `rightJoin`, `crossJoin`)
9+
* Added `orderByKnn()` and broader helper wrappers for operational and Manticore-oriented commands (`SHOW PROFILE/PLAN/THREADS/VERSION/PLUGINS`, table status/settings/indexes, flush/reload/kill, suggest family)
10+
* Added capability discovery and feature-gating APIs (`Capabilities`, `getCapabilities()`, `supports()`, `requireSupport()`) with `UnsupportedFeatureException` for unsupported command families
11+
* Added `SphinxQL::requireSupport()` passthrough and convenience engine predicates on `Capabilities` (`isManticore`, `isSphinx2`, `isSphinx3`)
12+
* Added helper parity wrappers for `SHOW CHARACTER SET` and `SHOW COLLATION`
13+
* Added `docs/feature-matrix.yml` as a feature-level support map across Sphinx2/Sphinx3/Manticore
14+
* Added capability-aware runtime tests for optional engine features (`supportsCommand`, Buddy-gated checks)
15+
* Added and stabilized Sphinx 3 compatibility coverage while preserving Sphinx 2 and Manticore test behavior
16+
* Added support for optional connection credentials (`username`/`password`) in both PDO and MySQLi drivers (closes #208)
17+
* Added optional-index `update($index = null)` flow for fluent `->update()->into($index)` usage (closes #184)
18+
* Added explicit `update()->compile()/execute()` guard when no target index is set via `into($index)` (prevents invalid `UPDATE` SQL emission)
19+
* Restored `showTables($index = null)` compatibility (`SHOW TABLES` for null/empty, `SHOW TABLES LIKE ...` for non-empty) and removed hardcoded `rt` assumptions from runtime capability probes
20+
* Aligned Buddy capability flags so `callQSuggest()`/`callAutocomplete()` are gated by detected Buddy availability
21+
* Added MVA insert/update array example in README (closes #178)
22+
* Corrected escaping docs to reference connection-level helpers and clarified `quoteIdentifier()` availability (closes #203)
23+
* Added a root `LICENSE` file (closes #171)
24+
* Migrated CI to GitHub Actions-only validation with strict composer metadata checks
25+
* Hardened GitHub Actions reliability with SQL-readiness checks, full-history checkout for changed-line artifacts, and digest-pinned Buddy integration runtime image
26+
* Updated documentation and added a dedicated `MIGRATING-4.0.md` guide
27+
128
#### 3.0.2
229
* Dropped support for PHP 7.3 and lower
330

0 commit comments

Comments
 (0)