Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
207 changes: 206 additions & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -392,11 +392,212 @@ jobs:
echo " - Local path installation"
echo ""

bun-integration:
name: Bun Integration Tests
runs-on: ubuntu-latest
needs: build
steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Setup Bun
uses: oven-sh/setup-bun@v2
with:
bun-version: latest

- name: Install dependencies
run: bun install

- name: Build plugin
run: bun run build

- name: Download package artifact
uses: actions/download-artifact@v4
with:
name: npm-package

- name: Test 1 - Plugin loading with Bun
run: |
echo "=== Testing Bun plugin loading ==="

# Create test directory
mkdir -p /tmp/bun-plugin-test
cd /tmp/bun-plugin-test

# Initialize with Bun
bun init -y

# Install from tarball
TARBALL=$(ls $GITHUB_WORKSPACE/*.tgz)
echo "Installing from tarball: $TARBALL"
bun add "$TARBALL"

# Create test script
cat > test-import.ts << 'EOF'
import { createWebhookPlugin, OpencodeEventType } from 'opencode-webhooks';

console.log('Testing Bun import...');

const plugin = createWebhookPlugin({
webhooks: [
{
url: 'https://example.com/webhook',
events: [OpencodeEventType.SESSION_CREATED]
}
]
});

if (typeof plugin !== 'function') {
console.error('❌ Plugin creation failed');
process.exit(1);
}

console.log('✅ Bun import successful');
EOF

# Run with Bun
bun run test-import.ts || (echo "❌ Bun import failed" && exit 1)

echo "✅ Bun plugin loading successful"

- name: Test 2 - Run Bun integration tests
run: |
echo "=== Running Bun integration tests ==="
cd $GITHUB_WORKSPACE
bun test tests/integration.bun.test.ts || (echo "❌ Bun tests failed" && exit 1)
echo "✅ Bun integration tests passed"

- name: Test 3 - Bun plugin execution
run: |
echo "=== Testing Bun plugin execution ==="

# Create test directory
mkdir -p /tmp/bun-exec-test
cd /tmp/bun-exec-test

# Initialize
bun init -y

# Install from tarball
TARBALL=$(ls $GITHUB_WORKSPACE/*.tgz)
bun add "$TARBALL"

# Create execution test
cat > test-exec.ts << 'EOF'
import { WebhookPlugin, OpencodeEventType } from 'opencode-webhooks';

console.log('Creating plugin instance...');

const plugin = new WebhookPlugin({
webhooks: [
{
url: 'https://httpbin.org/post',
events: [OpencodeEventType.SESSION_CREATED],
transformPayload: (payload) => ({
message: 'Bun test webhook',
sessionId: payload.sessionId
}),
timeoutMs: 5000,
retry: { maxAttempts: 1 }
}
],
debug: true
});

console.log('Triggering test event...');

const results = await plugin.handleEvent(OpencodeEventType.SESSION_CREATED, {
sessionId: 'bun-test-session-123',
userId: 'bun-test-user'
});

console.log('Results:', JSON.stringify(results, null, 2));

if (results.length === 0) {
console.error('❌ No results returned');
process.exit(1);
}

if (!results[0].success) {
console.error('❌ Webhook failed:', results[0].error);
process.exit(1);
}

if (results[0].statusCode !== 200) {
console.error('❌ Unexpected status code:', results[0].statusCode);
process.exit(1);
}

console.log('✅ Bun plugin execution successful');
EOF

# Run with Bun
bun run test-exec.ts || (echo "❌ Bun execution test failed" && exit 1)

echo "✅ Bun plugin execution successful"

- name: Test 4 - Bun performance comparison
run: |
echo "=== Testing Bun performance ==="

cd $GITHUB_WORKSPACE

# Create performance test
cat > /tmp/bun-perf-test.ts << 'EOF'
import { WebhookPlugin, OpencodeEventType } from './src/index';

const plugin = new WebhookPlugin({
webhooks: [
{
url: 'https://httpbin.org/post',
events: [OpencodeEventType.FILE_EDITED],
timeoutMs: 5000,
retry: { maxAttempts: 1 }
}
]
});

const startTime = performance.now();
const promises = Array.from({ length: 5 }, (_, i) =>
plugin.handleEvent(OpencodeEventType.FILE_EDITED, {
sessionId: 'perf-test',
changeId: i
})
);

await Promise.all(promises);
const duration = performance.now() - startTime;

console.log(`Bun: Processed 5 events in ${duration.toFixed(2)}ms`);
console.log(`Average: ${(duration / 5).toFixed(2)}ms per event`);
EOF

bun run /tmp/bun-perf-test.ts || echo "Performance test informational only"

echo "✅ Bun performance test complete"

- name: Bun integration summary
if: always()
run: |
echo ""
echo "======================================"
echo " Bun Integration Test Summary"
echo "======================================"
echo ""
echo "✅ All Bun integration tests passed!"
echo ""
echo "Verified scenarios:"
echo " - Plugin loading with Bun runtime"
echo " - Bun test suite execution"
echo " - Plugin hook execution with real HTTP"
echo " - Bun performance characteristics"
echo ""

# Combined check that runs after all other jobs
ci-success:
name: CI Success
runs-on: ubuntu-latest
needs: [lint, test, build, plugin-integration]
needs: [lint, test, build, plugin-integration, bun-integration]
if: always()
steps:
- name: Check all jobs
Expand All @@ -417,4 +618,8 @@ jobs:
echo "Plugin integration tests failed"
exit 1
fi
if [[ "${{ needs.bun-integration.result }}" != "success" ]]; then
echo "Bun integration tests failed"
exit 1
fi
echo "All CI checks passed!"
2 changes: 1 addition & 1 deletion eslint.config.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,6 @@ export default [
},
},
{
ignores: ['dist', 'node_modules', 'coverage', '*.js'],
ignores: ['dist', 'node_modules', 'coverage', '*.js', 'tests/**/*.bun.test.ts'],
},
];
6 changes: 5 additions & 1 deletion examples/custom-webhook.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
* 4. Restart OpenCode
*/

