[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"skill:01M6CHATK5R43RPM57YA6F1QZ1":3,"skill-same:01M6CHATK5R43RPM57YA6F1QZ1":99},{"skillNo":4,"name":5,"nameZh":6,"description":7,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":6,"sourceHtmlUrl":16,"categories":17,"keywords":26,"publishedAt":52,"linkOnly":53,"markdownContent":54,"markdownBody":55,"frontMatter":56,"refName":61,"commitSha":62,"skillDirectory":63,"forksCount":64,"repositoryHtmlUrl":65,"repositoryHomepageUrl":6,"ownerHtmlUrl":66,"ownerBlogUrl":67,"ownerDescription":68,"updatedAt":69,"install":70,"resources":83},"01M6CHATK5R43RPM57YA6F1QZ1","apollo-ci-integration",null,"Configure Apollo.io CI\u002FCD integration.\nUse when setting up automated testing, continuous integration,\nor deployment pipelines for Apollo integrations.\nTrigger with phrases like \"apollo ci\", \"apollo github actions\",\n\"apollo pipeline\", \"apollo ci\u002Fcd\", \"apollo automated tests\".","Dicklesworthstone\u002Fpi_agent_rust","Dicklesworthstone","https:\u002F\u002Favatars.githubusercontent.com\u002Fu\u002F35050222?v=4","01M6CG26AR942CSVMN1M5E3DSE","Jeff Emanuel","01M6CG26EPP71PSHW1VDS71121",1991,"MIT","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fsaas-packs\u002Fapollo-pack\u002Fskills\u002Fapollo-ci-integration\u002FSKILL.md",[18,23],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000008","测试与质量","SCENARIO","使用场景",{"categoryNo":24,"categoryName":25,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000011","运维与部署",[27,28,29,30,31,32,33,34,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51],"integration","ci","apollo ci integration","apollo","curl","when","for","CI\u002FCD","io","continuous integration","up","use","edit","write","read","testing","gh","integrations","configure","Bash","pipeline","github actions","actions","deployment","github","2026-11-10 10:12:30",false,"---\nname: apollo-ci-integration\ndescription: |\n  Configure Apollo.io CI\u002FCD integration.\n  Use when setting up automated testing, continuous integration,\n  or deployment pipelines for Apollo integrations.\n  Trigger with phrases like \"apollo ci\", \"apollo github actions\",\n  \"apollo pipeline\", \"apollo ci\u002Fcd\", \"apollo automated tests\".\nallowed-tools: Read, Write, Edit, Bash(gh:*), Bash(curl:*)\nversion: 1.0.0\nlicense: MIT\nauthor: Jeremy Longshore \u003Cjeremy@intentsolutions.io>\n---\n\n# Apollo CI Integration\n\n## Overview\nSet up CI\u002FCD pipelines for Apollo.io integrations with automated testing, secret management, and deployment workflows.\n\n## GitHub Actions Setup\n\n### Basic CI Workflow\n```yaml\n# .github\u002Fworkflows\u002Fapollo-ci.yml\nname: Apollo Integration CI\n\non:\n  push:\n    branches: [main, develop]\n  pull_request:\n    branches: [main]\n\nenv:\n  NODE_VERSION: '20'\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n\n      - name: Setup Node.js\n        uses: actions\u002Fsetup-node@v4\n        with:\n          node-version: ${{ env.NODE_VERSION }}\n          cache: 'npm'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Run linting\n        run: npm run lint\n\n      - name: Run unit tests\n        run: npm run test:unit\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY_TEST }}\n\n      - name: Run integration tests\n        if: github.event_name == 'push' && github.ref == 'refs\u002Fheads\u002Fmain'\n        run: npm run test:integration\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY_TEST }}\n\n  validate-apollo:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n\n      - name: Setup Node.js\n        uses: actions\u002Fsetup-node@v4\n        with:\n          node-version: ${{ env.NODE_VERSION }}\n          cache: 'npm'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Validate Apollo configuration\n        run: npm run apollo:validate\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY_TEST }}\n\n      - name: Check API health\n        run: |\n          curl -sf \"https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Fauth\u002Fhealth?api_key=$APOLLO_API_KEY\" \\\n            || echo \"Warning: Apollo API health check failed\"\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY_TEST }}\n```\n\n### Integration Test Workflow\n```yaml\n# .github\u002Fworkflows\u002Fapollo-integration.yml\nname: Apollo Integration Tests\n\non:\n  schedule:\n    - cron: '0 6 * * *'  # Daily at 6 AM UTC\n  workflow_dispatch:\n\njobs:\n  integration-tests:\n    runs-on: ubuntu-latest\n    timeout-minutes: 30\n\n    steps:\n      - uses: actions\u002Fcheckout@v4\n\n      - name: Setup Node.js\n        uses: actions\u002Fsetup-node@v4\n        with:\n          node-version: '20'\n          cache: 'npm'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Run Apollo integration tests\n        run: npm run test:apollo\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY_TEST }}\n          APOLLO_TEST_DOMAIN: 'apollo.io'\n\n      - name: Upload test results\n        if: always()\n        uses: actions\u002Fupload-artifact@v4\n        with:\n          name: apollo-test-results\n          path: test-results\u002F\n\n      - name: Notify on failure\n        if: failure()\n        uses: slackapi\u002Fslack-github-action@v1\n        with:\n          payload: |\n            {\n              \"text\": \"Apollo integration tests failed!\",\n              \"blocks\": [\n                {\n                  \"type\": \"section\",\n                  \"text\": {\n                    \"type\": \"mrkdwn\",\n                    \"text\": \"*Apollo Integration Tests Failed*\\n\u003C${{ github.server_url }}\u002F${{ github.repository }}\u002Factions\u002Fruns\u002F${{ github.run_id }}|View Run>\"\n                  }\n                }\n              ]\n            }\n        env:\n          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}\n```\n\n## Secrets Management\n\n### GitHub Secrets Setup\n```bash\n# Add secrets via GitHub CLI\ngh secret set APOLLO_API_KEY_TEST --body \"your-test-api-key\"\ngh secret set APOLLO_API_KEY_PROD --body \"your-prod-api-key\"\n\n# List configured secrets\ngh secret list\n```\n\n### Environment-Based Secrets\n```yaml\n# .github\u002Fworkflows\u002Fdeploy.yml\njobs:\n  deploy-staging:\n    environment: staging\n    steps:\n      - name: Deploy to staging\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY }}\n        run: npm run deploy:staging\n\n  deploy-production:\n    environment: production\n    needs: deploy-staging\n    steps:\n      - name: Deploy to production\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY }}\n        run: npm run deploy:production\n```\n\n## Test Configuration\n\n### Test Setup\n```typescript\n\u002F\u002F tests\u002Fsetup\u002Fapollo.ts\nimport { beforeAll, afterAll, beforeEach } from 'vitest';\nimport { setupServer } from 'msw\u002Fnode';\nimport { apolloHandlers } from '.\u002Fmocks\u002Fapollo-handlers';\n\nconst server = setupServer(...apolloHandlers);\n\nbeforeAll(() => {\n  server.listen({ onUnhandledRequest: 'warn' });\n});\n\nafterAll(() => {\n  server.close();\n});\n\nbeforeEach(() => {\n  server.resetHandlers();\n});\n\nexport { server };\n```\n\n### Mock Handlers for CI\n```typescript\n\u002F\u002F tests\u002Fmocks\u002Fapollo-handlers.ts\nimport { http, HttpResponse } from 'msw';\n\nexport const apolloHandlers = [\n  http.get('https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Fauth\u002Fhealth', () => {\n    return HttpResponse.json({ status: 'ok' });\n  }),\n\n  http.post('https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Fpeople\u002Fsearch', async ({ request }) => {\n    const body = await request.json();\n    return HttpResponse.json({\n      people: [\n        {\n          id: 'test-1',\n          name: 'Test User',\n          title: 'Engineer',\n          email: 'test@example.com',\n        },\n      ],\n      pagination: {\n        page: body.page || 1,\n        per_page: body.per_page || 25,\n        total_entries: 1,\n        total_pages: 1,\n      },\n    });\n  }),\n\n  http.get('https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Forganizations\u002Fenrich', ({ request }) => {\n    const url = new URL(request.url);\n    const domain = url.searchParams.get('domain');\n    return HttpResponse.json({\n      organization: {\n        id: 'org-1',\n        name: 'Test Company',\n        primary_domain: domain,\n        industry: 'Technology',\n      },\n    });\n  }),\n];\n```\n\n### Integration Tests\n```typescript\n\u002F\u002F tests\u002Fintegration\u002Fapollo.test.ts\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { apollo } from '..\u002F..\u002Fsrc\u002Flib\u002Fapollo\u002Fclient';\n\ndescribe('Apollo API Integration', () => {\n  \u002F\u002F Only run with real API in CI\n  const isCI = process.env.CI === 'true';\n  const hasApiKey = !!process.env.APOLLO_API_KEY;\n\n  beforeEach(() => {\n    if (!isCI || !hasApiKey) {\n      console.log('Skipping real API tests - using mocks');\n    }\n  });\n\n  it('should search for people', async () => {\n    const result = await apollo.searchPeople({\n      q_organization_domains: [process.env.APOLLO_TEST_DOMAIN || 'apollo.io'],\n      per_page: 5,\n    });\n\n    expect(result.people).toBeDefined();\n    expect(Array.isArray(result.people)).toBe(true);\n    expect(result.pagination.total_entries).toBeGreaterThanOrEqual(0);\n  });\n\n  it('should enrich organization', async () => {\n    const result = await apollo.enrichOrganization(\n      process.env.APOLLO_TEST_DOMAIN || 'apollo.io'\n    );\n\n    expect(result.organization).toBeDefined();\n    expect(result.organization.name).toBeTruthy();\n  });\n\n  it('should handle rate limits gracefully', async () => {\n    \u002F\u002F This test verifies rate limit handling without actually hitting limits\n    const startTime = Date.now();\n\n    \u002F\u002F Make 5 requests in sequence\n    for (let i = 0; i \u003C 5; i++) {\n      await apollo.searchPeople({ per_page: 1 });\n    }\n\n    const duration = Date.now() - startTime;\n    \u002F\u002F Should complete in reasonable time with rate limiting\n    expect(duration).toBeLessThan(30000);\n  });\n});\n```\n\n## Pipeline Scripts\n\n### package.json Scripts\n```json\n{\n  \"scripts\": {\n    \"test:unit\": \"vitest run --config vitest.unit.config.ts\",\n    \"test:integration\": \"vitest run --config vitest.integration.config.ts\",\n    \"test:apollo\": \"vitest run tests\u002Fintegration\u002Fapollo.test.ts\",\n    \"apollo:validate\": \"tsx scripts\u002Fvalidate-apollo-config.ts\",\n    \"apollo:health\": \"curl -sf 'https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Fauth\u002Fhealth?api_key=$APOLLO_API_KEY'\"\n  }\n}\n```\n\n### Validation Script\n```typescript\n\u002F\u002F scripts\u002Fvalidate-apollo-config.ts\nasync function validateConfig() {\n  const checks = [];\n\n  \u002F\u002F Check API key\n  if (!process.env.APOLLO_API_KEY) {\n    checks.push({ name: 'API Key', status: 'fail', message: 'Missing' });\n  } else {\n    checks.push({ name: 'API Key', status: 'pass', message: 'Present' });\n  }\n\n  \u002F\u002F Check API connectivity\n  try {\n    const response = await fetch(\n      `https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Fauth\u002Fhealth?api_key=${process.env.APOLLO_API_KEY}`\n    );\n    checks.push({\n      name: 'API Health',\n      status: response.ok ? 'pass' : 'fail',\n      message: response.ok ? 'Healthy' : `Status: ${response.status}`,\n    });\n  } catch (error) {\n    checks.push({\n      name: 'API Health',\n      status: 'fail',\n      message: 'Connection failed',\n    });\n  }\n\n  \u002F\u002F Output results\n  const failed = checks.filter((c) => c.status === 'fail');\n  if (failed.length > 0) {\n    console.error('Validation failed:', failed);\n    process.exit(1);\n  }\n\n  console.log('All checks passed:', checks);\n}\n\nvalidateConfig();\n```\n\n## Output\n- GitHub Actions workflows for CI\n- Secrets management configuration\n- Test setup with MSW mocks\n- Integration test suite\n- Validation scripts\n\n## Error Handling\n| Issue | Resolution |\n|-------|------------|\n| Secret not found | Verify secret name in GitHub |\n| Tests timeout | Increase timeout or mock API |\n| Rate limited in CI | Use mocks for unit tests |\n| Health check fails | Check Apollo status page |\n\n## Resources\n- [GitHub Actions Secrets](https:\u002F\u002Fdocs.github.com\u002Fen\u002Factions\u002Fsecurity-guides\u002Fencrypted-secrets)\n- [MSW (Mock Service Worker)](https:\u002F\u002Fmswjs.io\u002F)\n- [Vitest Documentation](https:\u002F\u002Fvitest.dev\u002F)\n\n## Next Steps\nProceed to `apollo-deploy-integration` for deployment configuration.\n","# Apollo CI Integration\n\n## Overview\nSet up CI\u002FCD pipelines for Apollo.io integrations with automated testing, secret management, and deployment workflows.\n\n## GitHub Actions Setup\n\n### Basic CI Workflow\n```yaml\n# .github\u002Fworkflows\u002Fapollo-ci.yml\nname: Apollo Integration CI\n\non:\n  push:\n    branches: [main, develop]\n  pull_request:\n    branches: [main]\n\nenv:\n  NODE_VERSION: '20'\n\njobs:\n  test:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n\n      - name: Setup Node.js\n        uses: actions\u002Fsetup-node@v4\n        with:\n          node-version: ${{ env.NODE_VERSION }}\n          cache: 'npm'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Run linting\n        run: npm run lint\n\n      - name: Run unit tests\n        run: npm run test:unit\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY_TEST }}\n\n      - name: Run integration tests\n        if: github.event_name == 'push' && github.ref == 'refs\u002Fheads\u002Fmain'\n        run: npm run test:integration\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY_TEST }}\n\n  validate-apollo:\n    runs-on: ubuntu-latest\n    steps:\n      - uses: actions\u002Fcheckout@v4\n\n      - name: Setup Node.js\n        uses: actions\u002Fsetup-node@v4\n        with:\n          node-version: ${{ env.NODE_VERSION }}\n          cache: 'npm'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Validate Apollo configuration\n        run: npm run apollo:validate\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY_TEST }}\n\n      - name: Check API health\n        run: |\n          curl -sf \"https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Fauth\u002Fhealth?api_key=$APOLLO_API_KEY\" \\\n            || echo \"Warning: Apollo API health check failed\"\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY_TEST }}\n```\n\n### Integration Test Workflow\n```yaml\n# .github\u002Fworkflows\u002Fapollo-integration.yml\nname: Apollo Integration Tests\n\non:\n  schedule:\n    - cron: '0 6 * * *'  # Daily at 6 AM UTC\n  workflow_dispatch:\n\njobs:\n  integration-tests:\n    runs-on: ubuntu-latest\n    timeout-minutes: 30\n\n    steps:\n      - uses: actions\u002Fcheckout@v4\n\n      - name: Setup Node.js\n        uses: actions\u002Fsetup-node@v4\n        with:\n          node-version: '20'\n          cache: 'npm'\n\n      - name: Install dependencies\n        run: npm ci\n\n      - name: Run Apollo integration tests\n        run: npm run test:apollo\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY_TEST }}\n          APOLLO_TEST_DOMAIN: 'apollo.io'\n\n      - name: Upload test results\n        if: always()\n        uses: actions\u002Fupload-artifact@v4\n        with:\n          name: apollo-test-results\n          path: test-results\u002F\n\n      - name: Notify on failure\n        if: failure()\n        uses: slackapi\u002Fslack-github-action@v1\n        with:\n          payload: |\n            {\n              \"text\": \"Apollo integration tests failed!\",\n              \"blocks\": [\n                {\n                  \"type\": \"section\",\n                  \"text\": {\n                    \"type\": \"mrkdwn\",\n                    \"text\": \"*Apollo Integration Tests Failed*\\n\u003C${{ github.server_url }}\u002F${{ github.repository }}\u002Factions\u002Fruns\u002F${{ github.run_id }}|View Run>\"\n                  }\n                }\n              ]\n            }\n        env:\n          SLACK_WEBHOOK_URL: ${{ secrets.SLACK_WEBHOOK_URL }}\n```\n\n## Secrets Management\n\n### GitHub Secrets Setup\n```bash\n# Add secrets via GitHub CLI\ngh secret set APOLLO_API_KEY_TEST --body \"your-test-api-key\"\ngh secret set APOLLO_API_KEY_PROD --body \"your-prod-api-key\"\n\n# List configured secrets\ngh secret list\n```\n\n### Environment-Based Secrets\n```yaml\n# .github\u002Fworkflows\u002Fdeploy.yml\njobs:\n  deploy-staging:\n    environment: staging\n    steps:\n      - name: Deploy to staging\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY }}\n        run: npm run deploy:staging\n\n  deploy-production:\n    environment: production\n    needs: deploy-staging\n    steps:\n      - name: Deploy to production\n        env:\n          APOLLO_API_KEY: ${{ secrets.APOLLO_API_KEY }}\n        run: npm run deploy:production\n```\n\n## Test Configuration\n\n### Test Setup\n```typescript\n\u002F\u002F tests\u002Fsetup\u002Fapollo.ts\nimport { beforeAll, afterAll, beforeEach } from 'vitest';\nimport { setupServer } from 'msw\u002Fnode';\nimport { apolloHandlers } from '.\u002Fmocks\u002Fapollo-handlers';\n\nconst server = setupServer(...apolloHandlers);\n\nbeforeAll(() => {\n  server.listen({ onUnhandledRequest: 'warn' });\n});\n\nafterAll(() => {\n  server.close();\n});\n\nbeforeEach(() => {\n  server.resetHandlers();\n});\n\nexport { server };\n```\n\n### Mock Handlers for CI\n```typescript\n\u002F\u002F tests\u002Fmocks\u002Fapollo-handlers.ts\nimport { http, HttpResponse } from 'msw';\n\nexport const apolloHandlers = [\n  http.get('https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Fauth\u002Fhealth', () => {\n    return HttpResponse.json({ status: 'ok' });\n  }),\n\n  http.post('https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Fpeople\u002Fsearch', async ({ request }) => {\n    const body = await request.json();\n    return HttpResponse.json({\n      people: [\n        {\n          id: 'test-1',\n          name: 'Test User',\n          title: 'Engineer',\n          email: 'test@example.com',\n        },\n      ],\n      pagination: {\n        page: body.page || 1,\n        per_page: body.per_page || 25,\n        total_entries: 1,\n        total_pages: 1,\n      },\n    });\n  }),\n\n  http.get('https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Forganizations\u002Fenrich', ({ request }) => {\n    const url = new URL(request.url);\n    const domain = url.searchParams.get('domain');\n    return HttpResponse.json({\n      organization: {\n        id: 'org-1',\n        name: 'Test Company',\n        primary_domain: domain,\n        industry: 'Technology',\n      },\n    });\n  }),\n];\n```\n\n### Integration Tests\n```typescript\n\u002F\u002F tests\u002Fintegration\u002Fapollo.test.ts\nimport { describe, it, expect, beforeEach } from 'vitest';\nimport { apollo } from '..\u002F..\u002Fsrc\u002Flib\u002Fapollo\u002Fclient';\n\ndescribe('Apollo API Integration', () => {\n  \u002F\u002F Only run with real API in CI\n  const isCI = process.env.CI === 'true';\n  const hasApiKey = !!process.env.APOLLO_API_KEY;\n\n  beforeEach(() => {\n    if (!isCI || !hasApiKey) {\n      console.log('Skipping real API tests - using mocks');\n    }\n  });\n\n  it('should search for people', async () => {\n    const result = await apollo.searchPeople({\n      q_organization_domains: [process.env.APOLLO_TEST_DOMAIN || 'apollo.io'],\n      per_page: 5,\n    });\n\n    expect(result.people).toBeDefined();\n    expect(Array.isArray(result.people)).toBe(true);\n    expect(result.pagination.total_entries).toBeGreaterThanOrEqual(0);\n  });\n\n  it('should enrich organization', async () => {\n    const result = await apollo.enrichOrganization(\n      process.env.APOLLO_TEST_DOMAIN || 'apollo.io'\n    );\n\n    expect(result.organization).toBeDefined();\n    expect(result.organization.name).toBeTruthy();\n  });\n\n  it('should handle rate limits gracefully', async () => {\n    \u002F\u002F This test verifies rate limit handling without actually hitting limits\n    const startTime = Date.now();\n\n    \u002F\u002F Make 5 requests in sequence\n    for (let i = 0; i \u003C 5; i++) {\n      await apollo.searchPeople({ per_page: 1 });\n    }\n\n    const duration = Date.now() - startTime;\n    \u002F\u002F Should complete in reasonable time with rate limiting\n    expect(duration).toBeLessThan(30000);\n  });\n});\n```\n\n## Pipeline Scripts\n\n### package.json Scripts\n```json\n{\n  \"scripts\": {\n    \"test:unit\": \"vitest run --config vitest.unit.config.ts\",\n    \"test:integration\": \"vitest run --config vitest.integration.config.ts\",\n    \"test:apollo\": \"vitest run tests\u002Fintegration\u002Fapollo.test.ts\",\n    \"apollo:validate\": \"tsx scripts\u002Fvalidate-apollo-config.ts\",\n    \"apollo:health\": \"curl -sf 'https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Fauth\u002Fhealth?api_key=$APOLLO_API_KEY'\"\n  }\n}\n```\n\n### Validation Script\n```typescript\n\u002F\u002F scripts\u002Fvalidate-apollo-config.ts\nasync function validateConfig() {\n  const checks = [];\n\n  \u002F\u002F Check API key\n  if (!process.env.APOLLO_API_KEY) {\n    checks.push({ name: 'API Key', status: 'fail', message: 'Missing' });\n  } else {\n    checks.push({ name: 'API Key', status: 'pass', message: 'Present' });\n  }\n\n  \u002F\u002F Check API connectivity\n  try {\n    const response = await fetch(\n      `https:\u002F\u002Fapi.apollo.io\u002Fv1\u002Fauth\u002Fhealth?api_key=${process.env.APOLLO_API_KEY}`\n    );\n    checks.push({\n      name: 'API Health',\n      status: response.ok ? 'pass' : 'fail',\n      message: response.ok ? 'Healthy' : `Status: ${response.status}`,\n    });\n  } catch (error) {\n    checks.push({\n      name: 'API Health',\n      status: 'fail',\n      message: 'Connection failed',\n    });\n  }\n\n  \u002F\u002F Output results\n  const failed = checks.filter((c) => c.status === 'fail');\n  if (failed.length > 0) {\n    console.error('Validation failed:', failed);\n    process.exit(1);\n  }\n\n  console.log('All checks passed:', checks);\n}\n\nvalidateConfig();\n```\n\n## Output\n- GitHub Actions workflows for CI\n- Secrets management configuration\n- Test setup with MSW mocks\n- Integration test suite\n- Validation scripts\n\n## Error Handling\n| Issue | Resolution |\n|-------|------------|\n| Secret not found | Verify secret name in GitHub |\n| Tests timeout | Increase timeout or mock API |\n| Rate limited in CI | Use mocks for unit tests |\n| Health check fails | Check Apollo status page |\n\n## Resources\n- [GitHub Actions Secrets](https:\u002F\u002Fdocs.github.com\u002Fen\u002Factions\u002Fsecurity-guides\u002Fencrypted-secrets)\n- [MSW (Mock Service Worker)](https:\u002F\u002Fmswjs.io\u002F)\n- [Vitest Documentation](https:\u002F\u002Fvitest.dev\u002F)\n\n## Next Steps\nProceed to `apollo-deploy-integration` for deployment configuration.\n",{"name":5,"author":57,"license":15,"version":58,"description":59,"allowed-tools":60},"Jeremy Longshore \u003Cjeremy@intentsolutions.io>","1.0.0","Configure Apollo.io CI\u002FCD integration.\nUse when setting up automated testing, continuous integration,\nor deployment pipelines for Apollo integrations.\nTrigger with phrases like \"apollo ci\", \"apollo github actions\",\n\"apollo pipeline\", \"apollo ci\u002Fcd\", \"apollo automated tests\".\n","Read, Write, Edit, Bash(gh:*), Bash(curl:*)","main","7439377908fdee98c9bb5863391212b95453de95","tests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fsaas-packs\u002Fapollo-pack\u002Fskills\u002Fapollo-ci-integration",234,"https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust","https:\u002F\u002Fgithub.com\u002FDicklesworthstone","https:\u002F\u002Fwww.jeffreyemanuel.com\u002F","Building in NY","2026-11-13 11:50:27",{"source":8,"skillName":5,"commands":71,"prompt":81,"zipAvailable":82},[72,75,78],{"tool":73,"command":74},"npx","npx skills add Dicklesworthstone\u002Fpi_agent_rust --skill apollo-ci-integration",{"tool":76,"command":77},"bunx","bunx skills add Dicklesworthstone\u002Fpi_agent_rust --skill apollo-ci-integration",{"tool":79,"command":80},"pnpm","pnpm dlx skills add Dicklesworthstone\u002Fpi_agent_rust --skill apollo-ci-integration","安装技能，技能地址：https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Fplugins-community\u002Fplugins\u002Fsaas-packs\u002Fapollo-pack\u002Fskills\u002Fapollo-ci-integration\u002FSKILL.md",true,[84,89,95],{"path":85,"resourceType":85,"resourceTypeDesc":86,"sizeBytes":87,"sourceHtmlUrl":88},"LICENSE","许可证",1071,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fmcp-servers\u002Fdanthamanvoiss-salesportl-pool-cleaning-main-router\u002FLICENSE",{"path":90,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":93,"sourceHtmlUrl":94},"SOURCE.md","REFERENCE","参考文档",489,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fmcp-servers\u002Fdanthamanvoiss-salesportl-pool-cleaning-main-router\u002FSOURCE.md",{"path":96,"resourceType":91,"resourceTypeDesc":92,"sizeBytes":97,"sourceHtmlUrl":98},"TRUST.auto.yaml",2217,"https:\u002F\u002Fgithub.com\u002Fjiayaoqijia\u002Fcryptoskill\u002Fblob\u002Fmain\u002Fskills\u002Fmcp-servers\u002Fdanthamanvoiss-salesportl-pool-cleaning-main-router\u002FTRUST.auto.yaml",[100,137,159,185,211,233],{"skillNo":101,"name":102,"nameZh":6,"description":103,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":104,"licenseFileUrl":105,"sourceHtmlUrl":106,"categories":107,"keywords":111,"publishedAt":52},"01M6FEGPPK0ZTKCCM0R3E3KS33","web-artifacts-builder","Suite of tools for creating elaborate, multi-component claude.ai HTML artifacts using modern frontend web technologies (React, Tailwind CSS, shadcn\u002Fui). Use for complex artifacts requiring state management, routing, or shadcn\u002Fui components - not for simple single-file HTML\u002FJSX artifacts.","Apache-2.0","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Futilities\u002Fweb-artifacts-builder\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Futilities\u002Fweb-artifacts-builder\u002FSKILL.md",[108],{"categoryNo":109,"categoryName":110,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000009","前端开发",[112,113,114,115,116,117,118,119,120,121,122,123,124,125,126,127,128,129,38,130,131,132,133,134,33,135,136],"web artifacts builder","web","artifacts","artifacts builder","builder","frontend","css","components","react","component","routing","state management","state","shadcn","file","ui","Tools","Tailwind","html","single-file","simple","ui components","multi","jsx","suite",{"skillNo":138,"name":139,"nameZh":6,"description":140,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":104,"licenseFileUrl":141,"sourceHtmlUrl":142,"categories":143,"keywords":146,"publishedAt":52},"01M6FEE9VTK1W4GY21AKREJXRG","webapp-testing","Toolkit for interacting with and testing local web applications using Playwright. Supports verifying frontend functionality, debugging UI behavior, capturing browser screenshots, and viewing browser logs.","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fsecurity\u002Fwebapp-testing\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fsecurity\u002Fwebapp-testing\u002FSKILL.md",[144,145],{"categoryNo":19,"categoryName":20,"taxonomyType":21,"taxonomyTypeDesc":22},{"categoryNo":109,"categoryName":110,"taxonomyType":21,"taxonomyTypeDesc":22},[42,147,148,117,149,150,113,151,152,153,127,154,155,156,157,158,33],"webapp testing","webapp","screenshots","playwright","debugging","toolkit","browser","logs","applications","behavior","local","with",{"skillNo":160,"name":161,"nameZh":6,"description":162,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":163,"sourceHtmlUrl":164,"categories":165,"keywords":166,"publishedAt":52},"01M6FE20F7ZTQBFWKF4MPJ2SBX","neuropixels-analysis","Neuropixels neural recording analysis. Load SpikeGLX\u002FOpenEphys data, preprocess, motion correction, Kilosort4 spike sorting, quality metrics, Allen\u002FIBL curation, AI-assisted visual analysis, for Neuropixels 1.0\u002F2.0 extracellular electrophysiology. Use when working with neural recordings, spike sorting, extracellular electrophysiology, or when the user mentions Neuropixels, SpikeGLX, Open Ephys, Kilosort, quality metrics, or unit curation.","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Fneuropixels-analysis\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fscientific\u002Fneuropixels-analysis\u002FSKILL.md",[],[167,168,169,170,171,172,173,174,38,175,176,177,178,179,180,181,158,182,183,184,33,32],"analysis","neuropixels analysis","spike","metrics","data","open","quality","user","recordings","Neural","motion","visual","quality metrics","unit","sorting","curation","recording","load",{"skillNo":186,"name":187,"nameZh":6,"description":188,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":104,"licenseFileUrl":189,"sourceHtmlUrl":190,"categories":191,"keywords":195,"publishedAt":52},"01M6FDP0PDK6F1GGX395C7625Z","skill-creator","Guide for creating effective skills. This skill should be used when users want to create a new skill (or update an existing skill) that extends Claude's capabilities with specialized knowledge, workflows, or tool integrations.","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fskill-creator\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fskill-creator\u002FSKILL.md",[192],{"categoryNo":193,"categoryName":194,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000023","Skill与智能体开发",[196,197,198,199,200,201,202,203,44,204,205,206,207,208,158,33,209,32,210],"skill creator","creator","workflows","create","update","capabilities","knowledge","tool","specialized","guide","new skill","existing skill","users","Existing","new",{"skillNo":212,"name":213,"nameZh":6,"description":214,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":15,"licenseFileUrl":215,"sourceHtmlUrl":216,"categories":217,"keywords":219,"publishedAt":52},"01M6FDM8Y7VK7NYG9SM7QPA3PW","notebooklm","Use this skill to query your Google NotebookLM notebooks directly from Claude Code for source-grounded, citation-backed answers from Gemini. Browser automation, library management, persistent auth. Drastically reduced hallucinations through document-only responses.","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fnotebooklm\u002FLICENSE","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fproductivity\u002Fnotebooklm\u002FSKILL.md",[218],{"categoryNo":193,"categoryName":194,"taxonomyType":21,"taxonomyTypeDesc":22},[213,220,221,222,223,224,225,153,226,227,38,228,229,230,231,33,232],"google","browser automation","gemini","automation","auth","code","library","management","only","document","query","Citation","source",{"skillNo":234,"name":235,"nameZh":6,"description":236,"descriptionZh":6,"repositoryFullName":8,"ownerLogin":9,"ownerAvatarUrl":10,"ownerAccountNo":11,"ownerDisplayName":12,"repositoryNo":13,"starsCount":14,"licenseSpdxId":104,"licenseFileUrl":237,"sourceHtmlUrl":238,"categories":239,"keywords":246,"publishedAt":52},"01M6FDHPXE10J3XGTCH5HBHS1M","slack-gif-creator","Knowledge and utilities for creating animated GIFs optimized for Slack. Provides constraints, validation tools, and animation concepts. Use when users request animated GIFs for Slack like \"make me a GIF of X doing Y for Slack.\"","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fenterprise-communication\u002Fslack-gif-creator\u002FLICENSE.txt","https:\u002F\u002Fgithub.com\u002FDicklesworthstone\u002Fpi_agent_rust\u002Fblob\u002Fmain\u002Ftests\u002Fext_conformance\u002Fartifacts\u002Ftemplates-davila7\u002Fcli-tool\u002Fcomponents\u002Fskills\u002Fenterprise-communication\u002Fslack-gif-creator\u002FSKILL.md",[240,243],{"categoryNo":241,"categoryName":242,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000005","邮件与沟通",{"categoryNo":244,"categoryName":245,"taxonomyType":21,"taxonomyTypeDesc":22},"01JBSEEDCAT000000000000016","图像与多媒体",[247,248,249,197,250,128,251,252,202,38,253,208,254,255,256,33,257,32],"slack gif creator","slack","gif","validation","constraints","Animation","me","make","Utilities","concepts","request"]