mvp-factory-openhands/phase3-code-snippets.md

9.0 KiB

Phase 3: Ready-to-Copy Code Snippets

📋 Node 3: Initialize Retry Counter

// Initialize retry counter in workflow staticData
$workflow.staticData = $workflow.staticData || {};

// Initialize or increment retry count
$workflow.staticData.retry_count = ($workflow.staticData.retry_count || 0);

// Preserve repo data from previous node
const repoData = $node["Extract Repo Info"].json;

return {
  ...repoData,
  retry_count: 0,
  status: 'INITIALIZED',
  attempt: 1
};

📋 Node 4: Execute OpenHands Build (Enhanced)

Part A: Command (in SSH node)

// Enhanced task with retry feedback
const repoData = $node["Extract Repo Info"].json;
const retryCount = $node["Initialize Retry Counter"].json.retry_count;
const buildDir = `/workspace/${repoData.repo_name}`;

// Base task
let task = `Build and test the project at ${buildDir}.

Execute the following steps:
1. cd ${buildDir}
2. If package.json exists: npm install
3. If build script exists: npm run build
4. Report build status (success/failure)
5. Capture and report any errors

Repository: ${repoData.repo_name}
Branch: ${repoData.branch}
Commit: ${repoData.commit_sha.substring(0, 8)}
`;

// Add feedback if this is a retry
if (retryCount > 0) {
  const previousOutput = $node["Check Build Results"].json;
  const errorDetails = previousOutput?.error_message || 'Unknown error';

  task += `

PREVIOUS BUILD FAILED (Attempt ${retryCount}):
Error Details:
${errorDetails}

Please analyze the previous errors and fix them. Be thorough and ensure all issues are resolved before attempting the build again.

This is retry attempt #${retryCount + 1}. Please be extremely careful and fix ALL problems.`;
}

// Execute via SDK wrapper
return `sh /home/bam/openhands-sdk-wrapper-sh.sh "${task.replace(/"/g, '\\"')}"`;

Part B: Data Preservation (below the command in same SSH node)

const sshOutput = $json;
const repoData = $node["Extract Repo Info"].json;
const retryCount = $node["Initialize Retry Counter"].json.retry_count;

return {
  ...repoData,              // Preserve repository data
  code: sshOutput.code,
  stdout: sshOutput.stdout,
  stderr: sshOutput.stderr,
  status: sshOutput.code === 0 ? 'SUCCESS' : 'FAILED',
  retry_count: retryCount,
  attempt: retryCount + 1
};

📋 Node 6: Evaluate Build Results

// Get OpenHands output
const openhandsOutput = $json;

// Determine success/failure
const buildSuccess = openhandsOutput.code === 0;

// Collect errors if build failed
let errorDetails = '';
if (!buildSuccess) {
  // Prefer stderr, fallback to stdout
  errorDetails = openhandsOutput.stderr || openhandsOutput.stdout || 'Build failed with no error output';
}

// Return structured results
return {
  ...openhandsOutput,  // Preserve all data
  build_success: buildSuccess,
  error_details: errorDetails,
  timestamp: new Date().toISOString()
};

📋 Node 8: Update Gitea Success (HTTP Node)

Configuration Tab:

Method: POST URL:

https://git.oky.sh/api/v1/repos/{{ $node["Extract Repo Info"].json.owner }}/{{ $node["Extract Repo Info"].json.repo_name }}/statuses/{{ $node["Extract Repo Info"].json.commit_sha }}

Headers:

  • Header 1:
    • Name: X-Gitea-Token
    • Value: {YOUR_GITEA_API_TOKEN}
  • Header 2:
    • Name: Content-Type
    • Value: application/json

Body:

{
  "state": "success",
  "description": "✅ Build passed after {{ $node["Initialize Retry Counter"].json.retry_count }} attempt(s)",
  "context": "openhands/autonomous-build",
  "target_url": "https://n8n.oky.sh"
}

Response Handling (in Code mode):

// Preserve data and add Gitea response
const giteaResponse = $json;
const previousData = $node["Extract Repo Info"].json;

return {
  ...previousData,
  gitea_status: 'success',
  gitea_response: giteaResponse,
  final_status: 'SUCCESS',
  build_success: true
};

📋 Node 9: Format Error for Retry

// Get build results and repo data
const buildResults = $node["Check Build Results"].json;
const repoData = $node["Extract Repo Info"].json;
const retryCount = $node["Initialize Retry Counter"].json.retry_count;