import type { Plugin } from '@opencode-ai/plugin';
import { createWebhookPlugin } from 'opencode-webhooks';

// ============================================================================
Expand All @@ -22,7 +23,8 @@ const WEBHOOK_URL = 'https://your-webhook-endpoint.com/api/events';
// Plugin Setup
// ============================================================================

export default createWebhookPlugin({
// Export the plugin with explicit type annotation for OpenCode
const CustomWebhookPlugin: Plugin = createWebhookPlugin({
webhooks: [
{
url: WEBHOOK_URL,
Expand Down Expand Up @@ -77,3 +79,5 @@ export default createWebhookPlugin({
// Enable debug logging (set to false in production)
debug: false,
});

export default CustomWebhookPlugin;
6 changes: 5 additions & 1 deletion examples/home-assistant.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
* Full guide: https://www.home-assistant.io/docs/automation/trigger/#webhook-trigger
*/

import type { Plugin } from '@opencode-ai/plugin';
import { createWebhookPlugin } from 'opencode-webhooks';

// ============================================================================
Expand All @@ -43,7 +44,8 @@ const WEBHOOK_URL = `${HOME_ASSISTANT_URL}/api/webhook/${WEBHOOK_ID}`;
// Plugin Setup
// ============================================================================

export default createWebhookPlugin({
// Export the plugin with explicit type annotation for OpenCode
const HomeAssistantPlugin: Plugin = createWebhookPlugin({
webhooks: [
{
url: WEBHOOK_URL,
Expand Down Expand Up @@ -127,3 +129,5 @@ export default createWebhookPlugin({
// Enable debug logging (set to false in production)
debug: false,
});

export default HomeAssistantPlugin;
8 changes: 6 additions & 2 deletions examples/local-dev.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@
* 4. Restart OpenCode
*/

import { createWebhookPlugin } from './opencode-webhooks/src/index.ts';
import type { Plugin } from '@opencode-ai/plugin';
import { createWebhookPlugin } from './opencode-webhooks/src/index.js';

// ============================================================================
// Configuration
Expand All @@ -23,7 +24,8 @@ const WEBHOOK_URL = 'https://your-webhook-endpoint.com/api/events';
// Plugin Setup
// ============================================================================

export default createWebhookPlugin({
// Export the plugin with explicit type annotation for OpenCode
const LocalDevPlugin: Plugin = createWebhookPlugin({
webhooks: [
{
url: WEBHOOK_URL,
Expand All @@ -49,3 +51,5 @@ export default createWebhookPlugin({
],
debug: true,
});

export default LocalDevPlugin;
8 changes: 6 additions & 2 deletions examples/slack-workflow.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
* Full guide: https://slack.com/help/articles/360041352714
*/

import type { Plugin } from '@opencode-ai/plugin';
import { createWebhookPlugin } from 'opencode-webhooks';

// ============================================================================
Expand All @@ -30,7 +31,8 @@ const WEBHOOK_URL = 'https://hooks.slack.com/workflows/T00000000/A00000000/12345
// Plugin Setup
// ============================================================================

export default createWebhookPlugin({
// Export the plugin with explicit type annotation for OpenCode
const SlackWorkflowPlugin: Plugin = createWebhookPlugin({
webhooks: [
{
url: WEBHOOK_URL,
Expand Down Expand Up @@ -78,13 +80,13 @@ export default createWebhookPlugin({

// Flatten payload to top level for Slack Workflow Builder
return {
...payload,
eventType: payload.eventType,
sessionId: payload.sessionId || 'N/A',
timestamp: payload.timestamp,
message: `${emoji} ${payload.eventType}`,
eventInfo: `${description}${messagePreview}\n\nAvailable data: ${availableKeys.join(', ')}`,
messageContent: messageContent,
...payload,
};
},

Expand All @@ -101,3 +103,5 @@ export default createWebhookPlugin({
// Enable debug logging (set to false in production)
debug: false,
});

export default SlackWorkflowPlugin;
4 changes: 4 additions & 0 deletions jest.config.cjs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ module.exports = {
testEnvironment: 'node',
roots: ['<rootDir>/src', '<rootDir>/tests'],
testMatch: ['**/__tests__/**/*.ts', '**/?(*.)+(spec|test).ts'],
testPathIgnorePatterns: [
'/node_modules/',
'\\.bun\\.test\\.ts$' // Exclude Bun-specific tests from Jest
],
collectCoverageFrom: [
'src/**/*.ts',
'!src/**/*.d.ts',
Expand Down
5 changes: 5 additions & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"test": "jest",
"test:watch": "jest --watch",
"test:coverage": "jest --coverage",
"test:bun": "bun test tests/integration.bun.test.ts",
"lint": "eslint 'src/**/*.ts' 'tests/**/*.ts'",
"lint:fix": "eslint 'src/**/*.ts' 'tests/**/*.ts' --fix"
},
Expand Down Expand Up @@ -61,9 +62,13 @@
"axios": "^1.6.0"
},
"peerDependencies": {
"@opencode-ai/plugin": "^1.0.0",
"opencode": "*"
},
"peerDependenciesMeta": {
"@opencode-ai/plugin": {
"optional": true
},
"opencode": {
"optional": true
}
Expand Down
Loading