From documenso-pack
Configures GitHub Actions CI/CD pipelines for Documenso projects with unit tests using Vitest mocks and integration tests against staging API.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin documenso-packThis skill is limited to using the following tools:
Configure CI/CD pipelines for Documenso integrations with GitHub Actions. Covers unit testing with mocks, integration testing against staging, and deployment workflows with secret management.
Sets up local dev environment for Documenso integrations: Docker self-hosting, TypeScript SDK client, test scripts, project structure, and env configs for rapid testing workflows.
Installs and configures Doc Detective GitHub Action workflow for automated documentation testing in CI. Detects project context, creates YAML file, sets triggers, PR/issue creation, and integrations.
Sets up GitHub Actions CI/CD workflows for Klaviyo API integrations, including Vitest unit tests, API integration tests, npm setup, and secret configuration.
Share bugs, ideas, or general feedback.
Configure CI/CD pipelines for Documenso integrations with GitHub Actions. Covers unit testing with mocks, integration testing against staging, and deployment workflows with secret management.
documenso-local-dev-loop)# .github/workflows/documenso-ci.yml
name: Documenso CI
on:
push:
branches: [main, develop]
pull_request:
branches: [main]
env:
NODE_ENV: test
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
# Unit tests use mocks — no API key needed
integration-tests:
runs-on: ubuntu-latest
if: github.event_name == 'push' # Only on push to main/develop
needs: unit-tests
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with:
node-version: '20'
cache: 'npm'
- run: npm ci
- run: npm run test:integration
env:
DOCUMENSO_API_KEY: ${{ secrets.DOCUMENSO_STAGING_API_KEY }}
- run: npm run test:cleanup # Remove test documents
env:
DOCUMENSO_API_KEY: ${{ secrets.DOCUMENSO_STAGING_API_KEY }}
if: always()
// tests/unit/document-service.test.ts
import { describe, it, expect, vi, beforeEach } from "vitest";
import { createMockClient } from "../mocks/documenso";
import { DocumentService } from "../../src/services/document-service";
describe("DocumentService", () => {
let service: DocumentService;
let mockClient: ReturnType<typeof createMockClient>;
beforeEach(() => {
mockClient = createMockClient();
service = new DocumentService(mockClient as any);
});
it("creates document with recipients and sends", async () => {
const result = await service.createAndSend({
title: "Test Contract",
pdfPath: "./fixtures/test.pdf",
signers: [{ email: "test@example.com", name: "Test User" }],
});
expect(mockClient.documents.createV0).toHaveBeenCalledWith({ title: "Test Contract" });
expect(mockClient.documentsRecipients.createV0).toHaveBeenCalled();
expect(mockClient.documents.sendV0).toHaveBeenCalled();
expect(result.documentId).toBe(1);
});
it("handles API errors gracefully", async () => {
mockClient.documents.createV0.mockRejectedValue(
Object.assign(new Error("Unauthorized"), { statusCode: 401 })
);
await expect(service.createAndSend({
title: "Test",
pdfPath: "./fixtures/test.pdf",
signers: [],
})).rejects.toThrow("Unauthorized");
});
});
// tests/integration/document-lifecycle.test.ts
import { describe, it, expect, afterAll } from "vitest";
import { Documenso } from "@documenso/sdk-typescript";
const client = new Documenso({ apiKey: process.env.DOCUMENSO_API_KEY! });
const testDocIds: number[] = [];
describe("Document Lifecycle (Integration)", () => {
it("creates a document", async () => {
const doc = await client.documents.createV0({
title: "[CI-TEST] Integration Test",
});
testDocIds.push(doc.documentId);
expect(doc.documentId).toBeGreaterThan(0);
}, 30000);
it("lists documents", async () => {
const { documents } = await client.documents.findV0({ page: 1, perPage: 5 });
expect(documents.length).toBeGreaterThan(0);
}, 15000);
afterAll(async () => {
// Cleanup: delete test documents
for (const id of testDocIds) {
try {
await client.documents.deleteV0(id);
} catch {
console.warn(`Cleanup: could not delete document ${id}`);
}
}
});
});
# Using GitHub CLI
gh secret set DOCUMENSO_STAGING_API_KEY --body "api_stg_xxxxxxxxxxxx"
gh secret set DOCUMENSO_WEBHOOK_SECRET --body "whsec_xxxxxxxxxxxx"
# Verify secrets exist
gh secret list
{
"scripts": {
"test": "vitest run tests/unit/",
"test:integration": "vitest run tests/integration/ --timeout 60000",
"test:cleanup": "tsx scripts/cleanup-test-docs.ts",
"test:all": "npm test && npm run test:integration"
}
}
# .husky/pre-commit
npm test -- --run
This runs unit tests (with mocks) before every commit, catching issues early without needing API access.
| Test Type | Runs On | API Key Needed? | Speed |
|---|---|---|---|
| Unit tests (mocks) | Every push + PR | No | Fast (~5s) |
| Integration tests | Push to main/develop only | Yes (staging) | Slow (~30s) |
| Cleanup | After integration tests | Yes (staging) | Fast |
| CI Issue | Cause | Solution |
|---|---|---|
| Integration test timeout | Slow API | Increase vitest timeout to 60s |
| Rate limit in CI | Too many test runs | Use mocks for PRs, live API only on main |
| Secret not found | Missing GitHub secret | Add via gh secret set |
| Stale test data | Cleanup didn't run | Run npm run test:cleanup manually |
For deployment strategies, see documenso-deploy-integration.