15 KiB
15 KiB
Phase 3 Workflow Diagram
Current Workflow (7 Nodes) → Target Workflow (11 Nodes)
┌─────────────────────────────────────────────────────────────────────────┐
│ PHASE 3: AUTONOMOUS BUILD TEST │
│ Workflow ID: j1MmXaRhDjvkRSLa │
└─────────────────────────────────────────────────────────────────────────┘
┌────────────────┐
│ [1] Gitea │ Webhook: /webhook/openhands-autonomous-build
│ Webhook │ Trigger: Push events
└────────┬───────┘
│
▼
┌────────────────┐
│ [2] Extract │ Code Node
│ Repo Info │ Extract: repo_name, owner, branch, commit_sha
└────────┬───────┘
│
▼
┌────────────────┐
│ [3] Initialize │ Code Node ★ NEW
│ Retry Count │ Initialize: $workflow.staticData.retry_count = 0
└────────┬───────┘
│
▼
┌────────────────┐
│ [4] OpenHands │ SSH Node ★ MODIFIED
│ Build │ - Enhanced task with error feedback
│ - Data preservation pattern
│ - Retry logic on loop back
▼
┌────────────────┐
│ [5] Wait │ Wait Node (10 seconds)
│ 10s │
└────────┬───────┘
│
▼
┌────────────────┐
│ [6] Check │ Code Node ★ MODIFIED
│ Build │ Add: build_success, error_details
│ Results │
└────────┬───────┘
│
▼
┌────────────────┐
│ [7] Decision │ IF Node ★ NEW
│ Build OK? │ Condition: build_success == true
└───────┬────────┘
│
├──────────────────────┐
│ │
▼ ▼
┌───────────────┐ ┌──────────────────┐
│ [8] Update │ │ [9] Format Error│ Code Node ★ NEW
│ Gitea │ │ for Retry │ Format: error_message
│ Success │ │ │
└───────┬───────┘ └────────┬─────────┘
│ │
│ ▼
│ ┌──────────────────┐
│ │ [10] Check Retry│ IF Node ★ NEW
│ │ Count │ Condition: can_retry == true
│ └───────┬────────┘
│ │
│ ┌───────┴────────┐
│ │ │
│ ▼ ▼
│ ┌────────────────┐ ┌──────────────────┐
│ │ Loop back to │ │ [11] Final │ Code Node
│ │ Node 4 │ │ Response │ ★ MODIFIED
│ └────────────────┘ │ (Failure) │
│ └────────┬─────────┘
│ │
└────────────────────────────────────┘
│
▼
┌────────────────┐
│ [12] HTTP │ Respond to Webhook
│ Response │ Status: 200/500
└────────────────┘
═══════════════════════════════════════════════════════════════════════════
DATA FLOW PATTERNS
═══════════════════════════════════════════════════════════════════════════
[2] Extract Repo Info ───┐
│ Output: {
[3] Initialize Retry ────┤ repo_name, owner, branch,
│ commit_sha, retry_count
[4] OpenHands ───────────┤ } ↓
│
[4] preserves data ──────┼──► return {
│ ...repoData, ← PRESERVE
│ code, stdout,
│ stderr, status
[6] Check Results ───────┤ }
│ ↓
│
[7] Decision ────────────┼──► build_success? → true/false
│
[8] Update Gitea ────────┤ On success → POST to Gitea API
│
[9] Format Error ────────┤ On failure → Format comprehensive error
│
[10] Retry Check ────────┤ can_retry? → true/false
│
[4] Loop back ───────────┤ If true → Back to OpenHands with feedback
│ If false → Final failure
│
[11] Final Response ─────┴──► SUCCESS or FAILED with details
═══════════════════════════════════════════════════════════════════════════
RETRY FLOW DETAIL
═══════════════════════════════════════════════════════════════════════════
Attempt 1:
[3] retry_count = 0 → [4] OpenHands (first attempt) → [6] Check → [7] FAIL
→ [9] Format Error → [10] Check: can_retry? YES (0 < 2) → Loop to [4]
Attempt 2:
[3] retry_count = 1 → [4] OpenHands (with error feedback) → [6] Check → [7] FAIL
→ [9] Format Error → [10] Check: can_retry? YES (1 < 2) → Loop to [4]
Attempt 3:
[3] retry_count = 2 → [4] OpenHands (with error feedback) → [6] Check → [7] FAIL
→ [9] Format Error → [10] Check: can_retry? NO (2 ≮ 2) → [11] Final Failure
Stop: Max retries (3) exceeded
═══════════════════════════════════════════════════════════════════════════
SUCCESS FLOW
═══════════════════════════════════════════════════════════════════════════
Attempt 1 (Success):
[3] retry_count = 0 → [4] OpenHands (first attempt) → [6] Check → [7] SUCCESS
→ [8] Update Gitea → [11] Final Response (Success)
═══════════════════════════════════════════════════════════════════════════
KEY IMPLEMENTATION NOTES
═══════════════════════════════════════════════════════════════════════════
⚠️ CRITICAL: Data Preservation Pattern
In Node 4 (SSH), ALWAYS preserve previous node data:
return { ...repoData, // ← This line is CRITICAL code: sshOutput.code, stdout: sshOutput.stdout, stderr: sshOutput.stderr };
⚠️ CRITICAL: Retry Counter Initialization
In Node 3, MUST initialize staticData:
$workflow.staticData = $workflow.staticData || {}; $workflow.staticData.retry_count = ($workflow.staticData.retry_count || 0) + 1;
⚠️ CRITICAL: Error Feedback Loop
In Node 4, include previous errors in task:
if (retryCount > 0) {
task += PREVIOUS BUILD FAILED:\n${errorDetails};
}
═══════════════════════════════════════════════════════════════════════════
NODE CONFIGURATIONS
═══════════════════════════════════════════════════════════════════════════
Node Type Matrix:
┌──────┬─────────────────┬──────────────────────────────────────────────┐
│ Node │ Type │ Key Configuration │
├──────┼─────────────────┼──────────────────────────────────────────────┤
│ 1 │ Webhook │ Path: /webhook/openhands-autonomous-build │
│ 2 │ Code │ Extract repo data │
│ 3 │ Code │ Initialize $workflow.staticData.retry_count │
│ 4 │ SSH │ Host: localhost, Timeout: 300000ms │
│ 5 │ Wait │ 10 seconds │
│ 6 │ Code │ Evaluate build_success │
│ 7 │ IF │ Condition: build_success == true │
│ 8 │ HTTP │ POST Gitea API │
│ 9 │ Code │ Format error with feedback │
│ 10 │ IF │ Condition: can_retry == true │
│ 11 │ Code │ Final SUCCESS/FAILED response │
│ 12 │ Respond to Web │ Return HTTP 200/500 │
└──────┴─────────────────┴──────────────────────────────────────────────┘
═══════════════════════════════════════════════════════════════════════════
GITEA STATUS UPDATES
═══════════════════════════════════════════════════════════════════════════
Success Path (Node 8):
POST https://git.oky.sh/api/v1/repos/{owner}/{repo}/statuses/{sha}
Body: {
"state": "success",
"description": "✅ Build passed after {retry_count} attempt(s)",
"context": "openhands/autonomous-build"
}
Failure Path (Node 11):
POST https://git.oky.sh/api/v1/repos/{owner}/{repo}/statuses/{sha}
Body: {
"state": "failure",
"description": "❌ Build failed after 3 attempts",
"context": "openhands/autonomous-build"
}
═══════════════════════════════════════════════════════════════════════════
EXECUTION TIMELINE
═══════════════════════════════════════════════════════════════════════════
Success (No Retry):
T+0s → Webhook received
T+5s → OpenHands starts build
T+15s → Build complete, result checked
T+16s → Gitea status updated
T+17s → Response sent
Success (After 2 Retries):
T+0s → Webhook received
T+5s → 1st OpenHands attempt
T+15s → 1st failure, formatted
T+20s → 2nd OpenHands attempt (with feedback)
T+30s → 2nd failure, formatted
T+35s → 3rd OpenHands attempt (with feedback)
T+45s → 3rd success
T+46s → Gitea status updated
T+47s → Response sent
Failure (Max Retries):
T+0s → Webhook received
T+5s → 1st OpenHands attempt
T+15s → 1st failure
T+20s → 2nd OpenHands attempt
T+30s → 2nd failure
T+35s → 3rd OpenHands attempt
T+45s → 3rd failure
T+46s → Gitea status updated (failure)
T+47s → Response sent (max retries exceeded)
═══════════════════════════════════════════════════════════════════════════
FILE REFERENCES
═══════════════════════════════════════════════════════════════════════════
📄 Documentation:
- phase3.md (Original plan)
- phase3-implementation-plan.md (Detailed guide)
- phase3-code-snippets.md (Ready-to-copy code)
- phase3-quickstart.md (Quick start)
🔧 Configuration:
- n8n API Key: /home/bam/.n8n_api_key
- SSH Key: /home/bam/.ssh/n8n_key
- OpenHands: /home/bam/openhands-sdk-wrapper-sh.sh
🧪 Testing:
- Test repo: autonomous-build-test
- Webhook: /webhook/openhands-autonomous-build
═══════════════════════════════════════════════════════════════════════════