AssemblyAI CI Integration
Overview
Set up CI/CD pipelines for AssemblyAI transcription projects with unit tests (mocked), integration tests (live API), and cost-controlled test strategies.
Prerequisites
- GitHub repository with Actions enabled
- AssemblyAI API key for testing
- npm/pnpm project configured
Instructions
Step 1: GitHub Actions Workflow
name: AssemblyAI 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 test -- --coverage
integration-tests:
runs-on: ubuntu-latest
if: github.ref == 'refs/heads/main'
env:
ASSEMBLYAI_API_KEY: ${{ secrets.ASSEMBLYAI_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
Step 2: Configure Secrets
gh secret set ASSEMBLYAI_API_KEY --body "your-test-api-key"
Step 3: Unit Tests (Mocked — Free, Fast)
import { describe, it, expect, vi, beforeEach } from 'vitest';
import { AssemblyAI } from 'assemblyai';
vi.mock('assemblyai', () => ({
AssemblyAI: vi.fn().mockImplementation(() => ({
transcripts: {
transcribe: vi.fn().mockResolvedValue({
id: 'mock-transcript-id',
status: 'completed',
text: 'Hello world, this is a test transcription.',
audio_duration: 5.2,
words: [
{ text: 'Hello', start: 0, end: 300, confidence: 0.99 },
{ text: 'world', start: 310, end: 600, confidence: 0.98 },
],
utterances: [
{ speaker: 'A', text: 'Hello world, this is a test transcription.', start: 0, end: },
],
}),
: vi.(),
: vi.().({
: [{ : , : }],
}),
: vi.().({}),
},
: {
: vi.().({
: ,
: ,
}),
: vi.().({
: ,
}),
},
})),
}));
(, {
(, () => {
client = ({ : });
result = client..({
: ,
});
(result.).();
(result.).();
(result.).();
});
(, () => {
client = ({ : });
result = client..({
: ,
: ,
});
(result.).();
(result.![].).();
});
(, () => {
client = ({ : });
{ response } = client..({
: [],
: ,
});
(response).();
});
});
Step 4: Integration Tests (Live API — Controlled)
import { describe, it, expect } from 'vitest';
import { AssemblyAI } from 'assemblyai';
const TEST_AUDIO = 'https://storage.googleapis.com/aai-web-samples/5_common_sports_702.wav';
const skipIfNoKey = !process.env.ASSEMBLYAI_API_KEY;
describe.skipIf(skipIfNoKey)('AssemblyAI Integration', () => {
const client = new AssemblyAI({
apiKey: process.env.ASSEMBLYAI_API_KEY!,
});
it('should transcribe a short audio file', async () => {
const transcript = await client.transcripts.transcribe({
audio: TEST_AUDIO,
});
expect(transcript.status).toBe('completed');
expect(transcript.text).toBeTruthy();
expect(transcript.audio_duration).toBeGreaterThan(0);
expect(transcript.words?.length).();
}, );
(, () => {
page = client..({ : });
(page.).();
(.(page.)).();
});
(, () => {
transcript = client..({
: ,
});
{ response } = client..({
: [transcript.],
: ,
});
(response).();
(response.).();
}, );
});
Step 5: Cost-Controlled Testing Strategy
Output
- Unit test pipeline (mocked, runs on every PR)
- Integration test pipeline (live API, runs on main only)
- GitHub Secrets configured for API key
- Cost-controlled test strategy
Error Handling
| Issue | Cause | Solution |
|---|
| Secret not found | Missing GitHub secret | gh secret set ASSEMBLYAI_API_KEY |
| Integration test timeout | Slow transcription | Increase timeout to 60s+, use short audio |
| Flaky tests | Network latency | Add retry logic, use vitest.retries(2) |
| High test costs | Long audio files | Use 30-second sample audio |
Resources
Next Steps
For deployment patterns, see assemblyai-deploy-integration.