LintBot : Votre assistant automatisé de qualité de code
Ceci est unEngineering, AIworkflow d'automatisation du domainecontenant 20 nœuds.Utilise principalement des nœuds comme Set, Code, Webhook, Aggregate, HttpRequest, combinant la technologie d'intelligence artificielle pour une automatisation intelligente. Automatisation des vérifications de code GitHub PR et de la réparation automatique avec Google Gemini AI
- •Point de terminaison HTTP Webhook (généré automatiquement par n8n)
- •Peut nécessiter les informations d'identification d'authentification de l'API cible
- •Clé API Google Gemini
Nœuds utilisés (20)
Catégorie
{
"id": "mfAxsn2XqfEzDtYr",
"meta": {
"instanceId": "24ca526572eca60ee26bbee4ba7087b1023a6874af4ebeed61b2d126e50e531b",
"templateCredsSetupCompleted": true
},
"name": "LintBot: Your Automated Code Quality Assistant",
"tags": [],
"nodes": [
{
"id": "8dedfb4b-d477-4fa5-9a9b-68b74450d1fe",
"name": "Écouter le Déclencheur du Workflow Github",
"type": "n8n-nodes-base.webhook",
"position": [
-1040,
-540
],
"webhookId": "1da5a6e1-9453-4a65-bbac-a1fed633f6ad",
"parameters": {
"path": "1da5a6e1-9453-4a65-bbac-a1fed633f6ad",
"options": {
"responseHeaders": {
"entries": [
{
"name": "Content-Type",
"value": "application/json"
}
]
}
},
"responseMode": "responseNode"
},
"typeVersion": 1
},
{
"id": "4bec8f3a-5670-4fe5-916f-b7fab3165880",
"name": "Agent IA",
"type": "@n8n/n8n-nodes-langchain.agent",
"position": [
1780,
-580
],
"parameters": {
"text": "=<files>\n{{ JSON.stringify($json.data) }}\n</files>",
"options": {
"systemMessage": "=You are an expert at code linting. Your job is to receive a JSON-formatted request with various file paths and the code inside each file.\n\nYou will:\n\n1. Look for and fix any linting issues in the files.\n2. First, check if a branch exists and if, create a new branch using the name {{ $('Get PR GitHub Branch').item.json.head.ref }}-linting-fix. If so, use the existing branch.\n3. Commit the new files with fixes to the branch.\n4. Create a PR from that branch with the name: \"Linting fixes for PR:{{ $('Listen for Trigger from Github Workflow').item.json.pull_request_number }}\""
},
"promptType": "define"
},
"typeVersion": 1.9
},
{
"id": "0e043c94-5b69-41f5-9f27-9dd5ea45a628",
"name": "Répondre à Webhook",
"type": "n8n-nodes-base.respondToWebhook",
"position": [
2200,
-660
],
"parameters": {
"options": {},
"respondWith": "allIncomingItems"
},
"typeVersion": 1.2
},
{
"id": "68047540-a8ea-4836-9d5b-3b81515f98fc",
"name": "Obtenir les Fichiers de la PR",
"type": "n8n-nodes-base.httpRequest",
"position": [
360,
-540
],
"parameters": {
"url": "={{ $('Set Common Fields').item.json.gitHubApiBaseEndpointUri }}/pulls/{{ $('Listen for Trigger from Github Workflow').item.json.pull_request_number }}/files",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "29b9cace-ceaa-446c-a547-ac25c4331d5a",
"name": "Obtenir le Contenu des Fichiers",
"type": "n8n-nodes-base.httpRequest",
"position": [
580,
-540
],
"parameters": {
"url": "={{ $json.contents_url }}",
"options": {}
},
"typeVersion": 4.2
},
{
"id": "a8920578-706a-4ed6-8c58-9be88f16420c",
"name": "Convertir Base64 en Fichier Texte",
"type": "n8n-nodes-base.convertToFile",
"position": [
780,
-540
],
"parameters": {
"options": {},
"operation": "toBinary",
"sourceProperty": "content"
},
"typeVersion": 1.1
},
{
"id": "1fccb56b-ca82-4c9b-9ede-f669a97067f6",
"name": "Extraire du Fichier",
"type": "n8n-nodes-base.extractFromFile",
"position": [
980,
-560
],
"parameters": {
"options": {},
"operation": "text"
},
"typeVersion": 1
},
{
"id": "543be972-e489-4ca0-8a43-d77442081016",
"name": "Créer un Objet Code/Chemin de Fichier",
"type": "n8n-nodes-base.set",
"position": [
1200,
-560
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "d18801c8-8c93-4c66-add8-0a5915ac3a6f",
"name": "code",
"type": "string",
"value": "={{ $json.data }}"
},
{
"id": "6da8a116-f59e-481c-a815-acda60e19398",
"name": "filePath",
"type": "string",
"value": "={{ $('Get File Contents').item.json.path }}"
}
]
}
},
"typeVersion": 3.4
},
{
"id": "ac2ac571-5a1c-4f06-b45f-296fc43557c8",
"name": "Collecter Tous les Fichiers Modifiés",
"type": "n8n-nodes-base.aggregate",
"position": [
1440,
-560
],
"parameters": {
"options": {},
"aggregate": "aggregateAllItemData"
},
"typeVersion": 1
},
{
"id": "9062c98b-6937-4411-9a21-6f047084ab78",
"name": "Obtenir la Branche GitHub de la PR",
"type": "n8n-nodes-base.httpRequest",
"position": [
-580,
-520
],
"parameters": {
"url": "={{ $json.gitHubApiBaseEndpointUri }}/pulls/{{ $('Listen for Trigger from Github Workflow').item.json.pull_request_number }}",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"id": "MI5Ul9UqEbdI0RRe",
"name": "GitHub account"
}
},
"typeVersion": 4.2
},
{
"id": "8c9f3d57-b73d-46a1-a7f8-b8ea49fbdbd0",
"name": "Créer un Blob GitHub",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1660,
-120
],
"parameters": {
"url": "={{ $('Set Common Fields').item.json.gitHubApiBaseEndpointUri }}/git/blobs",
"method": "POST",
"options": {},
"sendBody": true,
"authentication": "predefinedCredentialType",
"bodyParameters": {
"parameters": [
{
"name": "content",
"value": "={{ /*n8n-auto-generated-fromAI-override*/ $fromAI('parameters0_Value', ``, 'string') }}"
},
{
"name": "encoding",
"value": "utf-8"
}
]
},
"toolDescription": "Creates a GitHub blob for a file",
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"id": "MI5Ul9UqEbdI0RRe",
"name": "GitHub account"
}
},
"typeVersion": 4.2
},
{
"id": "3bba3645-f54e-46aa-866f-426404581221",
"name": "Créer un Arbre GitHub",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
1880,
-120
],
"parameters": {
"url": "={{ $('Set Common Fields').item.json.gitHubApiBaseEndpointUri }}/git/trees",
"method": "POST",
"options": {},
"jsonBody": "={\n \"base_tree\": \"{{ $('Get Latest Main Branch Tree Hash').item.json.tree.sha }}\",\n \"tree\": {{ $fromAI('json_array_of_files','','string') }}\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Creates a GitHub tree object with one file",
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"id": "MI5Ul9UqEbdI0RRe",
"name": "GitHub account"
}
},
"typeVersion": 4.2
},
{
"id": "26213bce-5117-475c-98a1-926140cdeec4",
"name": "Créer un Commit GitHub",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
2080,
-140
],
"parameters": {
"url": "={{ $('Set Common Fields').item.json.gitHubApiBaseEndpointUri }}/git/commits",
"method": "POST",
"options": {},
"jsonBody": "={\n \"message\": \"{{ $fromAI('message', '', 'string').replace(/\\n/g, '\\\\n') }}\",\n \"tree\": \"{{ $fromAI('treeHash', '', 'string') }}\",\n \"parents\": [\n \"{{ $('Get Latest Main Branch Commit SHA').item.json.object.sha }}\"\n ]\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Creates a commit from the new tree. ",
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"id": "MI5Ul9UqEbdI0RRe",
"name": "GitHub account"
}
},
"typeVersion": 4.2
},
{
"id": "cb6918d1-4345-4f77-8667-c4ae6c790db5",
"name": "Créer une Pull Request",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
2580,
-520
],
"parameters": {
"url": "={{ $('Set Common Fields').item.json.gitHubApiBaseEndpointUri }}/pulls",
"method": "POST",
"options": {},
"jsonBody": "={\n \"title\": \"{{ $fromAI('title','','string') }}\",\n \"head\": \"refs/heads/{{ $fromAI('head','','string') }}\",\n \"base\": \"main\",\n \"body\": \"{{ $fromAI('body','','string') }}\"\n}",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Creates a Pull Request",
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"id": "MI5Ul9UqEbdI0RRe",
"name": "GitHub account"
}
},
"typeVersion": 4.2
},
{
"id": "8b9240b2-e23a-4f49-851a-1810d24f1bf3",
"name": "Créer une Branche",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
2480,
-300
],
"parameters": {
"url": "={{ $('Set Common Fields').item.json.gitHubApiBaseEndpointUri }}/git/refs",
"method": "POST",
"options": {},
"jsonBody": "= {\n \"ref\": \"refs/heads/{{ $fromAI('branch_ref','','string') }}\",\n \"sha\": \"{{ $fromAI('commit_sha','','string') }}\"\n }",
"sendBody": true,
"specifyBody": "json",
"authentication": "predefinedCredentialType",
"toolDescription": "Creates a branch to point to the new commit",
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"id": "MI5Ul9UqEbdI0RRe",
"name": "GitHub account"
}
},
"typeVersion": 4.2
},
{
"id": "ea314631-174f-4d03-a947-0710b2870ed1",
"name": "Obtenir le SHA du Dernier Commit de la Branche Main",
"type": "n8n-nodes-base.httpRequest",
"position": [
-340,
-540
],
"parameters": {
"url": "={{ $('Set Common Fields').item.json.gitHubApiBaseEndpointUri }}/git/ref/heads/main",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"id": "MI5Ul9UqEbdI0RRe",
"name": "GitHub account"
}
},
"typeVersion": 4.2
},
{
"id": "36633281-8335-4381-9393-cb1f64390bee",
"name": "Obtenir le Hash de l'Arbre de la Dernière Branche Main",
"type": "n8n-nodes-base.httpRequest",
"position": [
140,
-540
],
"parameters": {
"url": "={{ $('Set Common Fields').item.json.gitHubApiBaseEndpointUri }}/git/commits/{{ $json.object.sha }}",
"options": {},
"authentication": "predefinedCredentialType",
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"id": "MI5Ul9UqEbdI0RRe",
"name": "GitHub account"
}
},
"typeVersion": 4.2
},
{
"id": "435d5b12-3a71-4dbf-9d5d-97b30b249414",
"name": "Obtenir la Branche",
"type": "n8n-nodes-base.httpRequestTool",
"position": [
2280,
-200
],
"parameters": {
"url": "={{ $('Set Common Fields').item.json.gitHubApiBaseEndpointUri }}/branches/{{ $fromAI('branch_name','','string') }}",
"options": {},
"authentication": "predefinedCredentialType",
"toolDescription": "Get a branch from the GitHub repo",
"nodeCredentialType": "githubApi"
},
"credentials": {
"githubApi": {
"id": "MI5Ul9UqEbdI0RRe",
"name": "GitHub account"
}
},
"typeVersion": 4.2
},
{
"id": "b26415fa-b898-4d79-a7da-8f66451f0747",
"name": "Modèle de Chat Gemini Google",
"type": "@n8n/n8n-nodes-langchain.lmChatGoogleGemini",
"position": [
1500,
-340
],
"parameters": {
"options": {},
"modelName": "models/gemini-2.0-flash"
},
"credentials": {
"googlePalmApi": {
"id": "ARYVKWu9TZzwQ3fB",
"name": "Google Gemini(PaLM) Api account"
}
},
"typeVersion": 1
},
{
"id": "9ec4b763-a3c8-4d5b-a50c-64842038a4ba",
"name": "Définir les Champs Communs",
"type": "n8n-nodes-base.code",
"position": [
-820,
-540
],
"parameters": {
"jsCode": "const commonFields = {\n 'gitHubRepoName': 'my-membership',\n 'gitHubOrgName': 'carved-rock-fitness-gym'\n}\ncommonFields['gitHubApiBaseEndpointUri'] = `https://api.github.com/repos/${commonFields.gitHubOrgName}/${commonFields.gitHubRepoName}`\n\nreturn commonFields"
},
"typeVersion": 2
}
],
"active": false,
"pinData": {
"Listen for Trigger from Github Workflow": [
{
"json": {
"pull_request_number": 204
}
}
]
},
"settings": {
"executionOrder": "v1"
},
"versionId": "17951810-1716-46ae-90bb-d698a6062483",
"connections": {
"4bec8f3a-5670-4fe5-916f-b7fab3165880": {
"main": [
[
{
"node": "0e043c94-5b69-41f5-9f27-9dd5ea45a628",
"type": "main",
"index": 0
}
]
]
},
"435d5b12-3a71-4dbf-9d5d-97b30b249414": {
"ai_tool": [
[
{
"node": "4bec8f3a-5670-4fe5-916f-b7fab3165880",
"type": "ai_tool",
"index": 0
}
]
]
},
"68047540-a8ea-4836-9d5b-3b81515f98fc": {
"main": [
[
{
"node": "29b9cace-ceaa-446c-a547-ac25c4331d5a",
"type": "main",
"index": 0
}
]
]
},
"8b9240b2-e23a-4f49-851a-1810d24f1bf3": {
"ai_tool": [
[
{
"node": "4bec8f3a-5670-4fe5-916f-b7fab3165880",
"type": "ai_tool",
"index": 0
}
]
]
},
"1fccb56b-ca82-4c9b-9ede-f669a97067f6": {
"main": [
[
{
"node": "543be972-e489-4ca0-8a43-d77442081016",
"type": "main",
"index": 0
}
]
]
},
"29b9cace-ceaa-446c-a547-ac25c4331d5a": {
"main": [
[
{
"node": "a8920578-706a-4ed6-8c58-9be88f16420c",
"type": "main",
"index": 0
}
]
]
},
"9ec4b763-a3c8-4d5b-a50c-64842038a4ba": {
"main": [
[
{
"node": "9062c98b-6937-4411-9a21-6f047084ab78",
"type": "main",
"index": 0
}
]
]
},
"8c9f3d57-b73d-46a1-a7f8-b8ea49fbdbd0": {
"ai_tool": [
[
{
"node": "4bec8f3a-5670-4fe5-916f-b7fab3165880",
"type": "ai_tool",
"index": 0
}
]
]
},
"3bba3645-f54e-46aa-866f-426404581221": {
"ai_tool": [
[
{
"node": "4bec8f3a-5670-4fe5-916f-b7fab3165880",
"type": "ai_tool",
"index": 0
}
]
]
},
"cb6918d1-4345-4f77-8667-c4ae6c790db5": {
"ai_tool": [
[
{
"node": "4bec8f3a-5670-4fe5-916f-b7fab3165880",
"type": "ai_tool",
"index": 0
}
]
]
},
"26213bce-5117-475c-98a1-926140cdeec4": {
"ai_tool": [
[
{
"node": "4bec8f3a-5670-4fe5-916f-b7fab3165880",
"type": "ai_tool",
"index": 0
}
]
]
},
"9062c98b-6937-4411-9a21-6f047084ab78": {
"main": [
[
{
"node": "ea314631-174f-4d03-a947-0710b2870ed1",
"type": "main",
"index": 0
}
]
]
},
"b26415fa-b898-4d79-a7da-8f66451f0747": {
"ai_languageModel": [
[
{
"node": "4bec8f3a-5670-4fe5-916f-b7fab3165880",
"type": "ai_languageModel",
"index": 0
}
]
]
},
"ac2ac571-5a1c-4f06-b45f-296fc43557c8": {
"main": [
[
{
"node": "4bec8f3a-5670-4fe5-916f-b7fab3165880",
"type": "main",
"index": 0
}
]
]
},
"a8920578-706a-4ed6-8c58-9be88f16420c": {
"main": [
[
{
"node": "1fccb56b-ca82-4c9b-9ede-f669a97067f6",
"type": "main",
"index": 0
}
]
]
},
"543be972-e489-4ca0-8a43-d77442081016": {
"main": [
[
{
"node": "ac2ac571-5a1c-4f06-b45f-296fc43557c8",
"type": "main",
"index": 0
}
]
]
},
"36633281-8335-4381-9393-cb1f64390bee": {
"main": [
[
{
"node": "68047540-a8ea-4836-9d5b-3b81515f98fc",
"type": "main",
"index": 0
}
]
]
},
"ea314631-174f-4d03-a947-0710b2870ed1": {
"main": [
[
{
"node": "36633281-8335-4381-9393-cb1f64390bee",
"type": "main",
"index": 0
}
]
]
},
"8dedfb4b-d477-4fa5-9a9b-68b74450d1fe": {
"main": [
[
{
"node": "9ec4b763-a3c8-4d5b-a50c-64842038a4ba",
"type": "main",
"index": 0
}
]
]
}
}
}Comment utiliser ce workflow ?
Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.
Dans quelles scénarios ce workflow est-il adapté ?
Avancé - Ingénierie, Intelligence Artificielle
Est-ce payant ?
Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.
Workflows recommandés
Adam Bertram
@adbertramPartager ce workflow