Skip to content

Conversation

A-D-E
Copy link
Contributor

@A-D-E A-D-E commented Aug 14, 2025

This MR implements a complete webhook system that enables real-time deployment notifications and integrations with external services.

🚀 Features Added

  • Webhook Management: Full CRUD operations for webhook configuration via UI and API
  • Multiple Event Types: Support for deployment lifecycle events (started, success, failed, cancelled)
  • Template System: Three payload formats - Generic JSON, Slack, and n8n optimized
  • Security: HMAC-SHA256 signature validation with optional secrets
  • Reliability: Retry mechanism with exponential backoff and delivery tracking
  • UI Components: Complete webhook management interface with delivery history

🔧 Technical Implementation

  • Database Schema: New webhook and webhook_deliveries tables
  • TRPC API: Comprehensive webhook router with 10+ endpoints
  • Service Integration: Webhooks triggered from deployment service lifecycle points
  • Error Handling: Robust retry logic and delivery status tracking
  • Testing: Unit tests covering validation and payload structure

📚 Documentation

  • Implementation Guide: Technical details, API usage, and security considerations
  • User Guide: Step-by-step setup instructions and troubleshooting
  • Integration Examples: Slack, n8n, and custom monitoring setups
  • Security Best Practices: HTTPS requirements and HMAC verification

🎯 Use Cases

  • DevOps notifications (Slack, email, PagerDuty)
  • Workflow automation (n8n, Zapier)
  • Monitoring system integration
  • Team collaboration tools (Jira, Trello, Microsoft Teams)

✅ Testing

  • Unit tests for webhook validation and payload structure
  • Manual testing procedures documented
  • Test webhook functionality built into UI

🔒 Security

  • HTTPS-only webhook endpoints
  • Optional HMAC-SHA256 signature validation
  • Custom headers support for authentication
  • Comprehensive error logging and monitoring

This implementation provides a solid foundation for deployment automation and team notifications while maintaining security and reliability standards.

A-D-E and others added 23 commits August 12, 2025 08:32
- Merged upstream canary branch to get latest v0.24.10
- Updated Node.js to 20.16.0 as required
- Fixed database schema with migrations
- Resolved dependency issues
- Add webhook and webhook_delivery database tables
- Implement complete webhook service with CRUD operations
- Add webhook triggering and delivery system
- Implement retry mechanism with exponential backoff
- Add template formatters for Slack and n8n
- Include HMAC signature generation for security
- Add delivery logging with 100-entry limit per webhook
- Add webhook triggering for deployment.started event in createDeployment
- Add webhook triggering for deployment.started event in createDeploymentCompose
- Enhance updateDeploymentStatus to trigger success/failed/cancelled webhooks
- Include full deployment context in webhook payloads
- Fire webhooks asynchronously to avoid blocking deployments
- Create webhook router with full CRUD operations
- Add endpoints for webhook testing and delivery history
- Include batch operations and statistics endpoints
- Add webhook toggle functionality
- Register webhook router in main API router
- Create webhook listing component with status indicators
- Add webhook form with support for Slack, n8n, and generic templates
- Implement webhook deliveries modal to show webhook history
- Add webhook management to application settings page
- Include test webhook functionality and delivery statistics
- Support enable/disable toggle and batch operations
- Add German (de) translation
- Add Spanish (es) translation
- Add French (fr) translation
- Add Portuguese (pt-br) translation
- Add Japanese (ja) translation
- Add Chinese Simplified (zh-Hans) translation
- Add Russian (ru) translation
- Add Italian (it) translation
- Add webhook and webhook_delivery database tables
- Implement complete webhook service with CRUD operations
- Add webhook triggering and delivery system
- Implement retry mechanism with exponential backoff
- Add template formatters for Slack and n8n
- Include HMAC signature generation for security
- Add delivery logging with 100-entry limit per webhook
- Remove remaining i18n references in webhook components
- Fix DOM nesting issue in delivery history table by removing Collapsible wrapper
- Use React.Fragment with key prop to fix React warning
- Fix modal closing issue by using onSelect with preventDefault
- Replace hardcoded English strings throughout webhook UI
These test files are already in .gitignore and should not be tracked.
…issues

- Split monolithic webhook components into modular, reusable pieces
- Created standalone WebhookForm component for create/edit operations
- Created dedicated WebhookHistoryModal for delivery history
- Created separate WebhookEditModal and WebhookCreateModal
- Fixed modal closing issues by removing conditional rendering
- Created custom WebhookDialog component without overscroll-contain issue
- Improved state management and separation of concerns
- Fixed all linting and TypeScript errors

This resolves the modal closing and scrolling issues that were preventing
proper webhook management functionality.

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
- Implement comprehensive n8n webhook template with flattened payload structure
- Add Slack Block Kit template with rich formatting and interactive components
- Create template configuration forms for both platforms
- Add template preview component with visual Slack message preview
- Implement template factory pattern for extensibility
- Add validation schemas for platform-specific configurations
- Create enhanced webhook service layer for integration

fix: remove automatic webhook secret generation

- Remove backend auto-generation of webhook secrets
- Fix form to properly handle undefined secrets
- Update edit modal to preserve null/undefined secret state
- Ensure users have full control over webhook secret management

