> algolia-ci-integration
Configure Algolia CI/CD: GitHub Actions for index validation, automated reindexing on deploy, and integration testing against real Algolia indices. Trigger: "algolia CI", "algolia GitHub Actions", "algolia automated tests", "CI algolia", "algolia deploy pipeline".
curl "https://skillshub.wtf/jeremylongshore/claude-code-plugins-plus-skills/algolia-ci-integration?format=md"Algolia CI Integration
Overview
Set up CI/CD pipelines for Algolia: run integration tests against a test index, validate index settings before deploy, and trigger reindexing on release.
Prerequisites
- GitHub repository with Actions enabled
- Algolia App ID and Admin key (stored as GitHub secrets)
- npm/pnpm project with
algoliasearchv5
Instructions
Step 1: Store Algolia Secrets
gh 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"
Step 2: GitHub Actions — Test & Validate
# .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
Step 3: Index Settings Validation Script
// 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); });
Step 4: Integration Test Pattern
// 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);
});
});
Step 5: Deploy-Triggered Reindex
# .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
Error Handling
| 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 |
Resources
Next Steps
For deployment patterns, see algolia-deploy-integration.
> related_skills --same-repo
> fathom-cost-tuning
Optimize Fathom API usage and plan selection. Trigger with phrases like "fathom cost", "fathom pricing", "fathom plan".
> fathom-core-workflow-b
Sync Fathom meeting data to CRM and build automated follow-up workflows. Use when integrating Fathom with Salesforce, HubSpot, or custom CRMs, or creating automated post-meeting email summaries. Trigger with phrases like "fathom crm sync", "fathom salesforce", "fathom follow-up", "fathom post-meeting workflow".
> fathom-core-workflow-a
Build a meeting analytics pipeline with Fathom transcripts and summaries. Use when extracting insights from meetings, building CRM sync, or creating automated meeting follow-up workflows. Trigger with phrases like "fathom analytics", "fathom meeting pipeline", "fathom transcript analysis", "fathom action items sync".
> fathom-common-errors
Diagnose and fix Fathom API errors including auth failures and missing data. Use when API calls fail, transcripts are empty, or webhooks are not firing. Trigger with phrases like "fathom error", "fathom not working", "fathom api failure", "fix fathom".