Skip to content

Commit 8b1b7ea

Browse files
committed
Add Github webhook setup
1 parent 7b5fb1e commit 8b1b7ea

File tree

1 file changed

+350
-0
lines changed

1 file changed

+350
-0
lines changed

GITHUB_WEBHOOK_SETUP.md

Lines changed: 350 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,350 @@
1+
# GitHub Webhook Integration Setup and Testing Guide
2+
3+
## Overview
4+
5+
The Topcoder Review API includes a secure GitHub webhook integration that receives webhook events from GitHub repositories, validates them using HMAC-SHA256 signature verification, and stores them in the database for audit and future processing.
6+
7+
## Table of Contents
8+
9+
1. [Quick Start](#quick-start)
10+
2. [Environment Setup](#environment-setup)
11+
3. [GitHub Repository Configuration](#github-repository-configuration)
12+
4. [Local Development Setup](#local-development-setup)
13+
5. [Testing the Integration](#testing-the-integration)
14+
6. [API Endpoint Reference](#api-endpoint-reference)
15+
7. [Database Schema](#database-schema)
16+
8. [Security Considerations](#security-considerations)
17+
9. [Troubleshooting](#troubleshooting)
18+
10. [Monitoring and Maintenance](#monitoring-and-maintenance)
19+
20+
## Quick Start
21+
22+
For immediate setup, follow these steps:
23+
24+
1. Generate a secure webhook secret
25+
2. Configure environment variables
26+
3. Set up GitHub webhook in repository settings
27+
4. Test with a sample event
28+
29+
## Environment Setup
30+
31+
### Required Environment Variables
32+
33+
Add the following environment variable to your application configuration:
34+
35+
```bash
36+
# .env file
37+
GITHUB_WEBHOOK_SECRET=your_generated_secret_here
38+
```
39+
40+
### Generate Webhook Secret
41+
42+
**Using OpenSSL:**
43+
```bash
44+
openssl rand -hex 32
45+
```
46+
47+
**Example Output:**
48+
```
49+
a1b2c3d4e5f6789012345678901234567890abcdef1234567890abcdef123456
50+
```
51+
52+
⚠️ **Important:** Store this secret securely and use the same value in both your application environment and GitHub webhook configuration.
53+
54+
### Database Setup
55+
56+
The webhook integration requires the `gitWebhookLog` table. If not already created, run the database migration:
57+
58+
```bash
59+
npx prisma migrate dev
60+
```
61+
62+
## GitHub Repository Configuration
63+
64+
### Step 1: Access Repository Settings
65+
66+
1. Navigate to your GitHub repository
67+
2. Click on the **Settings** tab (requires admin permissions)
68+
3. In the left sidebar, click **Webhooks**
69+
4. Click **Add webhook**
70+
71+
### Step 2: Configure Webhook Settings
72+
73+
#### Payload URL
74+
75+
**Production/Staging Environment:**
76+
```
77+
https://your-api-domain.com/v6/review/webhooks/git
78+
```
79+
80+
**Development Environment:**
81+
```
82+
https://your-dev-domain.com/webhooks/git
83+
```
84+
85+
Note: The `/v6/review` prefix is only added in production when `NODE_ENV=production`.
86+
87+
#### Content Type
88+
- Select `application/json`
89+
90+
#### Secret
91+
- Enter the webhook secret you generated earlier
92+
- This must exactly match your `GITHUB_WEBHOOK_SECRET` environment variable
93+
94+
#### SSL Verification
95+
- Keep **Enable SSL verification** checked (recommended for production)
96+
- For development with proper HTTPS setup, this should remain enabled
97+
98+
### Step 3: Select Events
99+
100+
Choose one of the following options:
101+
102+
**Option A: Send Everything (Recommended for Testing)**
103+
- Select "Send me everything" to receive all GitHub event types
104+
105+
**Option B: Select Individual Events**
106+
Common events for development workflows:
107+
- **Pushes** - Code pushes to repository
108+
- **Pull requests** - PR creation, updates, merges
109+
- **Issues** - Issue creation, updates, comments
110+
- **Issue comments** - Comments on issues and PRs
111+
- **Releases** - Release creation and updates
112+
- **Create** - Branch or tag creation
113+
- **Delete** - Branch or tag deletion
114+
115+
### Step 4: Activate and Create
116+
117+
1. Ensure **Active** checkbox is checked
118+
2. Click **Add webhook**
119+
3. GitHub will automatically send a `ping` event to test the webhook
120+
121+
## Local Development Setup
122+
123+
Since GitHub webhooks require a publicly accessible URL, local development requires exposing your local server to the internet.
124+
125+
**Install ngrok:**
126+
```bash
127+
npm install -g ngrok
128+
```
129+
130+
**Setup process:**
131+
```bash
132+
# 1. Start your local API server
133+
pnpm run start:dev
134+
135+
# 2. In another terminal, expose your local server
136+
ngrok http 3000
137+
138+
# 3. Copy the HTTPS URL from ngrok output
139+
# Example: https://abc123.ngrok.io
140+
141+
# 4. Use this URL in GitHub webhook settings
142+
# https://abc123.ngrok.io/webhooks/git
143+
```
144+
## Testing the Integration
145+
146+
### Manual Testing
147+
148+
#### 1. Verify Initial Setup
149+
150+
After creating the webhook, GitHub automatically sends a `ping` event:
151+
152+
1. Go to your repository's webhook settings
153+
2. Click on your webhook
154+
3. Check **Recent Deliveries** section
155+
4. Look for the `ping` event with status 200 OK
156+
157+
#### 2. Trigger Test Events
158+
159+
**Create a Push Event:**
160+
```bash
161+
# Make a small change
162+
echo "webhook test" >> test-webhook.txt
163+
git add test-webhook.txt
164+
git commit -m "Test webhook integration"
165+
git push origin main
166+
```
167+
168+
**Create an Issue:**
169+
1. Go to your repository on GitHub
170+
2. Click **Issues** tab
171+
3. Click **New issue**
172+
4. Create a test issue
173+
174+
**Create a Pull Request:**
175+
1. Create a new branch: `git checkout -b test-webhook`
176+
2. Make changes and commit
177+
3. Push branch: `git push origin test-webhook`
178+
4. Open pull request on GitHub
179+
180+
### Testing with curl
181+
182+
You can test the webhook endpoint directly using curl with proper signature generation:
183+
184+
```bash
185+
#!/bin/bash
186+
187+
# Configuration
188+
WEBHOOK_URL="http://localhost:3000/webhooks/git" # Adjust for your environment
189+
WEBHOOK_SECRET="your_webhook_secret_here"
190+
PAYLOAD='{"test": "data", "repository": {"name": "test-repo"}}'
191+
DELIVERY_ID="test-delivery-$(date +%s)"
192+
EVENT_TYPE="push"
193+
194+
# Generate signature
195+
SIGNATURE="sha256=$(echo -n "$PAYLOAD" | openssl dgst -sha256 -hmac "$WEBHOOK_SECRET" | sed 's/^.* //')"
196+
197+
# Send test webhook
198+
curl -X POST "$WEBHOOK_URL" \
199+
-H "Content-Type: application/json" \
200+
-H "X-GitHub-Event: $EVENT_TYPE" \
201+
-H "X-GitHub-Delivery: $DELIVERY_ID" \
202+
-H "X-Hub-Signature-256: $SIGNATURE" \
203+
-d "$PAYLOAD"
204+
```
205+
206+
## API Endpoint Reference
207+
208+
### Webhook Endpoint
209+
210+
**URL:** `POST /webhooks/git` (development) or `POST /v6/review/webhooks/git` (production)
211+
212+
**Required Headers:**
213+
- `Content-Type: application/json`
214+
- `X-GitHub-Event: {event_type}` - GitHub event type (push, pull_request, etc.)
215+
- `X-GitHub-Delivery: {delivery_id}` - Unique delivery identifier from GitHub
216+
- `X-Hub-Signature-256: sha256={signature}` - HMAC-SHA256 signature for verification
217+
218+
**Request Body:**
219+
- GitHub webhook payload (varies by event type)
220+
221+
**Response Codes:**
222+
- `200 OK` - Webhook processed successfully
223+
- `400 Bad Request` - Missing required headers or invalid payload
224+
- `403 Forbidden` - Invalid signature verification
225+
- `500 Internal Server Error` - Processing error or configuration issue
226+
227+
**Success Response:**
228+
```json
229+
{
230+
"success": true,
231+
"message": "Webhook processed successfully"
232+
}
233+
```
234+
235+
**Error Response:**
236+
```json
237+
{
238+
"statusCode": 403,
239+
"message": "Invalid signature",
240+
"error": "Forbidden",
241+
"timestamp": "2024-01-01T00:00:00.000Z",
242+
"path": "/webhooks/git"
243+
}
244+
```
245+
246+
## Database Schema
247+
248+
Webhook events are stored in the `gitWebhookLog` table:
249+
250+
```sql
251+
CREATE TABLE "gitWebhookLog" (
252+
"id" VARCHAR(14) NOT NULL DEFAULT nanoid(),
253+
"eventId" TEXT NOT NULL,
254+
"event" TEXT NOT NULL,
255+
"eventPayload" JSONB NOT NULL,
256+
"createdAt" TIMESTAMP(3) NOT NULL DEFAULT CURRENT_TIMESTAMP,
257+
258+
CONSTRAINT "gitWebhookLog_pkey" PRIMARY KEY ("id")
259+
);
260+
261+
-- Indexes for efficient querying
262+
CREATE INDEX "gitWebhookLog_eventId_idx" ON "gitWebhookLog"("eventId");
263+
CREATE INDEX "gitWebhookLog_event_idx" ON "gitWebhookLog"("event");
264+
CREATE INDEX "gitWebhookLog_createdAt_idx" ON "gitWebhookLog"("createdAt");
265+
```
266+
267+
### Query Examples
268+
269+
**View recent webhook events:**
270+
```sql
271+
SELECT
272+
id,
273+
"eventId",
274+
event,
275+
"createdAt"
276+
FROM "gitWebhookLog"
277+
ORDER BY "createdAt" DESC
278+
LIMIT 10;
279+
```
280+
281+
**Filter by event type:**
282+
```sql
283+
SELECT * FROM "gitWebhookLog"
284+
WHERE event = 'push'
285+
ORDER BY "createdAt" DESC;
286+
```
287+
288+
**View specific webhook payload:**
289+
```sql
290+
SELECT
291+
event,
292+
"eventPayload"
293+
FROM "gitWebhookLog"
294+
WHERE "eventId" = 'your-delivery-id';
295+
```
296+
297+
## Security Considerations
298+
299+
### Signature Verification
300+
301+
The webhook implementation uses GitHub's recommended security practices:
302+
303+
1. **HMAC-SHA256 Signature:** All incoming webhooks are verified using HMAC-SHA256
304+
2. **Timing-Safe Comparison:** Uses `crypto.timingSafeEqual()` to prevent timing attacks
305+
3. **Secret Protection:** Webhook secrets are stored as environment variables
306+
4. **Header Validation:** Validates all required GitHub headers
307+
308+
### Best Practices
309+
310+
1. **Use HTTPS:** Always use HTTPS URLs for production webhooks
311+
2. **Rotate Secrets:** Periodically rotate webhook secrets
312+
3. **Monitor Access:** Regularly review webhook delivery logs
313+
4. **Limit Events:** Only subscribe to events you actually need
314+
5. **Access Control:** Restrict webhook configuration to repository administrators
315+
316+
### Environment Security
317+
318+
- Store `GITHUB_WEBHOOK_SECRET` securely using your deployment platform's secret management
319+
- Never commit secrets to version control
320+
- Use different secrets for different environments
321+
- Implement proper secret rotation procedures
322+
323+
### Log Analysis
324+
325+
Key log messages to monitor:
326+
327+
```
328+
# Successful webhook processing
329+
[WebhookController] Successfully processed GitHub webhook
330+
331+
# Signature validation failures
332+
[GitHubSignatureGuard] Invalid webhook signature for delivery
333+
334+
# Configuration errors
335+
[GitHubSignatureGuard] GITHUB_WEBHOOK_SECRET environment variable is not configured
336+
```
337+
338+
Example
339+
340+
```
341+
[2025-08-02T01:06:48.312Z] [LOG] [Bootstrap] Server started on port 3000
342+
[2025-08-02T01:07:15.700Z] [LOG] [HttpRequest] {"type":"request","method":"POST","url":"/webhooks/git","ip":"::1","userAgent":"GitHub-Hookshot/4f8bd7a"}
343+
[2025-08-02T01:07:15.739Z] [LOG] [GitHubSignatureGuard] Valid webhook signature verified for delivery 0722d0bc-6f3d-11f0-8a2d-6cc18966c098, event push
344+
[2025-08-02T01:07:15.740Z] [LOG] [WebhookController] {"message":"Received GitHub webhook","delivery":"0722d0bc-6f3d-11f0-8a2d-6cc18966c098","event":"push","timestamp":"2025-08-02T01:07:15.740Z"}
345+
[2025-08-02T01:07:15.740Z] [LOG] [WebhookService] {"message":"Processing GitHub webhook event","eventId":"0722d0bc-6f3d-11f0-8a2d-6cc18966c098","event":"push","timestamp":"2025-08-02T01:07:15.740Z"}
346+
[2025-08-02T01:07:15.804Z] [LOG] [WebhookService] {"message":"Successfully stored webhook event","eventId":"0722d0bc-6f3d-11f0-8a2d-6cc18966c098","event":"push","storedId":"9aHvEgDYPCYYnU","createdAt":"2025-08-02T01:07:15.747Z"}
347+
[2025-08-02T01:07:15.804Z] [LOG] [WebhookService] {"message":"Event-specific processing placeholder","event":"push","payloadSize":7979}
348+
[2025-08-02T01:07:15.804Z] [LOG] [WebhookController] {"message":"Successfully processed GitHub webhook","delivery":"0722d0bc-6f3d-11f0-8a2d-6cc18966c098","event":"push","success":true}
349+
[2025-08-02T01:07:15.804Z] [LOG] [HttpRequest] {"type":"response","statusCode":200,"method":"POST","url":"/webhooks/git","responseTime":"104ms"}
350+
```

0 commit comments

Comments
 (0)