Example Workflow: Bitbucket PR Analysis ๐
This ready-to-adapt workflow automates Pull Request (PR) reviews on Bitbucket by extracting changed code files, generating documentation and test suggestions via DocuWriter.ai, and posting a comprehensive PR comment. An optional Slack notification keeps your team informed.
Workflow Overview
Below is a high-level flow of the Bitbucket PR analysis:
flowchart TD
A[Bitbucket PR Webhook] --> B[Filter: PR Created]
B -->|yes| C[Get PR Diff]
C --> D[Extract Changed Files]
D --> E[Get File Content]
E --> F[Prepare Source Code]
F --> G1[Generate Documentation]
F --> G2[Generate Test Suggestions]
G1 & G2 --> H[Aggregate Results]
H --> I[Format PR Comment]
I --> J[Post PR Comment]
J --> K[Notify Slack]
J --> L[Webhook Response]
B -->|no| M[Webhook Response (Ignored)]
1. Trigger: Bitbucket PR Creation
Listens for PR events in your Bitbucket workspace and repository.
- Node: Bitbucket PR Webhook
- Type:
n8n-nodes-base.bitbucketTrigger - Configuration:
- Events:
pullrequest:created - Credentials: OAuth2 with Bitbucket API
- Events:
2. Filtering PR Creation Events
Ensures only new Pull Requests trigger further actions.
- Node: Filter: PR Created
- Type:
n8n-nodes-base.if - Condition:
$json.pullrequest.state === 'OPEN'
3. Fetching PR Diff and Changed Files
Retrieves the diff, then parses it to identify only code files modified in the PR.
| Node Name | Type | Purpose |
|---|---|---|
| Get PR Diff | n8n-nodes-base.bitbucket |
Fetches PR diff from Bitbucket API |
| Extract Changed Files | n8n-nodes-base.code |
Parses diff, filters by extensions |
// Extract Changed Files
const codeExtensions = ['.js','.ts','.py','.java'];
const diffs = $json.pullrequest.diff.split('\n');
let changedFiles = [];
for (const line of diffs) {
const match = line.match(/diff --git a\/(.*?) b\/(.*?)$/);
if (match) {
const filePath = match[2];
const ext = '.' + filePath.split('.').pop().toLowerCase();
if (codeExtensions.includes(ext)) {
changedFiles.push({ path: filePath, extension: ext, ... });
}
}
}
return changedFiles.map(f => ({ json: f }));
*(Node: Extract Changed Files) *
4. Retrieving File Content
Fetches the raw content of each changed file at the PR commit.
- Node: Get File Content
- Type:
n8n-nodes-base.bitbucket - Operation:
getContent - Inputs:
workspace,repositoryId,filePath,ref
*(Node snippet: Get File Content) *
5. Preparing Source Code for AI
Transforms Bitbucket response into a standardized payload for DocuWriter.ai.
// Prepare Source Code
const fileContent = $json.body;
const filePath = $json.path;
const prData = $('Bitbucket PR Webhook').first().json.pullrequest;
return {
json: {
sourceCode: fileContent,
fileName: filePath.split('/').pop(),
filePath: filePath,
language: $json.extension.replace('.', ''),
pullRequest: {
id: prData.id,
title: prData.title,
author: prData.author.display_name,
sourceBranch: prData.source.branch.name,
targetBranch: prData.destination.branch.name,
repository: prData.destination.repository.full_name
}
}
};
*(Node: Prepare Source Code) *
6. Generating Documentation & Test Suggestions
Branches into two parallel DocuWriter.ai nodes:
| Node Name | Generation Type | Mode | Instructions |
|---|---|---|---|
| Generate Documentation | Documentation | accurate | Focus on functionality, dependencies, and PR context. |
| Generate Test Suggestions | Tests | fast | Emphasize edge cases and scenarios for pull request validation. |
{
"sourceCode": "={{ $json.sourceCode }}",
"generationType": "Documentation",
"mode": "accurate",
"additionalInstructions": "Focus on PR #{{ $json.pullRequest.id }} changes..."
}
*(DocuWriter.ai node definitions) & *
7. Aggregating Results
Collects outputs from both AI nodes into a single list.
- Node: Aggregate Results
- Type:
n8n-nodes-base.itemLists - Operation:
aggregateAllItemData
8. Formatting and Posting the PR Comment
Combines documentation and test suggestions into a Markdown PR comment, then posts it back to Bitbucket.
// Format PR Comment
const items = $input.all();
const pr = items[0].json.pullRequest;
let docs = '', tests = '';
for (const it of items) {
const content = it.json.generatedContent;
if (content.toLowerCase().includes('test')) {
tests += `\n### Test Suggestions for \`${it.json.fileName}\`\n\n${content}\n\n---\n`;
} else {
docs += `\n### Documentation for \`${it.json.fileName}\`\n\n${content}\n\n---\n`;
}
}
const comment = `# ๐ Pull Request Analysis
**Generated by DocuWriter.ai**
## ๐ Code Documentation
${docs}
## ๐งช Testing Recommendations
${tests}
## ๐ PR Summary
- Files Analyzed: ${items.length}
- Branch: \`${pr.sourceBranch}\` โ \`${pr.targetBranch}\`
- Author: ${pr.author}
*Generated on ${new Date().toISOString().split('T')[0]}*`;
return { json: { comment, pullRequestId: pr.id, ... } };
*(Node: Format PR Comment) *
- Node: Post PR Comment
- Type:
n8n-nodes-base.bitbucket - Operation:
addComment
9. Optional Slack Notification ๐
Notifies your team about completed PR analysis.
- Node: Notify Slack
- Type:
n8n-nodes-base.slack - Channel: e.g.
#development - Message:
- Title:
๐ PR Analysis Complete - Fields: Author, Branch, PR link
- Title:
*(Node snippet) *
10. Webhook Responses
Ensures Bitbucket receives timely HTTP responses:
| Node Name | Type | On Event |
|---|---|---|
| Webhook Response | n8n-nodes-base.respondToWebhook |
PR analysis completed |
| Webhook Response (Ignored) | n8n-nodes-base.respondToWebhook |
Non-creation events |
โญ Adaptation Tips
- Adjust filters for other PR actions (e.g., updates, merges).
- Extend additionalInstructions for more context.
- Integrate with other chat tools (Microsoft Teams, Discord).
- Swap Bitbucket nodes for GitHub/GitLab using analogous patterns.
Updated