From algolia-pack
Configures GitHub Actions for Algolia CI/CD: integration tests against real indices, index settings validation, and reindexing triggers on deploy.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin algolia-packThis skill is limited to using the following tools:
Set up CI/CD pipelines for Algolia: run integration tests against a test index, validate index settings before deploy, and trigger reindexing on release.
Configures Algolia for dev/staging/prod environments using index prefixing, scoped API keys, settings-as-code, and isolation in TypeScript/Node.js apps.
Provides patterns for Algolia search implementation using React InstantSearch hooks, indexing strategies, relevance tuning, and Next.js SSR integration.
Automates Algolia operations like indexing, searching, and record management via Composio toolkit and Rube MCP. Discovers current tool schemas before execution.
Share bugs, ideas, or general feedback.
Set up CI/CD pipelines for Algolia: run integration tests against a test index, validate index settings before deploy, and trigger reindexing on release.
algoliasearch v5gh secret set ALGOLIA_APP_ID --body "YourApplicationID"
gh secret set ALGOLIA_ADMIN_KEY --body "your_admin_api_key"
gh secret set ALGOLIA_SEARCH_KEY --body "your_search_only_key"
# .github/workflows/algolia-ci.yml
name: Algolia CI
on:
push:
branches: [main]
pull_request:
branches: [main]
jobs:
test:
runs-on: ubuntu-latest
env:
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
ALGOLIA_ADMIN_KEY: ${{ secrets.ALGOLIA_ADMIN_KEY }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- name: Unit tests (mocked Algolia)
run: npm test
- name: Integration tests (real Algolia)
if: env.ALGOLIA_APP_ID != ''
run: npm run test:integration
env:
# Use timestamped index to avoid cross-PR collision
ALGOLIA_TEST_INDEX: ci_test_${{ github.run_id }}_products
validate-settings:
runs-on: ubuntu-latest
if: github.event_name == 'pull_request'
env:
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
ALGOLIA_ADMIN_KEY: ${{ secrets.ALGOLIA_ADMIN_KEY }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20', cache: 'npm' }
- run: npm ci
- name: Validate index settings match config
run: npx tsx scripts/validate-algolia-settings.ts
// scripts/validate-algolia-settings.ts
import { algoliasearch } from 'algoliasearch';
import expectedSettings from '../config/algolia-settings.json' assert { type: 'json' };
const client = algoliasearch(process.env.ALGOLIA_APP_ID!, process.env.ALGOLIA_ADMIN_KEY!);
async function validateSettings() {
const actual = await client.getSettings({ indexName: 'products' });
const errors: string[] = [];
// Check critical settings match
const checks: [string, any, any][] = [
['searchableAttributes', actual.searchableAttributes, expectedSettings.searchableAttributes],
['attributesForFaceting', actual.attributesForFaceting, expectedSettings.attributesForFaceting],
['customRanking', actual.customRanking, expectedSettings.customRanking],
];
for (const [field, actual, expected] of checks) {
if (JSON.stringify(actual) !== JSON.stringify(expected)) {
errors.push(`${field}: expected ${JSON.stringify(expected)}, got ${JSON.stringify(actual)}`);
}
}
if (errors.length > 0) {
console.error('Settings drift detected:');
errors.forEach(e => console.error(` - ${e}`));
process.exit(1);
}
console.log('All Algolia settings match expected configuration.');
}
validateSettings().catch(e => { console.error(e); process.exit(1); });
// tests/integration/algolia.integration.test.ts
import { describe, it, expect, afterAll } from 'vitest';
import { algoliasearch } from 'algoliasearch';
const client = algoliasearch(process.env.ALGOLIA_APP_ID!, process.env.ALGOLIA_ADMIN_KEY!);
const testIndex = process.env.ALGOLIA_TEST_INDEX || `test_${Date.now()}`;
describe.skipIf(!process.env.ALGOLIA_APP_ID)('Algolia Integration', () => {
afterAll(async () => {
// Clean up test index
try { await client.deleteIndex({ indexName: testIndex }); } catch {}
});
it('indexes records and searches', async () => {
const { taskID } = await client.saveObjects({
indexName: testIndex,
objects: [
{ objectID: '1', name: 'Test Widget', category: 'tools' },
{ objectID: '2', name: 'Test Gadget', category: 'electronics' },
],
});
await client.waitForTask({ indexName: testIndex, taskID });
const { hits, nbHits } = await client.searchSingleIndex({
indexName: testIndex,
searchParams: { query: 'widget' },
});
expect(nbHits).toBe(1);
expect(hits[0].name).toBe('Test Widget');
});
it('applies filters correctly', async () => {
await client.setSettings({
indexName: testIndex,
indexSettings: { attributesForFaceting: ['category'] },
});
// Wait for settings propagation
await new Promise(r => setTimeout(r, 2000));
const { hits } = await client.searchSingleIndex({
indexName: testIndex,
searchParams: { query: '', filters: 'category:tools' },
});
expect(hits.every(h => h.category === 'tools')).toBe(true);
});
});
# .github/workflows/algolia-deploy.yml
name: Algolia Reindex on Deploy
on:
push:
tags: ['v*']
jobs:
reindex:
runs-on: ubuntu-latest
env:
ALGOLIA_APP_ID: ${{ secrets.ALGOLIA_APP_ID }}
ALGOLIA_ADMIN_KEY: ${{ secrets.ALGOLIA_ADMIN_KEY }}
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20', cache: 'npm' }
- run: npm ci
- name: Full reindex from data source
run: npx tsx scripts/full-reindex.ts
- name: Verify index health
run: npx tsx scripts/verify-index-health.ts
| Issue | Cause | Solution |
|---|---|---|
| Secret not available | Secrets not set or wrong name | gh secret list to verify |
| Test index collision | Parallel CI runs | Use ${{ github.run_id }} in index name |
| Integration test timeout | Network latency to Algolia | Increase vitest timeout: { test: { timeout: 30000 } } |
| Settings drift | Manual dashboard change | Run settings validation in CI |
For deployment patterns, see algolia-deploy-integration.