🤖 Generated with [Claude Code](https://claude.ai/code)

Co-Authored-By: Claude <[email protected]>
@A-D-E A-D-E requested a review from Siumauricio as a code owner August 14, 2025 12:06
Copy link
Contributor

@Siumauricio Siumauricio left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I see you implemented for applications and compose, but I cannot see for compose, can you check it?

Also if you can remove the unused .md files and remove the bun.lock files since we are using pnpm

Comment on lines 24 to 29
export const WebhookCreateModal = ({
applicationId,
composeId,
trigger,
onSuccess,
}: WebhookCreateModalProps) => {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Can you move the WebhookCreateModal and WebhookEditModal to handlewebhook? you can see examples where we handle the creation and the update in the same component, you can see the handle-project.tsx as an example

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

refactor: consolidate webhook modals into single handle-webhook component

…nent

- Create unified HandleWebhook component following handle-project pattern
- Replace WebhookCreateModal and WebhookEditModal with single component
- Update show-webhooks.tsx to use new HandleWebhook component
- Remove deprecated modal components
@A-D-E A-D-E force-pushed the feature/deployment-webhooks branch from 9e8bc46 to 8316222 Compare August 31, 2025 18:27
Comment on lines 6 to 120
"fixed inset-0 z-50 bg-black/80 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0",
className,
)}
{...props}
/>
));
WebhookDialogOverlay.displayName = DialogPrimitive.Overlay.displayName;

const WebhookDialogContent = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Content>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Content>
>(({ className, children, ...props }, ref) => (
<WebhookDialogPortal>
<WebhookDialogOverlay />
<DialogPrimitive.Content
ref={ref}
className={cn(
"fixed left-[50%] top-[50%] z-50 grid w-full translate-x-[-50%] translate-y-[-50%] gap-4 border bg-background p-6 shadow-lg duration-200 data-[state=open]:animate-in data-[state=closed]:animate-out data-[state=closed]:fade-out-0 data-[state=open]:fade-in-0 data-[state=closed]:zoom-out-95 data-[state=open]:zoom-in-95 data-[state=closed]:slide-out-to-left-1/2 data-[state=closed]:slide-out-to-top-[48%] data-[state=open]:slide-in-from-left-1/2 data-[state=open]:slide-in-from-top-[48%] sm:rounded-lg",
"overflow-y-auto", // Simple overflow without overscroll-contain
className,
)}
{...props}
>
{children}
<DialogPrimitive.Close className="absolute right-4 top-4 rounded-sm opacity-70 ring-offset-background transition-opacity hover:opacity-100 focus:outline-none focus:ring-2 focus:ring-ring focus:ring-offset-2 disabled:pointer-events-none data-[state=open]:bg-accent data-[state=open]:text-muted-foreground">
<X className="h-4 w-4" />
<span className="sr-only">Close</span>
</DialogPrimitive.Close>
</DialogPrimitive.Content>
</WebhookDialogPortal>
));
WebhookDialogContent.displayName = DialogPrimitive.Content.displayName;

const WebhookDialogHeader = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col space-y-1.5 text-center sm:text-left",
className,
)}
{...props}
/>
);
WebhookDialogHeader.displayName = "WebhookDialogHeader";

const WebhookDialogFooter = ({
className,
...props
}: React.HTMLAttributes<HTMLDivElement>) => (
<div
className={cn(
"flex flex-col-reverse sm:flex-row sm:justify-end sm:space-x-2",
className,
)}
{...props}
/>
);
WebhookDialogFooter.displayName = "WebhookDialogFooter";

const WebhookDialogTitle = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Title>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Title>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Title
ref={ref}
className={cn(
"text-lg font-semibold leading-none tracking-tight",
className,
)}
{...props}
/>
));
WebhookDialogTitle.displayName = DialogPrimitive.Title.displayName;

const WebhookDialogDescription = React.forwardRef<
React.ElementRef<typeof DialogPrimitive.Description>,
React.ComponentPropsWithoutRef<typeof DialogPrimitive.Description>
>(({ className, ...props }, ref) => (
<DialogPrimitive.Description
ref={ref}
className={cn("text-sm text-muted-foreground", className)}
{...props}
/>
));
WebhookDialogDescription.displayName = DialogPrimitive.Description.displayName;

export {
WebhookDialog,
WebhookDialogPortal,
WebhookDialogOverlay,
WebhookDialogClose,
WebhookDialogTrigger,
WebhookDialogContent,
WebhookDialogHeader,
WebhookDialogFooter,
WebhookDialogTitle,
WebhookDialogDescription,
};
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm wondering why we need to duplicate the base shadcn ui components for this? I don't see much differences with the components we already have

Siumauricio and others added 10 commits September 6, 2025 14:35
- Deleted 0106_mysterious_dracula.sql and 0106_nasty_silver_surfer.sql files containing webhook and webhook_delivery table definitions.
- Updated _journal.json to remove references to the deleted SQL files.
- Removed 0106_snapshot.json file as it is no longer needed.
…key constraints

- Created new SQL files for the 'webhook' and 'webhook_delivery' tables.
- Added columns and constraints to establish relationships between these tables and existing application and compose tables.
- Updated the journal to include the new migration version.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants