AutomationFlowsAI & RAG › Analyze GitLab CI Failures with AI and Send Slack Reports

Analyze GitLab CI Failures with AI and Send Slack Reports

Original n8n title: Analyze Gitlab Ci Job Failures with Gpt-5.3 and Send Reports to Slack

BySergei Byvshev @javdet on n8n.io

This workflow helps automatically analyze the causes of build failures in Gitlab CI and propose solutions without involving DevOps engineers. See detailed setup guide Checks whether a job crashed. Gets logs of the crashed job and a description of the pipeline. The agent analyzes…

Webhook trigger★★★★☆ complexityAI-powered22 nodesHTTP RequestAgentOpenAI ChatHTTP Request ToolMcp Client ToolSlack
AI & RAG Trigger: Webhook Nodes: 22 Complexity: ★★★★☆ AI nodes: yes Added:

This workflow corresponds to n8n.io template #14129 — we link there as the canonical source.

This workflow follows the Agent → HTTP Request recipe pattern — see all workflows that pair these two integrations.

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
{
  "id": "2E16VAHgDq5sG1kI",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "publicCI/CDassistant",
  "tags": [],
  "nodes": [
    {
      "id": "cf4db35c-a98b-444e-a765-3e43204206c7",
      "name": "Is job failed?",
      "type": "n8n-nodes-base.if",
      "position": [
        96,
        0
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 3,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bbeeb61b-b294-4328-a9f7-001e2a0a1920",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.body.object_attributes.status }}",
              "rightValue": "failed"
            }
          ]
        }
      },
      "typeVersion": 2.3
    },
    {
      "id": "bf700581-5681-49ae-84d1-5e18894ba71e",
      "name": "Get Job Events",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -112,
        0
      ],
      "parameters": {
        "path": "ab7b7111-31d5-4676-8b69-dfc364d9c4b7",
        "options": {},
        "httpMethod": "POST",
        "authentication": "headerAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.1
    },
    {
      "id": "3796ec77-82aa-4360-84ff-97ab2e24149f",
      "name": "Extract event data",
      "type": "n8n-nodes-base.code",
      "position": [
        576,
        -128
      ],
      "parameters": {
        "language": "pythonNative",
        "pythonCode": "\"\"\"\nExtract pipeline context and identify failed jobs from Pipeline Hook event.\n\"\"\"\n\nbody = _items[0][\"json\"][\"body\"]\nattrs = body.get(\"object_attributes\", {})\nproject = body.get(\"project\", {})\ncommit = body.get(\"commit\", {})\nuser = body.get(\"user\", {})\nmerge_request = body.get(\"merge_request\", {})\nbuilds = body.get(\"builds\", [])\n\n# --- Filter failed jobs (only those that actually broke the pipeline) ---\nfailed_jobs = []\nfor build in builds:\n    if build.get(\"status\") != \"failed\":\n        continue\n    if build.get(\"allow_failure\", False):\n        continue\n\n    runner = build.get(\"runner\", {})\n    environment = build.get(\"environment\", {})\n\n    failed_jobs.append({\n        \"job_id\": build.get(\"id\"),\n        \"job_name\": build.get(\"name\", \"unknown\"),\n        \"job_stage\": build.get(\"stage\", \"unknown\"),\n        \"failure_reason\": build.get(\"failure_reason\", \"unknown\"),\n        \"duration_sec\": round(build.get(\"duration\", 0), 1),\n        \"queued_duration_sec\": round(build.get(\"queued_duration\", 0), 1),\n        \"started_at\": build.get(\"started_at\", \"\"),\n        \"finished_at\": build.get(\"finished_at\", \"\"),\n        \"env_name\": environment.get(\"name\", \"\") if environment else \"\",\n        \"env_action\": environment.get(\"action\", \"\") if environment else \"\",\n        \"has_artifacts\": build.get(\"artifacts_file\", {}).get(\"filename\") is not None,\n    })\n\n# --- If no real failed jobs found, skip processing ---\nif not failed_jobs:\n    return []\n\n# --- Project & GitLab API base ---\nproject_url = project.get(\"web_url\", \"\")\ngitlab_base_url = \"/\".join(project_url.split(\"/\")[:3]) if project_url else \"https://gitlab.com\"\n\n# --- Merge Request info (if triggered by MR) ---\nmr_info = None\nif merge_request:\n    mr_info = {\n        \"mr_iid\": merge_request.get(\"iid\"),\n        \"mr_title\": merge_request.get(\"title\", \"\"),\n        \"source_branch\": merge_request.get(\"source_branch\", \"\"),\n        \"target_branch\": merge_request.get(\"target_branch\", \"\"),\n        \"mr_url\": merge_request.get(\"url\", \"\"),\n        \"mr_state\": merge_request.get(\"state\", \"\"),\n    }\n\n# --- Common pipeline context ---\npipeline_context = {\n    \"project_id\": project.get(\"id\"),\n    \"pipeline_id\": attrs.get(\"id\"),\n    \"pipeline_iid\": attrs.get(\"iid\"),\n    \"commit_sha\": attrs.get(\"sha\"),\n    \"gitlab_base_url\": gitlab_base_url,\n    \"pipeline_duration_sec\": attrs.get(\"duration\", 0),\n    \"pipeline_url\": attrs.get(\"url\", \"\"),\n    \"project_url\": project_url,\n    \"default_branch\": project.get(\"default_branch\", \"main\"),\n}\n\n# --- Output: one item per failed job ---\nresults = []\nfor job in failed_jobs:\n    results.append({\n        \"pipeline\": pipeline_context,\n        \"failed_job\": job,\n    })\n\nreturn results"
      },
      "typeVersion": 2
    },
    {
      "id": "a14e2e13-7a00-4434-a266-0cf7ba12b7d0",
      "name": "No Operation, do nothing",
      "type": "n8n-nodes-base.noOp",
      "position": [
        384,
        272
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "09f5ff62-4d6b-46b2-8731-a264747ec92f",
      "name": "GetJobLogs",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        736,
        -320
      ],
      "parameters": {
        "url": "={{ $json.pipeline.gitlab_base_url }}/api/v4/projects/{{ $json.pipeline.project_id }}/jobs/{{ $json.failed_job.job_id }}/trace",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "gitlabApi"
      },
      "credentials": {
        "githubApi": {
          "name": "<your credential>"
        },
        "gitlabApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "f32b5199-245f-4643-8d4f-5da5aed72c83",
      "name": "GetCIFile",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        864,
        64
      ],
      "parameters": {
        "url": "={{ $json.pipeline.gitlab_base_url }}/api/v4/projects/{{ $json.pipeline.project_id }}/repository/files/.gitlab-ci.yml/raw",
        "options": {},
        "sendQuery": true,
        "authentication": "predefinedCredentialType",
        "queryParameters": {
          "parameters": [
            {
              "name": "ref",
              "value": "={{ $json.pipeline.commit_sha }}"
            }
          ]
        },
        "nodeCredentialType": "gitlabApi"
      },
      "credentials": {
        "githubApi": {
          "name": "<your credential>"
        },
        "gitlabApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.4
    },
    {
      "id": "81b7537e-89e4-4540-be63-f7730d1d8e41",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        1136,
        -144
      ],
      "parameters": {
        "numberInputs": 3
      },
      "typeVersion": 3.2
    },
    {
      "id": "54f8d4ac-d84b-4eff-8b35-4fe418ab5173",
      "name": "AI Agent",
      "type": "@n8n/n8n-nodes-langchain.agent",
      "position": [
        1616,
        -128
      ],
      "parameters": {
        "text": "={{ JSON.stringify($json, null, 2) }}",
        "options": {
          "systemMessage": "You have a good understanding of CI/CD systems such as Gitlab CI, Github Actions, Jenkins, Teamcity.\nYour main task is to analyze unsuccessful jobs. You only look and analyze, without changing anything. You need to provide 1 to 3 probable causes and their solutions.\n\n## Input format\nYou will receive request in json format. \n```\n[{\n\t \"job_log\": \"Last 50 lines of failed job\"\n\t },\n\t {\"data\": \"Content .gitlab-ci.yml\"},\n\t {\"pipeline\": {}}, // information about project and pipeline\n     {\"failed_job\" {}}, // information about failed job\n},]\n```\n\n## Gitlab tools\n- Use for manipulation with projects, repositories, files, commits, merge requests\n- Gitlab root group name: {{ $('SetVars').first().json.gitlab_group }}\n\n## HTTP request tool\n- Use for web request\n\n## Grafana tools\n- Use it to get GitLab Runner resource consumption metrics.\n- Use this to get pod metrics and logs in case of a failed deployment\n- Prometheus datasource name: {{ $('SetVars').first().json.prometheus_name }}\n- Loki datasource name: {{ $('SetVars').first().json.loki_name }}\n\n## Critical Rules for Tool Usage\n- Don't make any changes to anything through mcp.\n\n\n## Important rules\n- Don't ask anything, analyze it yourself\n\n## Investigation suggestion\n- Always analyze job_log first\n\n\n## Output format\n### What happened\nDescription of what happened and what happened to what\n\n### Root cause\nNo more than two root cause suggestions\n\n### Troubleshooting tips\nStep-by-step description of actions for each root cause"
        },
        "promptType": "define"
      },
      "typeVersion": 3.1
    },
    {
      "id": "681813df-17a9-40d8-ba76-afc0cd8a12a4",
      "name": "OpenAI Chat Model",
      "type": "@n8n/n8n-nodes-langchain.lmChatOpenAi",
      "position": [
        1488,
        80
      ],
      "parameters": {
        "model": {
          "__rl": true,
          "mode": "list",
          "value": "gpt-5.3-codex",
          "cachedResultName": "gpt-5.3-codex"
        },
        "options": {},
        "builtInTools": {}
      },
      "credentials": {
        "openAiApi": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 1.3
    },
    {
      "id": "85c671a7-a531-411c-a957-b145d7c6d191",
      "name": "GetLastLogLines",
      "type": "n8n-nodes-base.code",
      "position": [
        896,
        -320
      ],
      "parameters": {
        "language": "pythonNative",
        "pythonCode": "raw_log = _items[0][\"json\"].get(\"data\", \"\")\n\n# --- Strip ANSI escape sequences without regex ---\nclean = \"\"\ni = 0\nwhile i < len(raw_log):\n    if raw_log[i] == \"\\x1b\":\n        # Skip ESC[ ... <letter> sequences (CSI)\n        if i + 1 < len(raw_log) and raw_log[i + 1] == \"[\":\n            i += 2\n            while i < len(raw_log) and not raw_log[i].isalpha():\n                i += 1\n            i += 1  # skip the final letter\n            continue\n        # Skip ESC] ... ESC\\ sequences (OSC, used by GitLab hyperlinks)\n        elif i + 1 < len(raw_log) and raw_log[i + 1] == \"]\":\n            i += 2\n            while i < len(raw_log):\n                if raw_log[i] == \"\\x1b\" and i + 1 < len(raw_log) and raw_log[i + 1] == \"\\\\\":\n                    i += 2\n                    break\n                i += 1\n            continue\n        else:\n            i += 1\n            continue\n    clean += raw_log[i]\n    i += 1\n\n# --- Filter out section markers and empty lines ---\nlines = []\nfor line in clean.splitlines():\n    stripped = line.strip()\n    if not stripped:\n        continue\n    if stripped.startswith(\"section_start:\") or stripped.startswith(\"section_end:\"):\n        continue\n    lines.append(line)\n\n# --- Keep last 50 lines ---\nmax_lines = 50\ntotal = len(lines)\nif total > max_lines:\n    trimmed = lines[-max_lines:]\n    header = \"[... truncated \" + str(total - max_lines) + \" lines, showing last \" + str(max_lines) + \" ...]\\n\"\nelse:\n    trimmed = lines\n    header = \"\"\n\nreturn [{\n    \"job_log\": header + \"\\n\".join(trimmed),\n}]"
      },
      "typeVersion": 2
    },
    {
      "id": "283ccf3d-9369-42e6-97a6-8dcdb307b91c",
      "name": "HTTP Request",
      "type": "n8n-nodes-base.httpRequestTool",
      "position": [
        1808,
        320
      ],
      "parameters": {
        "url": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('URL', ``, 'string') }}",
        "options": {}
      },
      "typeVersion": 4.4
    },
    {
      "id": "6f2657bd-7d73-4120-bc08-1f01b452cd1f",
      "name": "Gitlab MCP",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "position": [
        1520,
        320
      ],
      "parameters": {
        "include": "selected",
        "options": {},
        "endpointUrl": "http://gitlab-mcp:8091/mcp",
        "includeTools": [
          "search_repositories",
          "get_file_contents",
          "get_merge_request",
          "get_merge_request_diffs",
          "list_merge_request_versions",
          "get_merge_request_version",
          "get_branch_diffs",
          "list_labels",
          "get_label",
          "list_projects",
          "get_project",
          "get_namespace",
          "list_namespaces",
          "get_commit",
          "get_commit_diff",
          "list_commits",
          "get_repository_tree",
          "list_merge_requests",
          "list_group_projects",
          "list_events",
          "get_pipeline",
          "list_pipelines",
          "list_pipeline_jobs",
          "list_pipeline_trigger_jobs",
          "get_pipeline_job",
          "get_pipeline_job_output"
        ]
      },
      "typeVersion": 1.2
    },
    {
      "id": "6b7a434d-be8e-41a8-b7dc-0e13eb2269ef",
      "name": "Send a message",
      "type": "n8n-nodes-base.slack",
      "position": [
        2080,
        -128
      ],
      "parameters": {
        "text": "={{ $json.output }}",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0AJFB5PV5Y",
          "cachedResultName": "devops-ai-tests"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "credentials": {
        "slackOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 2.4
    },
    {
      "id": "212cd5f6-c612-44b9-907b-83fe750b2fdc",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        368,
        -368
      ],
      "parameters": {
        "color": 5,
        "width": 928,
        "height": 560,
        "content": "# Collect data\n* Job logs\n* Pipeline file"
      },
      "typeVersion": 1
    },
    {
      "id": "f82eca31-ed2b-4c2e-b926-dd57b8460acb",
      "name": "FormatData",
      "type": "n8n-nodes-base.code",
      "position": [
        1360,
        -128
      ],
      "parameters": {
        "language": "pythonNative",
        "pythonCode": "result = {}\n\nfor item in _items:\n    data = item[\"json\"]\n    \n    # Item with job_log\n    if \"job_log\" in data:\n        result[\"job_log\"] = data[\"job_log\"]\n        result[\"job_log_total_lines\"] = data.get(\"job_log_total_lines\", 0)\n    \n    # Item with pipeline context and failed job info\n    if \"pipeline\" in data:\n        result[\"pipeline\"] = data[\"pipeline\"]\n        result[\"failed_job\"] = data[\"failed_job\"]\n    \n    # Item with CI config (raw YAML as string)\n    if \"data\" in data and \"pipeline\" not in data and \"job_log\" not in data:\n        result[\"ci_config\"] = data[\"data\"]\n    \n    # Item with commit diff (array of changed files)\n    if \"diff\" in data or (isinstance(data, list) and len(data) > 0 and \"diff\" in data[0]):\n        result[\"commit_diff\"] = data\n\nreturn [result]"
      },
      "typeVersion": 2
    },
    {
      "id": "431c2aec-c6ed-44a8-84c8-70b9e5f094fc",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1952,
        -208
      ],
      "parameters": {
        "width": 432,
        "height": 400,
        "content": "# Output Chain\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nPost generated report to Slack"
      },
      "typeVersion": 1
    },
    {
      "id": "9ac578ff-749c-416a-a887-15d82bb84940",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1328,
        -208
      ],
      "parameters": {
        "color": 6,
        "width": 592,
        "height": 400,
        "content": "# Error analysis"
      },
      "typeVersion": 1
    },
    {
      "id": "63e5c267-5ff5-4de1-8791-4c2168fb4e57",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1328,
        208
      ],
      "parameters": {
        "color": 4,
        "width": 592,
        "height": 416,
        "content": "# MCP servers\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nAdd correct URLs for remote MCPs\nUse following mcp:\n* [gitlab-mcp](https://github.com/zereight/gitlab-mcp)\n* [grafana-mcp](https://github.com/grafana/mcp-grafana)"
      },
      "typeVersion": 1
    },
    {
      "id": "fca3da23-d17b-4aa4-94b2-44fc256ca758",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -320,
        -736
      ],
      "parameters": {
        "color": 5,
        "width": 608,
        "height": 608,
        "content": "# Overview\nThis workflow helps automatically analyze the causes of build failures in Gitlab CI and propose solutions without involving DevOps engineers.\n## How it work\n1. Checks whether a job crashed.\n1. Gets logs of the crashed job and a description of the pipeline.\n1. The agent analyzes this data according to its system prompt.\n1. During the process, the agent can retrieve additional data from Gitlab and check the availability of endpoints.\n1. A report on the causes and solutions is sent to the selected Slack channel \n\n## How to use\n1. Generate webhook credentials and use it in Gitlab\n1. Add your own Rules and recommendations to system prompt\n1. Run MCP servers\n1. Choose Slack channel\n\n## Requirements:\n- OpenAI  or Anthropic API key\n- Slack API key\n- Webhook with X-Gitlab-Token \n- Gitlab Access key\n- Grafana Service Account token"
      },
      "typeVersion": 1
    },
    {
      "id": "b2460b44-19ef-4281-9699-889af3107091",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -176,
        -96
      ],
      "parameters": {
        "width": 448,
        "height": 288,
        "content": "# Input Chain\n\n\n\n\n\n\n\n\n\n\n\n\n\nReceving pipeline event from Gitlab"
      },
      "typeVersion": 1
    },
    {
      "id": "3dc3b6fe-eba2-4b91-908e-4f86ef753f60",
      "name": "MCP Grafana",
      "type": "@n8n/n8n-nodes-langchain.mcpClientTool",
      "position": [
        1664,
        320
      ],
      "parameters": {
        "include": "selected",
        "options": {},
        "endpointUrl": "http://mcp-grafana:8000/mcp",
        "includeTools": [
          "get_annotations",
          "get_annotation_tags",
          "get_dashboard_by_uid",
          "get_dashboard_panel_queries",
          "get_dashboard_property",
          "get_dashboard_summary",
          "get_datasource",
          "get_panel_image",
          "list_datasources",
          "list_loki_label_names",
          "list_loki_label_values",
          "list_prometheus_label_names",
          "list_prometheus_label_values",
          "list_prometheus_metric_metadata",
          "list_prometheus_metric_names",
          "query_loki_logs",
          "query_loki_patterns",
          "query_loki_stats",
          "query_prometheus",
          "query_prometheus_histogram",
          "search_dashboards",
          "search_folders"
        ]
      },
      "typeVersion": 1.2
    },
    {
      "id": "f9524ed0-d8ba-4982-a97d-934653899328",
      "name": "SetVars",
      "type": "n8n-nodes-base.set",
      "position": [
        400,
        -128
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "bc66cc19-c97c-4252-bb84-a0c81806565c",
              "name": "prometheus_name",
              "type": "string",
              "value": "dev"
            },
            {
              "id": "e9992949-2cc4-4341-873f-df6c88940027",
              "name": "loki_name",
              "type": "string",
              "value": "grafanacloud-logs"
            },
            {
              "id": "8fd89221-20b5-4013-b89c-bebfd2a509dc",
              "name": "grafana_group",
              "type": "string",
              "value": "TL"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    }
  ],
  "active": false,
  "settings": {
    "binaryMode": "separate",
    "availableInMCP": false,
    "executionOrder": "v1"
  },
  "versionId": "87124211-5d40-4cf8-a9c6-7b965ee202c4",
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "FormatData",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SetVars": {
      "main": [
        [
          {
            "node": "Extract event data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "AI Agent": {
      "main": [
        [
          {
            "node": "Send a message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GetCIFile": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "FormatData": {
      "main": [
        [
          {
            "node": "AI Agent",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GetJobLogs": {
      "main": [
        [
          {
            "node": "GetLastLogLines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Gitlab MCP": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "MCP Grafana": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request": {
      "ai_tool": [
        [
          {
            "node": "AI Agent",
            "type": "ai_tool",
            "index": 0
          }
        ]
      ]
    },
    "Get Job Events": {
      "main": [
        [
          {
            "node": "Is job failed?",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Is job failed?": {
      "main": [
        [
          {
            "node": "SetVars",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "No Operation, do nothing",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GetLastLogLines": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "OpenAI Chat Model": {
      "ai_languageModel": [
        [
          {
            "node": "AI Agent",
            "type": "ai_languageModel",
            "index": 0
          }
        ]
      ]
    },
    "Extract event data": {
      "main": [
        [
          {
            "node": "GetJobLogs",
            "type": "main",
            "index": 0
          },
          {
            "node": "GetCIFile",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    }
  }
}

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.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow helps automatically analyze the causes of build failures in Gitlab CI and propose solutions without involving DevOps engineers. See detailed setup guide Checks whether a job crashed. Gets logs of the crashed job and a description of the pipeline. The agent analyzes…

Source: https://n8n.io/workflows/14129/ — original creator credit. Request a take-down →

More AI & RAG workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

AI & RAG

This workflow automatically processes new free-trial / lead sign-ups in real time: Catches a webhook from any source (Webflow form, Intercom, custom agent, etc.) Filters out personal / disposable / .e

Output Parser Structured, Agent, HTTP Request +7
AI & RAG

This workflow transforms natural language queries into research reports through a five-stage AI pipeline. When triggered via webhook (typically from Google Sheets using the companion [](https://gist.g

Redis, Agent, Output Parser Structured +7
AI & RAG

slack command simple. Uses slackTrigger, httpRequest, slack, lmChatOpenAi. Webhook trigger; 17 nodes.

Slack Trigger, HTTP Request, Slack +5
AI & RAG

CLINICAINTEGRAL_secretary. Uses postgres, mcpClientTool, googleDriveTool, toolWorkflow. Webhook trigger; 89 nodes.

Postgres, Mcp Client Tool, Google Drive Tool +14
AI & RAG

This n8n workflow orchestrates a powerful suite of AI Agents and automations to manage and optimize various aspects of an e-commerce operation, particularly for platforms like Shopify. It leverages La

Google Sheets, HTTP Request, Slack +10