Skillshub exa-ci-integration
install
source · Clone the upstream repo
git clone https://github.com/ComeOnOliver/skillshub
Claude Code · Install into ~/.claude/skills/
T=$(mktemp -d) && git clone --depth=1 https://github.com/ComeOnOliver/skillshub "$T" && mkdir -p ~/.claude/skills && cp -r "$T/skills/jeremylongshore/claude-code-plugins-plus-skills/exa-ci-integration" ~/.claude/skills/comeonoliver-skillshub-exa-ci-integration && rm -rf "$T"
manifest:
skills/jeremylongshore/claude-code-plugins-plus-skills/exa-ci-integration/SKILL.mdsource content
Exa CI Integration
Overview
Set up CI/CD pipelines for Exa integrations with unit tests (mocked), integration tests (real API), and health checks. Uses GitHub Actions with secrets for API key management.
Prerequisites
- GitHub repository with Actions enabled
- Exa API key for testing
- npm/pnpm project with vitest or jest
Instructions
Step 1: GitHub Actions Workflow
# .github/workflows/exa-tests.yml name: Exa Integration Tests on: push: branches: [main] pull_request: branches: [main] jobs: unit-tests: runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: "20" cache: "npm" - run: npm ci - run: npm run test:unit # Unit tests use mocked Exa — no API key needed integration-tests: runs-on: ubuntu-latest # Only run if API key is available (not on forks) if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name == github.repository env: EXA_API_KEY: ${{ secrets.EXA_API_KEY }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: "20" cache: "npm" - run: npm ci - run: npm run test:integration timeout-minutes: 5 exa-health-check: runs-on: ubuntu-latest env: EXA_API_KEY: ${{ secrets.EXA_API_KEY }} steps: - name: Verify Exa API connectivity run: | HTTP_CODE=$(curl -s -o /dev/null -w "%{http_code}" \ -X POST https://api.exa.ai/search \ -H "x-api-key: $EXA_API_KEY" \ -H "Content-Type: application/json" \ -d '{"query":"CI health check","numResults":1}') echo "Exa API status: $HTTP_CODE" [ "$HTTP_CODE" = "200" ] || exit 1
Step 2: Configure Secrets
# Add API key as repository secret gh secret set EXA_API_KEY --body "your-exa-api-key" # For staging/production deployments gh secret set EXA_API_KEY_STAGING --body "staging-key" --env staging gh secret set EXA_API_KEY_PROD --body "prod-key" --env production
Step 3: Integration Test Suite
// tests/exa.integration.test.ts import { describe, it, expect } from "vitest"; import Exa from "exa-js"; const describeWithKey = process.env.EXA_API_KEY ? describe : describe.skip; describeWithKey("Exa API Integration", () => { const exa = new Exa(process.env.EXA_API_KEY!); it("should search and return results", async () => { const result = await exa.search("JavaScript frameworks", { type: "auto", numResults: 3, }); expect(result.results.length).toBeGreaterThanOrEqual(1); expect(result.results[0]).toHaveProperty("url"); expect(result.results[0]).toHaveProperty("title"); expect(result.results[0]).toHaveProperty("score"); }, 10000); it("should return content with searchAndContents", async () => { const result = await exa.searchAndContents("Node.js best practices", { numResults: 2, text: { maxCharacters: 500 }, highlights: { maxCharacters: 200 }, }); expect(result.results[0].text).toBeDefined(); expect(result.results[0].text!.length).toBeGreaterThan(0); }, 15000); it("should find similar pages", async () => { const result = await exa.findSimilar("https://nodejs.org", { numResults: 3, }); expect(result.results.length).toBeGreaterThanOrEqual(1); }, 10000); it("should handle invalid queries gracefully", async () => { // Empty query should return 400 await expect( exa.search("", { numResults: 1 }) ).rejects.toThrow(); }, 10000); });
Step 4: Release Gate with Exa Verification
# .github/workflows/release.yml on: push: tags: ["v*"] jobs: verify-and-release: runs-on: ubuntu-latest env: EXA_API_KEY: ${{ secrets.EXA_API_KEY_PROD }} steps: - uses: actions/checkout@v4 - uses: actions/setup-node@v4 with: node-version: "20" - run: npm ci - run: npm test - name: Verify Exa production connectivity run: npm run test:integration - run: npm run build - run: npm publish
Error Handling
| Issue | Cause | Solution |
|---|---|---|
| Secret not found | Missing configuration | |
| Integration tests timeout | Slow API response | Increase timeout to 15000ms |
| Tests fail on forks | No access to secrets | Skip integration tests on fork PRs |
| Rate limited in CI | Too many concurrent runs | Use unique test queries per run |
Resources
Next Steps
For deployment patterns, see
exa-deploy-integration.