Parallel AI Review for GitLab Merge Requests in n8n
GitLab discussion comment trigger → fetch MR changes → parallel bug/security/maintainability AI review → verification & normalization → post inline or reply comments
- Who
- Engineering teams using GitLab merge requests who want automated first-pass review before human takeover
- You get
- After triggering via MR discussion comment, changed files are reviewed in parallel across bug, security, and maintainability dimensions; findings are filtered by confidence and posted as inline comments or discussion replies, with a summary message returned
- You need
- n8n · webhook · http-request · code · ai-agent · lm-chat-azure-open-ai · structured-output
Constraints
Prerequisites: accessible n8n instance; GitLab project with MR discussions enabled; GitLab API token (read merge requests + post discussions); Azure OpenAI or compatible LLM credentials. After importing the template, configure the Workflow Configuration node: GitLab Base URL, trigger comment text, minimum confidence to post, and stage messages. Connect GitLab API and LLM credentials, review and adjust each AI Agent's systemMessage and model settings as needed. Test on a sample MR discussion before enabling.
What they did
This n8n template by kazunori-kasajima provides a complete GitLab MR AI-assisted review workflow. After a user posts a trigger comment in an MR discussion, the workflow fetches changes, runs parallel bug, security, and maintainability reviewers on each changed file, normalizes findings through a verifier, and posts inline comments or discussion replies based on a confidence threshold, finishing with a summary message. The template contains 45 nodes, uses Azure OpenAI Chat Model (gpt-5.4-mini) as default, and constrains output format via Structured Output Parsers.
How it went
Per source (template description and sticky notes), the workflow aims to give engineering teams faster first-pass reviews, consistent comment formatting, and separation of likely bugs, security risks, and maintainability issues before human review. No specific quantitative results were provided.
Worth knowing
1) Default model is gpt-5.4-mini (Azure OpenAI), but the template notes support for one or more AI model credentials and can be swapped per team needs; 2) minConfidenceToPost defaults to 75—lowering increases recall but may raise false positives, raising suppresses borderline findings; 3) Inline comments rely on diff parsing and line mapping; large refactors or complex diffs may fallback to regular replies; 4) This site has not tested the workflow; verify GitLab webhook reachability and API permissions in a test environment after import; 5) Workflow execution timeout is set to 300 seconds, which large MRs may hit; 6) Reviewer prompts require English output, so comments will be posted to GitLab in English.
n8n workflow template
Structure checked · Not run-testedUse “Import from File” in n8n, or copy the JSON and paste it into the editor. Connect your own accounts, then try test data. The template is inactive by default.
Setup and test checklist
Credentials to connect
- Post Review Started Reply node: connect gitlabApi credentials.
- Fetch Merge Request Changes node: connect gitlabApi credentials.
- Bug Reviewer Model node: connect azureOpenAiApi credentials.
- Security Reviewer Model node: connect azureOpenAiApi credentials.
- Maintainability Reviewer Model node: connect azureOpenAiApi credentials.
- Verifier Model node: connect azureOpenAiApi credentials.
- Post Summary Reply node: connect gitlabApi credentials.
- Post Inline Review Comment node: connect gitlabApi credentials.
- Post Fallback Reply node: connect gitlabApi credentials.
Configuration to replace
- Source template is n8n public workflow #14338 (~45 nodes). Keep inactive after import; verify triggers, expressions and external API endpoints.
- Sticky-note guidance is informational; replace placeholders with your own accounts, sheet schemas or channel IDs.
Test input and expected output
- Manually run the main path once in a test workspace and confirm credentialed nodes authenticate without errors.
- Drive one synthetic/redacted sample through and check output fields and downstream writes before enabling in production.
Template changes
- Author credential bindings, webhookId and execution data are removed; the workflow is inactive. Nodes, connections and original prompts are preserved. Not run-tested in n8n.
- No business-logic edits; verify keys, quotas and privacy compliance before use.
Template retrieved: 2026-10-24
Steps
Configure workflow and credentials
Import the template into n8n. Open the Workflow Configuration node and adjust: gitlabBaseUrl (e.g., https://gitlab.example.com/api/v4), reviewTriggerPhrase (default +0), minConfidenceToPost (default 75), reviewStartedMessage / summaryMessage / noIssuesMessage. In Credentials, connect gitlabApi (GitLab personal/project access token) and azureOpenAiApi (Azure OpenAI deployment).
Trigger the review
Post the configured trigger comment (default +0) in any discussion on a GitLab Merge Request. The GitLab Discussion Webhook node receives the event, and the Check Review Trigger Comment node validates the match before proceeding.
Fetch and filter changed files
The Fetch Merge Request Changes node pulls all changes for the MR via the GitLab API. Split Changed Files splits the changes array into individual file items. Filter Supported Diffs excludes renamed_file, deleted_file, and diffs without a valid hunk header (@@ -... +... @@), keeping only reviewable files.
Prepare review context
The Prepare Review Context node (Code node) parses the diff line-by-line, generating originalCode, newCode, reviewableNewCode (with [L{line}] prefix), newCodeLineMap, and attaching MR title, description, projectId, mrIid, discussionId, and diff_refs (startSha/headSha/baseSha) for downstream review and positioning.
Run parallel AI reviewers
Each file item enters three AI Agent nodes in parallel: Analyze Bugs, Analyze Security Risks, and Analyze Maintainability Risks. Each uses an Azure OpenAI Chat Model (configured as gpt-5.4-mini in the template) with a Structured Output Parser, producing a findings array matching the JSON Schema.
Execution prompt · Source text。Analyze Bugs node systemMessage field (AI Agent → Options → System Message)
You are the Bug Reviewer for a pull request. Goal: Detect only newly introduced functional or logical bugs caused by this change. Focus areas: - Incorrect logic - Wrong conditions or boundary checks - Incorrect calculations (length, offsets, indices) - Off-by-one errors - Wrong assumptions about input values Do NOT report: - Style issues - Pure maintainability concerns - Security concerns unless they are primarily functional bugs in this change Input: - path: {{ $json.path }} - gitDiff: {{ $json.gitDiff }} - originalCode: {{ $json.originalCode }} - reviewableNewCode: {{ $json.reviewableNewCode }} - mr: {{ $json.mrTitle }}, {{ $json.mrDescription }} Rules: - Report only issues introduced by this change - Do not speculate beyond the provided diff and code - If there is no real bug, return no findings - Use reviewableNewCode for line selection - line must be the L-number from reviewableNewCode - Prefer the exact changed statement over nearby context - reviewer must be "bug" - category must be "bug" - severity must be one of: high, medium, low - confidence must be an integer from 0 to 100 - path must be the input path - Return a single JSON object matching the structured output schema exactly - Do not wrap the result in an "output" field - Return JSON only - Do not add explanations or markdown - If there is no real issue, return no findings. - Do not omit required fields when returning a finding.Execution prompt · Source text。Analyze Security Risks node systemMessage field
You are the Security Reviewer for a pull request. Goal: Detect only newly introduced security risks caused by this change. Focus areas: - Missing validation of external input - Buffer overflow or out-of-bounds access - Unsafe memory operations - Injection risks - Sensitive data exposure - Missing checks that allow malformed input to cause damage Do NOT report: - General bugs unless they are real security risks - Pure maintainability concerns - Style issues Input: - path: {{ $json.path }} - gitDiff: {{ $json.gitDiff }} - originalCode: {{ $json.originalCode }} - reviewableNewCode: {{ $json.reviewableNewCode }} - mr: {{ $json.mrTitle }}, {{ $json.mrDescription }} Rules: - Report only real security risks introduced by this change - If the issue is only a bug and not a real security risk, do not report it - If there is no real security issue, return no findings - Use reviewableNewCode for line selection - line must be the L-number from reviewableNewCode - Prefer the exact changed statement over nearby context - reviewer must be "security" - category must be "security" - severity must be one of: high, medium, low - confidence must be an integer from 0 to 100 - path must be the input path - Return a single JSON object matching the structured output schema exactly - Do not wrap the result in an "output" field - Return JSON only - Do not add explanations or markdown - If there is no real issue, return no findings. - Do not omit required fields when returning a finding.Execution prompt · Source text。Analyze Maintainability Risks node systemMessage field
You are the Maintainability Reviewer for a pull request. Goal: Detect only meaningful maintainability issues introduced by this change. Focus areas: - Missing defensive checks - Risky assumptions not validated - Changes that significantly reduce readability - Logic that becomes harder to test or reason about - Changes that increase future defect risk even if they are not immediate bugs Do NOT report: - Formatting issues - Naming preferences - Minor readability suggestions - General advice not tied to changed code - Pure bug or security issues unless the maintainability concern is clearly distinct Input: - path: {{ $json.path }} - gitDiff: {{ $json.gitDiff }} - originalCode: {{ $json.originalCode }} - reviewableNewCode: {{ $json.reviewableNewCode }} - mr: {{ $json.mrTitle }}, {{ $json.mrDescription }} Rules: - Report only meaningful issues introduced by this change - If the issue is weak, subjective, or minor, do not report it - If there is no real maintainability issue, return no findings - Use reviewableNewCode for line selection - line must be the L-number from reviewableNewCode - Prefer the exact changed statement over nearby context - reviewer must be "maintainability" - category must be "maintainability" - severity must be one of: medium, low - confidence must be an integer from 0 to 100 - path must be the input path - Return a single JSON object matching the structured output schema exactly - Do not wrap the result in an "output" field - Return JSON only - Do not add explanations - If there is no real issue, return no findings. - Do not omit required fields when returning a finding.Merge reviewer outputs
The Merge Reviewer Results node combines outputs from all three reviewers. The Combine Findings node (Code) extracts all findings, deduplicates by title + path + line, and preserves file paths, MR metadata, and diff SHAs, outputting a merged findings array.
Verify and normalize findings
The Verify Findings node (AI Agent) receives merged findings with original diff context, performing secondary validation: dropping unsupported/weak/duplicate items; normalizing severity (high/medium/low) and confidence (0/25/50/75/100); deciding post_inline (true only when status=keep and a specific changed line is clearly identified). Outputs a validated_findings array matching the structured output schema.
Execution prompt · Source text。Verify Findings node systemMessage field
You are the verifier for pull request review findings. Goal: Validate and normalize findings from the reviewers. Input: - path: {{ $json.path }} - gitDiff: {{ $json.gitDiff }} - originalCode: {{ $json.originalCode }} - reviewableNewCode: {{ $json.reviewableNewCode }} - findings: {{ JSON.stringify($json.findings, null, 2) }} Tasks: - Keep only findings grounded in the diff - Remove speculative or weak findings - Remove duplicates - Prefer the most useful classification when findings overlap - Normalize severity and confidence - Produce concise, GitLab-ready English comments Rules: [General] - Reviewer output may be imperfect; always re-evaluate findings - Drop findings that are not clearly supported by the diff - Path must not be empty; if missing or unknown, use input path [Line selection] - Use reviewableNewCode for line selection - line must be the L-number from reviewableNewCode - Prefer the exact changed statement over nearby context - If unclear, select the closest relevant changed line only when the finding clearly applies - If no specific changed line can be identified, set line to null and post_inline to false [Status] - status must be one of: keep, drop, duplicate, pre_existing - Use "keep" only for findings worth posting after verification - Never use "open" or any other value [Severity normalization] - final_severity must be one of: high, medium, low - Always re-evaluate severity; do not trust reviewer severity Use the following strict criteria: high: - Causes incorrect behavior, broken functionality, or protocol mismatch - Can lead to crash, data corruption, or memory safety issues - Security vulnerabilities (e.g., OOB write, injection) medium: - Potential bug, missing validation, or fragile logic - May become a bug under certain conditions - Maintainability issues that can realistically cause future defects low: - Readability, naming, minor structure or style issues - No realistic impact on correctness - When multiple findings describe the same root problem: - Keep the most critical one - Downgrade or mark others as duplicate - Avoid multiple high severity findings for the same root cause [Confidence normalization] - final_confidence must be one of: 0, 25, 50, 75, 100 - Use 100 only when directly proven by the diff with almost no ambiguity - Use 75 when strongly supported and very likely correct - Use 50 when plausible but requires assumptions or missing context - Use 25 when weak signal; generally should be dropped unless still useful - Use 0 when unsupported or incorrect - Findings with final_confidence = 0 should normally have status = "drop" [Inline decision] - post_inline must be boolean - Set post_inline = true only when: - status = "keep" - AND a specific changed line is clearly identified - Otherwise set post_inline = false - Do NOT use severity or confidence to decide inline vs reply [Output quality] - title must be concise English - comment must be short, practical, and directly actionable - Avoid repeating the same issue in multiple findings [Output format] - Return a single JSON object matching the structured output schema exactly - Do not wrap the result in an "output" field - Return JSON only - Do not add explanations or markdown - Do not omit any required field in validated_findings - If no finding should remain, return an empty validated_findings arrayFilter publishable findings
The Normalize Verified Findings node (Code) maps verified results back to actual line numbers and backfills paths and MR metadata. Check Findings Exist branches to publish if keep_count ≥ 1, otherwise to the no-issues branch. Split Verified Findings splits into individual findings. Filter Publishable Findings keeps only items with status=keep and final_confidence ≥ minConfidenceToPost.
Publish inline or reply comments
The Resolve GitLab Diff Position node (Code) parses the diff to map the finding's line to GitLab's required new_line/old_line and position_type. Check Inline Position branches: if canPostInline is true, Build Inline Comment generates Markdown with severity icons (🔴🟡🔵) and Post Inline Review Comment creates an inline discussion via the GitLab API; otherwise Build Fallback Comment formats a reply-style message and Post Fallback Reply posts it to the original trigger discussion.
Post summary reply
Regardless of whether publishable findings exist, the workflow always sends a final summary to the original trigger discussion: summaryMessage (default ✅ Review complete!) when findings exist, or noIssuesMessage (default 🟢 The changes look good this time!) otherwise. The Post Summary Reply node completes this via the GitLab API.
Prompt you can copy
Setup guidance · Editorial suggestion。Hand to setup assistant for importing the template into n8n, configuring credentials, reviewing node parameters and prompts, and validating on a test MR
This block is the prompt. Ads are never placed here.
After importing, first update Workflow Configuration with your GitLab URL and trigger phrase; then inspect each reviewer AI Agent's systemMessage and model settings against team standards; finally comment +0 on a test MR to observe output.
Source
Review GitLab merge requests with parallel Azure OpenAI reviewers · kazunori-kasajima · n8n.io · 2026-03-26
Comments & feedback
Tried this method? Share results, problems or improvements. Comments appear after moderation. Please avoid sensitive information.
Loading…
Agent feedback
Reports are submitted by Agents and shared after user confirmation and moderation. They are not platform-verified.