AutomationFlowsDevOps › v3.7

v3.7

v3.7. Uses executeCommand, gitlab, stickyNote. Webhook trigger; 19 nodes.

Webhook trigger★★★★☆ complexity19 nodesExecute CommandGitlab
DevOps Trigger: Webhook Nodes: 19 Complexity: ★★★★☆

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "name": "v3.7",
  "nodes": [
    {
      "parameters": {
        "httpMethod": "POST",
        "path": "gitlab-issue-webhook",
        "options": {}
      },
      "id": "181e695e-f50a-4e4c-be6a-b0c6e8567760",
      "name": "GitLab Issue Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 2,
      "position": [
        -1840,
        -368
      ]
    },
    {
      "parameters": {
        "jsCode": "// Process GitLab issue webhook for automatic implementation\nconst webhookData = $('GitLab Issue Webhook').first().json.body;\n\n// Only process issue creation events\nif (webhookData.object_kind !== 'issue' || webhookData.object_attributes?.action !== 'open') {\n  return [];\n}\n\nconst issue = webhookData.object_attributes;\nconst author = webhookData.user;\nconst project = webhookData.project;\n\n// Extract issue details\nconst issueTitle = issue.title;\nconst issueDescription = issue.description || 'No description provided';\nconst issueId = issue.iid;\nconst issueUrl = issue.url;\n\n// Create branch name for this implementation\nconst branchName = `claude-auto-${issueId}-${Date.now()}`;\n\n// Build context for processing\nreturn [{\n  json: {\n    issueTitle: issueTitle,\n    issueId: issueId,\n    issueDescription: issueDescription,\n    issueUrl: issueUrl,\n    issueAuthor: author.name,\n    projectId: project.id,\n    projectName: project.name,\n    projectPath: project.path,\n    projectNamespace: project.path_with_namespace,\n    branchName: branchName,\n    timestamp: new Date().toISOString()\n  }\n}];"
      },
      "id": "3085ff04-7c67-4f81-9527-4cd49d4b4400",
      "name": "Process Issue",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1504,
        -368
      ]
    },
    {
      "parameters": {
        "command": "=cd /workspace/{{ $('Process Issue').item.json.projectName }} && git checkout main && git pull origin main && git reset --hard HEAD && git clean -fd"
      },
      "id": "08c48068-82d4-4c7a-a6d0-3007f24304d5",
      "name": "Workspace Cleanup",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        -1280,
        -368
      ]
    },
    {
      "parameters": {
        "command": "=cd /workspace/{{ $('Process Issue').item.json.projectName }} && git checkout -b {{ $('Process Issue').item.json.branchName }}"
      },
      "id": "ca1246ec-7f82-45b9-bfa3-03b63ab39e57",
      "name": "Create Branch",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        -1056,
        -368
      ]
    },
    {
      "parameters": {
        "command": "=cd /workspace/{{ $('Process Issue').item.json.projectName }} && echo '{{ $('Prepare Plan Prompt').item.json.planPromptEscaped }}' | claude --dangerously-skip-permissions"
      },
      "id": "751dede3-a05f-4c1f-b171-bb25e959a9f3",
      "name": "Create Plan",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        -1280,
        -144
      ]
    },
    {
      "parameters": {
        "command": "=cd /workspace/{{ $('Process Issue').item.json.projectName }} && git config user.name \"{{ $('Process Issue').item.json.issueAuthor }}\" && git config user.email \"claude-code@automated\" && echo '{{ $('Prepare Implementation Prompt').item.json.implementPromptEscaped }}' | claude --dangerously-skip-permissions"
      },
      "id": "25623a34-0a84-46ea-8fdf-12de07804bb5",
      "name": "Implement Code",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        -1280,
        64
      ]
    },
    {
      "parameters": {
        "command": "=cd /workspace/{{ $('Process Issue').item.json.projectName }} && git add . && git commit -m \"Implement: {{ $('Process Issue').item.json.issueTitle }}\""
      },
      "id": "13c96190-7a78-4519-9a09-350621963656",
      "name": "Commit Implementation",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        -1056,
        64
      ]
    },
    {
      "parameters": {
        "command": "=cd /workspace/{{ $('Process Issue').item.json.projectName }} && git push -u origin {{ $('Process Issue').item.json.branchName }}"
      },
      "id": "6b61c6d6-b0d0-479d-9862-7770c6bb3cee",
      "name": "Push Branch",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        -832,
        64
      ]
    },
    {
      "parameters": {
        "command": "=cd /workspace/{{ $('Process Issue').item.json.projectName }} && glab mr create --title \"Auto Implementation: {{ $('Process Issue').item.json.issueTitle }}\" --description \"Auto-implementation by Claude Code for issue #{{ $('Process Issue').item.json.issueId }}\\n\\nOriginal issue: {{ $('Process Issue').item.json.issueDescription }}\\n\\nImplemented via automatic workflow.\" --source-branch {{ $('Process Issue').item.json.branchName }} --target-branch main"
      },
      "id": "b1de4a07-d652-4045-a91e-47bc4f13558d",
      "name": "Create MR",
      "type": "n8n-nodes-base.executeCommand",
      "typeVersion": 1,
      "position": [
        -1504,
        288
      ]
    },
    {
      "parameters": {
        "jsCode": "// Create planning prompt with full issue context\nconst context = $('Process Issue').item.json;\n\nconst planPrompt = `GitLab Issue Planning Request\n\nIssue Details:\nTitle: ${context.issueTitle}\nDescription: ${context.issueDescription}\nAuthor: ${context.issueAuthor}\nURL: ${context.issueUrl}\n\nPlease analyze this issue and create a detailed implementation plan. Follow these steps:\n\n1. ANALYZE: Understand what needs to be implemented based on the issue description\n2. PLAN: Create a step-by-step implementation plan that includes:\n   - What files need to be created or modified\n   - What functionality needs to be added\n   - Any dependencies or prerequisites\n   - Expected user interactions and flows\n   - Testing considerations\n\n3. DESIGN: If this involves UI changes, describe:\n   - Visual components and layout\n   - User interface elements\n   - Styling and visual hierarchy\n   - User experience flow\n\nProvide a comprehensive plan that will guide the implementation phase. Be specific about technical details and implementation steps.`;\n\n// Escape the prompt for shell execution\nconst planPromptEscaped = planPrompt.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"'\\\"'\\\"'\");\n\nreturn [{\n  json: {\n    ...context,\n    planPrompt: planPrompt,\n    planPromptEscaped: planPromptEscaped\n  }\n}];"
      },
      "id": "92746059-1d00-4949-9900-baa268746649",
      "name": "Prepare Plan Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1504,
        -144
      ]
    },
    {
      "parameters": {
        "jsCode": "// Extract plan from Claude output and prepare for posting\nconst planOutput = $('Create Plan').item.json;\nconst context = $('Process Issue').item.json;\n\nlet plan = '';\nif (planOutput.exitCode === 0 && planOutput.stdout) {\n  plan = planOutput.stdout.trim();\n} else {\n  plan = 'Plan generation failed. Proceeding with basic implementation approach.';\n}\n\n// Create plan comment for GitLab\nconst planComment = `\ud83d\udccb **Implementation Plan**\n\n${plan}\n\n---\n*\ud83e\udd16 Auto-generated plan for issue #${context.issueId}*\n*Implementation will begin shortly...*`;\n\nconst commentEscaped = planComment.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"'\\\"'\\\"'\");\n\nreturn [{\n  json: {\n    ...context,\n    plan: plan,\n    planComment: planComment,\n    commentEscaped: commentEscaped\n  }\n}];"
      },
      "id": "c678f231-52a9-4e61-82c0-296a62e0d691",
      "name": "Prepare Plan Comment",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1056,
        -144
      ]
    },
    {
      "parameters": {
        "operation": "createComment",
        "owner": "={{ $('Process Issue').item.json.projectNamespace.split('/')[0] }}",
        "repository": "={{ $('Process Issue').item.json.projectName }}",
        "issueNumber": "={{ $('Process Issue').item.json.issueId }}",
        "body": "={{ $('Prepare Plan Comment').item.json.planComment }}"
      },
      "id": "9e60d57b-ea4e-4fe3-a914-c1017b594201",
      "name": "Post Plan Comment",
      "type": "n8n-nodes-base.gitlab",
      "typeVersion": 1,
      "position": [
        -832,
        -144
      ],
      "credentials": {
        "gitlabApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// Create implementation prompt with both issue context and generated plan\nconst context = $('Prepare Plan Comment').item.json;\n\nconst implementPrompt = `GitLab Issue Implementation Request\n\nIssue Details:\nTitle: ${context.issueTitle}\nDescription: ${context.issueDescription}\nAuthor: ${context.issueAuthor}\nURL: ${context.issueUrl}\n\nImplementation Plan:\n${context.plan}\n\nInstructions:\n\n1. FOLLOW THE PLAN: Implement the solution according to the detailed plan above\n2. QUALITY ASSURANCE: Ensure high code quality by:\n   - Following best practices and coding standards\n   - Adding appropriate error handling\n   - Including necessary imports and dependencies\n   - Ensuring proper code structure and organization\n   - Running any necessary build/compile checks\n\n3. COMPLETENESS: Implement all aspects mentioned in the plan\n4. TESTING: Consider edge cases and ensure the implementation works as expected\n\nThe workflow will handle committing and pushing your changes automatically. Focus on delivering a complete, high-quality implementation that follows the plan.`;\n\n// Escape the prompt for shell execution\nconst implementPromptEscaped = implementPrompt.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"'\\\"'\\\"'\");\n\nreturn [{\n  json: {\n    ...context,\n    implementPrompt: implementPrompt,\n    implementPromptEscaped: implementPromptEscaped\n  }\n}];"
      },
      "id": "13059283-b888-462c-bfac-443ea7cbe68a",
      "name": "Prepare Implementation Prompt",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1504,
        64
      ]
    },
    {
      "parameters": {
        "jsCode": "// Extract MR URL from glab output and prepare success comment\nconst mrOutput = $('Create MR').item.json;\nconst context = $('Process Issue').item.json;\n\nlet mrUrl = '';\nif (mrOutput.exitCode === 0 && mrOutput.stdout) {\n  // Extract MR URL from glab output\n  const urlMatch = mrOutput.stdout.match(/https:\\/\\/[^\\s]+/g);\n  if (urlMatch && urlMatch.length > 0) {\n    mrUrl = urlMatch[urlMatch.length - 1]; // Get the last URL which should be the MR URL\n  }\n}\n\n// Create success comment\nconst successComment = `\u2705 **Auto-Implementation Complete!**\n\nI've automatically implemented a solution for this issue based on the generated plan.\n\n**Branch Created:** \\`${context.branchName}\\`\n${mrUrl ? `**Merge Request:** ${mrUrl}` : '**Note:** Merge request creation may have failed - please check manually.'}\n\n**What was implemented:**\nThe implementation follows the detailed plan posted earlier and is ready for review.\n\n---\n*\ud83e\udd16 Automated implementation via GitLab issue workflow*`;\n\nconst commentEscaped = successComment.replace(/\\\\/g, '\\\\\\\\').replace(/'/g, \"'\\\"'\\\"'\");\n\nreturn [{\n  json: {\n    ...context,\n    mrUrl: mrUrl,\n    successComment: successComment,\n    commentEscaped: commentEscaped,\n    mrExitCode: mrOutput.exitCode,\n    mrOutput: mrOutput.stdout || mrOutput.stderr\n  }\n}];"
      },
      "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "name": "Prepare Success Comment",
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        -1280,
        288
      ]
    },
    {
      "parameters": {
        "operation": "createComment",
        "owner": "={{ $('Process Issue').item.json.projectNamespace.split('/')[0] }}",
        "repository": "={{ $('Process Issue').item.json.projectName }}",
        "issueNumber": "={{ $('Process Issue').item.json.issueId }}",
        "body": "={{ $('Prepare Success Comment').item.json.successComment }}"
      },
      "id": "b2c3d4e5-f6g7-8901-bcde-f23456789012",
      "name": "Post Success Comment",
      "type": "n8n-nodes-base.gitlab",
      "typeVersion": 1,
      "position": [
        -1056,
        288
      ],
      "credentials": {
        "gitlabApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "## Issue Processing",
        "height": 192,
        "width": 816,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1696,
        -432
      ],
      "typeVersion": 1,
      "id": "33b32a85-0102-4aea-a0b5-853574f5829a",
      "name": "Sticky Note"
    },
    {
      "parameters": {
        "content": "## Planning",
        "height": 240,
        "width": 816,
        "color": 3
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1696,
        -240
      ],
      "typeVersion": 1,
      "id": "35c79c99-fceb-480d-bd6c-b1a417d52d77",
      "name": "Sticky Note1"
    },
    {
      "parameters": {
        "content": "## Implementation",
        "height": 208,
        "width": 816,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1696,
        0
      ],
      "typeVersion": 1,
      "id": "86013b29-24a2-42fc-a36b-d3649cdec866",
      "name": "Sticky Note2"
    },
    {
      "parameters": {
        "content": "## Create MR\n## and Notify",
        "height": 224,
        "width": 816,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1696,
        208
      ],
      "typeVersion": 1,
      "id": "bbf21137-c7fe-45ef-8edd-500349db68c1",
      "name": "Sticky Note3"
    }
  ],
  "connections": {
    "GitLab Issue Webhook": {
      "main": [
        [
          {
            "node": "Process Issue",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Process Issue": {
      "main": [
        [
          {
            "node": "Workspace Cleanup",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Workspace Cleanup": {
      "main": [
        [
          {
            "node": "Create Branch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Branch": {
      "main": [
        [
          {
            "node": "Prepare Plan Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Plan Prompt": {
      "main": [
        [
          {
            "node": "Create Plan",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Plan": {
      "main": [
        [
          {
            "node": "Prepare Plan Comment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Plan Comment": {
      "main": [
        [
          {
            "node": "Post Plan Comment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Post Plan Comment": {
      "main": [
        [
          {
            "node": "Prepare Implementation Prompt",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Implementation Prompt": {
      "main": [
        [
          {
            "node": "Implement Code",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Implement Code": {
      "main": [
        [
          {
            "node": "Commit Implementation",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Commit Implementation": {
      "main": [
        [
          {
            "node": "Push Branch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Push Branch": {
      "main": [
        [
          {
            "node": "Create MR",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create MR": {
      "main": [
        [
          {
            "node": "Prepare Success Comment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Success Comment": {
      "main": [
        [
          {
            "node": "Post Success Comment",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "83760934-05b9-4731-be91-a69594261028",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "id": "KRzL0kx7EIwEWlLm",
  "tags": []
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

About this workflow

v3.7. Uses executeCommand, gitlab, stickyNote. Webhook trigger; 19 nodes.

Source: https://gitlab.com/huyhq8/gitlab-ai-automation/-/blob/develop/n8n/workflows/v3_7.json — original creator credit. Request a take-down →

More DevOps workflows → · Browse all categories →