From 5c5e1d3ed57ec8ce216596f818639e17cceadf95 Mon Sep 17 00:00:00 2001 From: eric-zaharia Date: Tue, 21 Apr 2026 12:13:13 +0300 Subject: [PATCH 1/3] fix: add index cleanup cron --- .github/workflows/cleanup-test-indexes.yml | 35 ++++++++++++++++++++++ 1 file changed, 35 insertions(+) create mode 100644 .github/workflows/cleanup-test-indexes.yml diff --git a/.github/workflows/cleanup-test-indexes.yml b/.github/workflows/cleanup-test-indexes.yml new file mode 100644 index 0000000..208e70c --- /dev/null +++ b/.github/workflows/cleanup-test-indexes.yml @@ -0,0 +1,35 @@ +name: Cleanup test indexes + +on: + schedule: + - cron: '0 3 * * 0' + workflow_dispatch: + +jobs: + cleanup: + runs-on: ubuntu-latest + env: + APP_ID: ${{ secrets.ALGOLIA_APP_ID }} + API_KEY: ${{ secrets.ALGOLIA_API_KEY }} + steps: + - name: Delete sf_phpunit_* indexes + run: | + set -euo pipefail + + auth=(-H "X-Algolia-Application-Id: $APP_ID" -H "X-Algolia-API-Key: $API_KEY") + host="https://${APP_ID}.algolia.net" + + names=$(curl -sSf "${auth[@]}" "$host/1/indexes" \ + | jq -r '.items[].name | select(startswith("sf_phpunit_"))') + + if [ -z "$names" ]; then + echo "Nothing to delete." + exit 0 + fi + + echo "Deleting $(echo "$names" | wc -l) indexes..." + while IFS= read -r name; do + encoded=$(jq -rn --arg v "$name" '$v|@uri') + curl -sSf -X DELETE "${auth[@]}" "$host/1/indexes/$encoded" > /dev/null + echo " $name" + done <<< "$names" From 6ecf994a976b69bdd04ca9fbbbc39a177bcd06b3 Mon Sep 17 00:00:00 2001 From: eric-zaharia Date: Tue, 21 Apr 2026 12:28:40 +0300 Subject: [PATCH 2/3] fix: also include atomic reindex temps --- .github/workflows/cleanup-test-indexes.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/cleanup-test-indexes.yml b/.github/workflows/cleanup-test-indexes.yml index 208e70c..43546d3 100644 --- a/.github/workflows/cleanup-test-indexes.yml +++ b/.github/workflows/cleanup-test-indexes.yml @@ -12,7 +12,7 @@ jobs: APP_ID: ${{ secrets.ALGOLIA_APP_ID }} API_KEY: ${{ secrets.ALGOLIA_API_KEY }} steps: - - name: Delete sf_phpunit_* indexes + - name: Delete sf_phpunit_* indexes (including atomic-reindex temps) run: | set -euo pipefail @@ -20,7 +20,7 @@ jobs: host="https://${APP_ID}.algolia.net" names=$(curl -sSf "${auth[@]}" "$host/1/indexes" \ - | jq -r '.items[].name | select(startswith("sf_phpunit_"))') + | jq -r '.items[].name | select(contains("sf_phpunit_"))') if [ -z "$names" ]; then echo "Nothing to delete." From 6293cb457c1843964e49ae2885c30832a31e4467 Mon Sep 17 00:00:00 2001 From: eric-zaharia Date: Tue, 21 Apr 2026 13:01:12 +0300 Subject: [PATCH 3/3] fix: port cron script to js, add batching and wait for deletion --- .github/scripts/cleanup-test-indexes.js | 45 ++++++++++++++++++++++ .github/scripts/package.json | 10 +++++ .github/workflows/cleanup-test-indexes.yml | 34 +++++----------- .gitignore | 2 + 4 files changed, 67 insertions(+), 24 deletions(-) create mode 100644 .github/scripts/cleanup-test-indexes.js create mode 100644 .github/scripts/package.json diff --git a/.github/scripts/cleanup-test-indexes.js b/.github/scripts/cleanup-test-indexes.js new file mode 100644 index 0000000..7bc0fe8 --- /dev/null +++ b/.github/scripts/cleanup-test-indexes.js @@ -0,0 +1,45 @@ +const { algoliasearch } = require('algoliasearch'); + +const BATCH_SIZE = 20; + +async function main() { + const client = algoliasearch(process.env.APP_ID, process.env.API_KEY); + + const { items } = await client.listIndices(); + const names = items.map((i) => i.name).filter((n) => n.includes('sf_phpunit_')); + + if (names.length === 0) { + console.log('Nothing to delete.'); + return; + } + + console.log(`Deleting ${names.length} indexes in batches of ${BATCH_SIZE}...`); + + const tasks = []; + for (let i = 0; i < names.length; i += BATCH_SIZE) { + const batch = names.slice(i, i + BATCH_SIZE); + const batchTasks = await Promise.all( + batch.map(async (name) => { + const { taskID } = await client.deleteIndex({ indexName: name }); + return { name, taskID }; + }) + ); + tasks.push(...batchTasks); + console.log(` requested ${Math.min(i + BATCH_SIZE, names.length)}/${names.length}`); + } + + console.log('Waiting for all tasks to complete...'); + await Promise.all( + tasks.map(async ({ name, taskID }) => { + await client.waitForTask({ indexName: name, taskID }); + console.log(` confirmed ${name}`); + }) + ); + + console.log('All deletes confirmed.'); +} + +main().catch((err) => { + console.error(err); + process.exit(1); +}); diff --git a/.github/scripts/package.json b/.github/scripts/package.json new file mode 100644 index 0000000..3f7574b --- /dev/null +++ b/.github/scripts/package.json @@ -0,0 +1,10 @@ +{ + "name": "search-bundle-ci-scripts", + "private": true, + "dependencies": { + "algoliasearch": "^5" + }, + "devDependencies": { + "@types/node": "^24" + } +} diff --git a/.github/workflows/cleanup-test-indexes.yml b/.github/workflows/cleanup-test-indexes.yml index 43546d3..83ce09d 100644 --- a/.github/workflows/cleanup-test-indexes.yml +++ b/.github/workflows/cleanup-test-indexes.yml @@ -8,28 +8,14 @@ on: jobs: cleanup: runs-on: ubuntu-latest - env: - APP_ID: ${{ secrets.ALGOLIA_APP_ID }} - API_KEY: ${{ secrets.ALGOLIA_API_KEY }} steps: - - name: Delete sf_phpunit_* indexes (including atomic-reindex temps) - run: | - set -euo pipefail - - auth=(-H "X-Algolia-Application-Id: $APP_ID" -H "X-Algolia-API-Key: $API_KEY") - host="https://${APP_ID}.algolia.net" - - names=$(curl -sSf "${auth[@]}" "$host/1/indexes" \ - | jq -r '.items[].name | select(contains("sf_phpunit_"))') - - if [ -z "$names" ]; then - echo "Nothing to delete." - exit 0 - fi - - echo "Deleting $(echo "$names" | wc -l) indexes..." - while IFS= read -r name; do - encoded=$(jq -rn --arg v "$name" '$v|@uri') - curl -sSf -X DELETE "${auth[@]}" "$host/1/indexes/$encoded" > /dev/null - echo " $name" - done <<< "$names" + - uses: actions/checkout@v4 + - uses: actions/setup-node@v4 + with: + node-version: '24' + - run: npm install algoliasearch@^5 --no-save + - name: Delete sf_phpunit_* indexes + env: + APP_ID: ${{ secrets.ALGOLIA_APP_ID }} + API_KEY: ${{ secrets.ALGOLIA_API_KEY }} + run: node .github/scripts/cleanup-test-indexes.js diff --git a/.gitignore b/.gitignore index b8e453c..88c1b7a 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,5 @@ clover.xml /tests/QualityTools/composer.lock .phpunit.result.cache phpunit.xml.dist.bak +/.github/scripts/node_modules/ +/.github/scripts/package-lock.json