From evernote-pack
Configures GitHub Actions CI/CD pipelines for Evernote integrations with JS mock NoteStore for unit tests and sandbox integration tests.
npx claudepluginhub jeremylongshore/claude-code-plugins-plus-skills --plugin evernote-packThis skill is limited to using the following tools:
Configure continuous integration pipelines for Evernote integrations with mock-based unit tests, sandbox-based integration tests, credential management, and deployment workflows.
Sets up local dev workflow for Evernote API with sandbox credentials, JS client wrapper, ENML utilities, Express OAuth server, and test scripts.
Sets up GitHub Actions CI pipelines for OneNote Graph API integrations using MSW mocks or live Azure AD tests with credential isolation.
Sets up GitHub Actions CI/CD for Apollo.io integrations: MSW unit tests, sandbox staging, main-branch live API tests, secret scanning.
Share bugs, ideas, or general feedback.
Configure continuous integration pipelines for Evernote integrations with mock-based unit tests, sandbox-based integration tests, credential management, and deployment workflows.
Create a workflow that runs unit tests on every PR and integration tests on merges to main. Store sandbox credentials as GitHub Actions secrets.
# .github/workflows/evernote-ci.yml
name: Evernote CI
on: [push, pull_request]
jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/setup-node@v4
with: { node-version: '20' }
- run: npm ci
- run: npm test
- name: Integration tests
if: github.ref == 'refs/heads/main'
env:
EVERNOTE_DEV_TOKEN: ${{ secrets.EVERNOTE_SANDBOX_TOKEN }}
EVERNOTE_SANDBOX: 'true'
run: npm run test:integration
Create a mock NoteStore that returns predictable data without hitting the API. Mock createNote, getNote, findNotesMetadata, listNotebooks, and listTags.
class MockNoteStore {
constructor() {
this.notes = new Map();
this.notebooks = [{ guid: 'nb-1', name: 'Default', defaultNotebook: true }];
}
async createNote(note) {
const guid = `note-${Date.now()}`;
const created = { ...note, guid, created: Date.now(), updated: Date.now() };
this.notes.set(guid, created);
return created;
}
async getNote(guid, withContent) {
const note = this.notes.get(guid);
if (!note) throw { identifier: 'Note.guid', key: guid };
return withContent ? note : { ...note, content: undefined };
}
async listNotebooks() { return this.notebooks; }
}
Write unit tests against the mock client (fast, no credentials needed). Write integration tests against the sandbox (slow, needs EVERNOTE_DEV_TOKEN). Tag integration tests so they can run separately.
Store EVERNOTE_CONSUMER_KEY, EVERNOTE_CONSUMER_SECRET, and EVERNOTE_DEV_TOKEN as repository secrets. Never log or echo secret values. Use environment-specific secret names for staging vs production.
For the full CI workflow, mock client, test examples, and deployment pipeline, see Implementation Guide.
MockNoteStore class for deterministic unit testingtest, test:unit, test:integration| Error | Cause | Solution |
|---|---|---|
| Integration test auth failure | Expired sandbox token | Regenerate Developer Token in sandbox settings |
| Flaky integration tests | Rate limits in CI | Add delays between integration tests, reduce parallelism |
| Secret not available | Missing repository secret | Add secret in GitHub Settings > Secrets and variables |
| Mock drift | Mock doesn't match real API behavior | Update mock when upgrading SDK version |
For deployment pipelines, see evernote-deploy-integration.
Unit test suite: Test NoteService.createNote() against MockNoteStore to verify ENML wrapping, title sanitization, and tag handling without any API calls.
Sandbox integration test: In CI, create a note in the sandbox, retrieve it by GUID, verify content matches, then delete it. Runs only on main branch merges.