// Format comprehensive error message
const errorMsg = `Build failed with the following errors:

REPOSITORY: ${repoData.repo_name}
BRANCH: ${repoData.branch}
COMMIT: ${repoData.commit_sha.substring(0, 8)}
ATTEMPT: ${retryCount + 1}/3

ERROR DETAILS:
${buildResults.error_details}

BUILD OUTPUT (stderr):
${buildResults.stderr || 'No stderr output'}

BUILD OUTPUT (stdout):
${buildResults.stdout || 'No stdout output'}

NEXT STEPS:
Please analyze these errors and fix all issues to ensure a successful build.
Focus on:
1. Dependency issues (npm install errors)
2. Build script failures
3. Code syntax errors
4. Configuration problems

After fixing, the project should build successfully with: npm install && npm run build

This is attempt ${retryCount + 1} of 3. You have ${2 - retryCount} retry(s) remaining.`;

return {
  ...repoData,
  ...buildResults,
  status: 'FAILED',
  error_message: errorMsg,
  retry_count: retryCount,
  can_retry: retryCount < 2,  // < 3 total attempts
  formatted_error: errorMsg
};

📋 Node 11: Final Response

For Success Path:

// Format success response
const repoData = $node["Extract Repo Info"].json;
const retryCount = $node["Initialize Retry Counter"].json.retry_count;

const successResponse = {
  status: 'SUCCESS',
  repo: repoData.repo_name,
  branch: repoData.branch,
  commit: repoData.commit_sha.substring(0, 8),
  attempts: retryCount + 1,
  message: 'Build completed successfully ✅',
  timestamp: new Date().toISOString(),
  gitea_status: 'success'
};

return successResponse;

For Failure Path:

// Format failure response
const repoData = $node["Extract Repo Info"].json;
const errorData = $node["Format Error for Retry"].json;

const failureResponse = {
  status: 'FAILED',
  repo: repoData.repo_name,
  branch: repoData.branch,
  commit: repoData.commit_sha.substring(0, 8),
  attempts: errorData.retry_count + 1,
  max_attempts: 3,
  message: 'Build failed after 3 attempts ❌',
  errors: errorData.error_details,
  timestamp: new Date().toISOString(),
  gitea_status: 'failure',
  next_steps: 'Please review the error messages and fix the issues manually before pushing again.'
};

return failureResponse;

📋 HTTP Response Node

const response = $json;
return [
  {
    statusCode: response.status === 'SUCCESS' ? 200 : 500,
    body: response
  }
];

🔧 Decision Node Configurations

Node 7: "Build OK?" (IF Node)

Mode: Expression Value 1:

{{ $json.build_success }}

Operation: Equal Value 2:

true

Node 10: "Can We Retry?" (IF Node)

Mode: Expression Value 1:

{{ $json.can_retry }}

Operation: Equal Value 2:

true

📋 Quick Setup Commands

Generate Gitea Token

# Method 1: API (requires admin token)
curl -X POST https://git.oky.sh/api/v1/users/gitadmin/tokens \
  -H "X-Gitea-Token: {ADMIN_TOKEN_HERE}" \
  -H "Content-Type: application/json" \
  -d '{"name": "n8n-autonomous-build", "scopes": ["repo", "admin:repo_hook"]}'

# Method 2: UI
# 1. https://git.oky.sh/user/settings/applications
# 2. Generate Token → n8n-autonomous-build
# 3. Copy token (format: gho_...)

Store Token Securely

echo "GITEA_API_TOKEN=gho_your_token_here" > /home/bam/.gitea_token
chmod 600 /home/bam/.gitea_token

🧪 Test Commands

Test Workflow Manually

curl -X POST https://n8n.oky.sh/webhook/openhands-autonomous-build \
  -H "Content-Type: application/json" \
  -d '{
    "repository": {
      "name": "test-project",
      "full_name": "gitadmin/test-project",
      "owner": {"name": "gitadmin", "username": "gitadmin"}
    },
    "ref": "refs/heads/main",
    "after": "abc123def456789012345678901234567890abcd",
    "pusher": {"name": "testuser"}
  }'

Create Test Repository

curl -X POST https://git.oky.sh/api/v1/user/repos \
  -H "X-Gitea-Token: {YOUR_TOKEN}" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "autonomous-build-test",
    "description": "Phase 3 test repository"
  }'

Implementation Checklist

Before Starting

  • Read phase3-implementation-plan.md
  • Generate Gitea API token
  • Store token in secure location
  • Have test repository ready

During Implementation

  • Add Node 3: Initialize Retry Counter
  • Modify Node 2: Extract Repo Info (add fields)
  • Modify Node 4: Enhance OpenHands Build command + data preservation
  • Modify Node 5: Ensure Wait is 10s
  • Modify Node 6: Update Check Build Results
  • Add Node 7: Decision - Build OK?
  • Add Node 8: Update Gitea Success
  • Add Node 9: Format Error for Retry
  • Add Node 10: Check Retry Count
  • Modify Node 11: Final Response (both paths)
  • Update HTTP Response

After Implementation

  • Test success path
  • Test retry with fixable errors
  • Test max retries (3 attempts)
  • Test with real project
  • Verify Gitea status updates

Ready to copy & paste! 🚀