447 lines
10 KiB
Markdown
447 lines
10 KiB
Markdown
# Gitea → n8n → OpenHands Webhook Integration Guide
|
|
|
|
**Workflow:** Automatic CI/CD on every git push
|
|
**File:** `/tmp/openhands-gitea-webhook-workflow.json`
|
|
|
|
---
|
|
|
|
## 📋 Overview
|
|
|
|
This workflow automatically triggers OpenHands builds when you push to Gitea:
|
|
|
|
```
|
|
Git Push → Gitea Webhook → n8n → OpenHands API → Build & Test → Results
|
|
```
|
|
|
|
---
|
|
|
|
## 🚀 Step-by-Step Setup
|
|
|
|
### Step 1: Import Webhook Workflow to n8n (5 min)
|
|
|
|
1. Open **https://n8n.oky.sh**
|
|
2. Log in with your credentials
|
|
3. Click **"Workflows"** → **"Add Workflow"**
|
|
4. Click **"⋮" menu** → **"Import from File"**
|
|
5. Upload `/tmp/openhands-gitea-webhook-workflow.json`
|
|
6. Click **"Save"**
|
|
7. Give it a name: **"Gitea CI/CD with OpenHands"**
|
|
|
|
### Step 2: Activate the Workflow
|
|
|
|
1. In the workflow editor, find the toggle switch at the top
|
|
2. Click it to change from **"Inactive"** to **"Active"**
|
|
3. The workflow is now listening for webhooks!
|
|
|
|
### Step 3: Get the Webhook URL
|
|
|
|
1. Click on the **"Gitea Webhook"** node (first node)
|
|
2. Look for **"Webhook URLs"** section
|
|
3. Copy the **Production URL**, it should look like:
|
|
```
|
|
https://n8n.oky.sh/webhook/gitea-push
|
|
```
|
|
4. Keep this URL handy for Gitea configuration
|
|
|
|
---
|
|
|
|
## 🔧 Gitea Repository Setup
|
|
|
|
### Step 4: Create Test Repository in Gitea (5 min)
|
|
|
|
1. Open **https://git.oky.sh**
|
|
2. Log in with your Gitea credentials
|
|
3. Click **"+"** (top right) → **"New Repository"**
|
|
4. Fill in:
|
|
- **Repository Name:** `openhands-test`
|
|
- **Description:** "Test repo for OpenHands CI/CD"
|
|
- **Visibility:** Private or Public (your choice)
|
|
- **Initialize Repository:** ✓ Check this
|
|
- **Add .gitignore:** Node
|
|
- **Add README:** ✓ Check this
|
|
5. Click **"Create Repository"**
|
|
|
|
### Step 5: Configure Gitea Webhook (5 min)
|
|
|
|
1. In your repository, click **"Settings"** (gear icon, top right)
|
|
2. Click **"Webhooks"** in the left sidebar
|
|
3. Click **"Add Webhook"** → **"Gitea"**
|
|
4. Configure:
|
|
|
|
**Target URL:**
|
|
```
|
|
https://n8n.oky.sh/webhook/gitea-push
|
|
```
|
|
|
|
**HTTP Method:**
|
|
```
|
|
POST
|
|
```
|
|
|
|
**POST Content Type:**
|
|
```
|
|
application/json
|
|
```
|
|
|
|
**Secret:** (Optional, leave empty for now)
|
|
|
|
**Trigger On:**
|
|
- ✓ **Push Events**
|
|
- ✗ Create Events
|
|
- ✗ Delete Events
|
|
- ✗ Fork Events
|
|
- etc. (uncheck all others)
|
|
|
|
**Branch filter:** (leave empty to trigger on all branches)
|
|
|
|
**Active:** ✓ **Check this!**
|
|
|
|
5. Click **"Add Webhook"**
|
|
|
|
### Step 6: Test the Webhook (2 min)
|
|
|
|
1. On the webhook page, scroll down to **"Recent Deliveries"**
|
|
2. Click **"Test Delivery"** button
|
|
3. You should see a new delivery appear
|
|
4. Click on it to see the response
|
|
5. **Expected:** HTTP 200 OK
|
|
|
|
If you get an error, check:
|
|
- n8n workflow is **Active**
|
|
- Webhook URL is correct
|
|
- n8n is accessible at https://n8n.oky.sh
|
|
|
|
---
|
|
|
|
## 🧪 Testing End-to-End Automation
|
|
|
|
### Step 7: Clone Repository Locally
|
|
|
|
```bash
|
|
# Clone the test repository
|
|
git clone https://git.oky.sh/[your-username]/openhands-test.git
|
|
cd openhands-test
|
|
|
|
# Check current status
|
|
git status
|
|
```
|
|
|
|
### Step 8: Create a Simple Node.js Project
|
|
|
|
```bash
|
|
# Initialize package.json
|
|
cat > package.json << 'EOF'
|
|
{
|
|
"name": "openhands-test",
|
|
"version": "1.0.0",
|
|
"description": "Test project for OpenHands CI/CD",
|
|
"main": "index.js",
|
|
"scripts": {
|
|
"test": "node test.js",
|
|
"build": "echo 'Build completed successfully'"
|
|
},
|
|
"author": "",
|
|
"license": "MIT"
|
|
}
|
|
EOF
|
|
|
|
# Create main file
|
|
cat > index.js << 'EOF'
|
|
function add(a, b) {
|
|
return a + b;
|
|
}
|
|
|
|
function multiply(a, b) {
|
|
return a * b;
|
|
}
|
|
|
|
module.exports = { add, multiply };
|
|
EOF
|
|
|
|
# Create test file
|
|
cat > test.js << 'EOF'
|
|
const { add, multiply } = require('./index.js');
|
|
|
|
console.log('Running tests...');
|
|
|
|
// Test add function
|
|
if (add(2, 3) === 5) {
|
|
console.log('✓ add(2, 3) = 5 PASSED');
|
|
} else {
|
|
console.log('✗ add test FAILED');
|
|
process.exit(1);
|
|
}
|
|
|
|
// Test multiply function
|
|
if (multiply(4, 5) === 20) {
|
|
console.log('✓ multiply(4, 5) = 20 PASSED');
|
|
} else {
|
|
console.log('✗ multiply test FAILED');
|
|
process.exit(1);
|
|
}
|
|
|
|
console.log('\nAll tests passed! ✅');
|
|
EOF
|
|
|
|
# Add all files
|
|
git add .
|
|
git commit -m "Add Node.js project with tests"
|
|
git push origin main
|
|
```
|
|
|
|
### Step 9: Monitor the Workflow
|
|
|
|
**In n8n:**
|
|
1. Go to **"Executions"** (left sidebar)
|
|
2. You should see a new execution appear
|
|
3. Click on it to see the progress
|
|
4. Watch as each node executes:
|
|
- ✅ Webhook received
|
|
- ✅ Repo info extracted
|
|
- ✅ OpenHands session created
|
|
- ✅ Build status polled
|
|
- ✅ Events retrieved
|
|
- ✅ Results analyzed
|
|
|
|
**Expected execution time:** 2-3 minutes (first time), 30-60 seconds (subsequent)
|
|
|
|
**In Gitea:**
|
|
1. Go to your repository → **Settings** → **Webhooks**
|
|
2. Click on your webhook
|
|
3. Scroll to **"Recent Deliveries"**
|
|
4. You should see the delivery with HTTP 200 response
|
|
|
|
### Step 10: Verify Build Results
|
|
|
|
**Check n8n Execution:**
|
|
1. In n8n, click on the execution
|
|
2. Click on **"Analyze Build Results"** node
|
|
3. Check the output - you should see:
|
|
```json
|
|
{
|
|
"repo": "username/openhands-test",
|
|
"branch": "main",
|
|
"commit": "abc123...",
|
|
"build_status": "SUCCESS" or "FAILED",
|
|
"total_events": 10+,
|
|
"has_errors": false,
|
|
"has_success": true
|
|
}
|
|
```
|
|
|
|
**Check OpenHands Logs:**
|
|
```bash
|
|
# List conversations
|
|
curl http://localhost:3000/api/conversations | python3 -m json.tool
|
|
|
|
# Get specific conversation events (use conversation_id from n8n)
|
|
curl "http://localhost:3000/api/conversations/[conversation-id]/events" | python3 -m json.tool
|
|
```
|
|
|
|
**Check Runtime Container:**
|
|
```bash
|
|
# Find the runtime container
|
|
docker ps | grep openhands-runtime
|
|
|
|
# Check if tests ran successfully
|
|
docker exec [container-name] cat /workspace/test.js
|
|
|
|
# Check installed packages
|
|
docker exec [container-name] ls -la /workspace/node_modules
|
|
```
|
|
|
|
---
|
|
|
|
## 🎯 Workflow Logic Explained
|
|
|
|
### Node 1: Gitea Webhook
|
|
- **Trigger:** Receives POST requests from Gitea
|
|
- **Path:** `/webhook/gitea-push`
|
|
- **Payload:** Complete webhook payload with repo, commit, pusher info
|
|
|
|
### Node 2: Extract Repo Info
|
|
- Parses Gitea webhook payload
|
|
- Extracts: repository name, clone URL, branch, commit SHA, message
|
|
- Builds task description for OpenHands
|
|
|
|
### Node 3: Create OpenHands Session
|
|
- **POST** `/api/conversations`
|
|
- Passes repository URL and branch
|
|
- Includes custom build task
|
|
|
|
### Node 4-8: Status Polling Loop
|
|
- Waits 10s initially
|
|
- Checks status every 15s
|
|
- Max 20 retries (5 minutes timeout)
|
|
- Loops until status is RUNNING, STOPPED, or AWAITING_USER_INPUT
|
|
|
|
### Node 9: Get Build Events
|
|
- Retrieves all events from the conversation
|
|
- Contains logs, actions, observations
|
|
|
|
### Node 10: Analyze Build Results
|
|
- Scans events for error/success indicators
|
|
- Determines final build status
|
|
- Counts total events
|
|
|
|
### Node 11-12: Format & Respond
|
|
- Formats response JSON
|
|
- Sends back to Gitea webhook
|
|
|
|
---
|
|
|
|
## 📊 Customizing the Workflow
|
|
|
|
### Change Build Commands
|
|
|
|
Edit the **"Extract Repo Info"** node, modify the `task` variable:
|
|
|
|
```javascript
|
|
const task = `Build and test project ${repoFullName}. ` +
|
|
`Run: npm install && npm run lint && npm test && npm build`;
|
|
```
|
|
|
|
### Add Python Support
|
|
|
|
```javascript
|
|
const task = `Clone repository, install dependencies with pip, ` +
|
|
`and run: pip install -r requirements.txt && pytest`;
|
|
```
|
|
|
|
### Add Docker Build
|
|
|
|
```javascript
|
|
const task = `Build Docker image: docker build -t ${repoName}:${commitSha.substring(0,8)} . ` +
|
|
`Run tests in container: docker run ${repoName} npm test`;
|
|
```
|
|
|
|
### Filter by Branch
|
|
|
|
Add a filter after webhook trigger:
|
|
|
|
```javascript
|
|
// In Extract Repo Info node, add at the top:
|
|
const branch = payload.ref?.replace('refs/heads/', '') || '';
|
|
|
|
if (branch !== 'main' && branch !== 'develop') {
|
|
throw new Error('Skipping build for branch: ' + branch);
|
|
}
|
|
```
|
|
|
|
### Add Notifications
|
|
|
|
After "Analyze Build Results", add:
|
|
- **Slack notification node**
|
|
- **Email node**
|
|
- **Discord webhook**
|
|
|
|
Example for Slack:
|
|
```json
|
|
{
|
|
"channel": "#ci-cd",
|
|
"text": "Build {{$json.build_status}} for {{$json.repo}} on {{$json.branch}}"
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## 🐛 Troubleshooting
|
|
|
|
### Webhook Not Triggering
|
|
|
|
**Problem:** No execution appears in n8n after git push
|
|
|
|
**Solutions:**
|
|
1. Check workflow is **Active** (toggle at top of workflow)
|
|
2. Verify webhook URL in Gitea matches n8n webhook path
|
|
3. Check Gitea "Recent Deliveries" for errors
|
|
4. Test webhook manually in Gitea UI
|
|
|
|
**Debug:**
|
|
```bash
|
|
# Check n8n logs
|
|
docker logs n8n | grep webhook
|
|
|
|
# Test webhook manually
|
|
curl -X POST https://n8n.oky.sh/webhook/gitea-push \
|
|
-H "Content-Type: application/json" \
|
|
-d '{"test": "data"}'
|
|
```
|
|
|
|
### Build Timeout
|
|
|
|
**Problem:** Workflow hits max retries (5 minutes)
|
|
|
|
**Solutions:**
|
|
1. Increase max retries in "Retry Counter" node (change `maxRetries` from 20 to 40)
|
|
2. Increase wait time from 15s to 30s
|
|
3. Check OpenHands logs for errors:
|
|
```bash
|
|
sudo journalctl -u openhands.service -f
|
|
```
|
|
|
|
### Build Always Shows "UNKNOWN"
|
|
|
|
**Problem:** Build status is never SUCCESS or FAILED
|
|
|
|
**Solutions:**
|
|
1. Check event messages don't contain success/error keywords
|
|
2. Modify "Analyze Build Results" node to look for different patterns:
|
|
```javascript
|
|
const hasSuccess = events.some(e =>
|
|
e.message?.includes('Tests passed') ||
|
|
e.message?.includes('Build complete')
|
|
);
|
|
```
|
|
|
|
### OpenHands Connection Failed
|
|
|
|
**Problem:** "Cannot reach 172.18.0.1:3000"
|
|
|
|
**Solutions:**
|
|
1. Verify OpenHands is running:
|
|
```bash
|
|
sudo systemctl status openhands.service
|
|
curl http://localhost:3000/api/options/agents
|
|
```
|
|
|
|
2. Test from n8n container:
|
|
```bash
|
|
docker exec n8n wget -O- http://172.18.0.1:3000/api/options/agents
|
|
```
|
|
|
|
3. Restart n8n:
|
|
```bash
|
|
cd /home/bam/services/services-stack
|
|
docker compose restart n8n
|
|
```
|
|
|
|
---
|
|
|
|
## 🎉 Success Criteria
|
|
|
|
- ✅ Git push triggers n8n workflow automatically
|
|
- ✅ n8n creates OpenHands conversation
|
|
- ✅ OpenHands clones repository
|
|
- ✅ OpenHands runs build commands (npm install, test, build)
|
|
- ✅ Build results are analyzed
|
|
- ✅ Webhook response is sent back to Gitea
|
|
- ✅ Execution completes within 5 minutes
|
|
|
|
---
|
|
|
|
## 🔗 Resources
|
|
|
|
- **Webhook Workflow:** `/tmp/openhands-gitea-webhook-workflow.json`
|
|
- **Test Workflow:** `/tmp/openhands-workflow.json`
|
|
- **API Reference:** `/home/bam/openhands-api-reference.md`
|
|
- **Gitea:** https://git.oky.sh
|
|
- **n8n:** https://n8n.oky.sh
|
|
- **OpenHands API:** http://localhost:3000/docs
|
|
|
|
---
|
|
|
|
**Ready to go live!** 🚀
|
|
|
|
Push your code and watch the magic happen!
|