Workflow n8n pour une sauvegarde automatique quotidienne vers un dépôt GitLab
Avancé
Ceci est unEngineering, DevOpsworkflow d'automatisation du domainecontenant 19 nœuds.Utilise principalement des nœuds comme N8n, Set, Code, Gitlab, Switch. Workflow n8n pour la sauvegarde quotidienne automatisée dans un dépôt GitLab
Prérequis
- •Personal Access Token GitLab
Nœuds utilisés (19)
Catégorie
Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
"meta": {
"instanceId": "7d8066d2f56a07000fe7d753d3eeabf0ecdf68413466f30d10afe0906f058427",
"templateCredsSetupCompleted": true
},
"nodes": [
{
"id": "91bb5db7-0bd4-4a17-859a-672515048d9e",
"name": "Globals",
"type": "n8n-nodes-base.set",
"position": [
-2060,
205.5
],
"parameters": {
"fields": {
"values": [
{
"name": "repo.owner",
"stringValue": "={{ $json.owner.username }}"
},
{
"name": "repo.name",
"stringValue": "={{ $json.name }}"
},
{
"name": "repo.branch",
"stringValue": "={{ $json.default_branch }}"
},
{
"name": "repo.path",
"stringValue": "={{ $json.web_url }}"
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "b8ed50c3-3b78-428a-997b-9efc109df984",
"name": "Result",
"type": "n8n-nodes-base.noOp",
"position": [
-1400,
5.5
],
"parameters": {},
"typeVersion": 1
},
{
"id": "04b6d718-d3bd-481c-8b7b-5b1188df2edf",
"name": "Current workflow",
"type": "n8n-nodes-base.noOp",
"position": [
-1400,
205.5
],
"parameters": {},
"typeVersion": 1
},
{
"id": "5db89b68-76d1-461d-a49b-955373359830",
"name": "Loop Over Workflows",
"type": "n8n-nodes-base.splitInBatches",
"position": [
-1620,
205.5
],
"parameters": {
"options": {}
},
"typeVersion": 3
},
{
"id": "8944cbfa-e659-4683-a11f-c3510d0b34dc",
"name": "Get file",
"type": "n8n-nodes-base.gitlab",
"onError": "continueErrorOutput",
"position": [
-1180,
205.5
],
"parameters": {
"owner": "={{ $('Globals').first().json.repo.owner }}",
"filePath": "={{ $json.id }}.json",
"resource": "file",
"operation": "get",
"repository": "={{ $('Globals').first().json.repo.name }}",
"binaryPropertyName": "file-from-gitlab",
"additionalParameters": {
"reference": "={{ $('Globals').first().json.repo.branch }}"
}
},
"credentials": {
"gitlabApi": {
"id": "6NLmdaoq2NsT324y",
"name": "GitLab account"
}
},
"executeOnce": true,
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "10f24280-16ce-406c-b5fe-2d715ed66b0c",
"name": "File status",
"type": "n8n-nodes-base.code",
"position": [
-520,
205.5
],
"parameters": {
"mode": "runOnceForEachItem",
"jsCode": "var item = $json;\n\n// Check first if is error\nif (item.error) {\n if (\"The resource you are requesting could not be found\" == item.error) {\n item[\"status\"] = \"new\";\n } else {\n item[\"status\"] = \"error\";\n }\n return $input.item;\n}\n\n// If not error check file with saved version\nvar workflowFromN8n = item[\"workflow-from-n8n\"];\nvar workflowFromGitlab = item[\"workflow-from-gitlab\"];\nvar areEquals = objectsAreEquals(workflowFromN8n, workflowFromGitlab);\n\nif (areEquals) {\n item[\"status\"] = \"same\";\n} else {\n item[\"status\"] = \"diff\";\n}\n\n// Return Item\nreturn item;\n\n/**\n * Compare to objects\n * @param object1 \n * @param object2 \n * @returns true if the are the same without ignored fields\n */\nfunction objectsAreEquals(object1, object2) {\n const objectKeys1 = Object.keys(object1);\n const objectKeys2 = Object.keys(object2);\n\n // If the numbers of fields are differents, the objects are differents\n if (objectKeys1.length !== objectKeys2.length) {\n return false;\n }\n for (const key of objectKeys1) {\n // Define some fields to be ignored\n var ignoreCurrent = false;\n switch (key) {\n case \"updatedAt\": // Changed because workflow change... not usefull\n case \"global\": // changed for running reasons, no need to check\n ignoreCurrent = true;\n }\n\n // If it's not an ignored field\n if (!ignoreCurrent) {\n const value1 = object1[key];\n const value2 = object2[key];\n const isBothAreObjects = isObject(value1) && isObject(value2);\n\n // If it's objects recursive check\n if (isBothAreObjects && !objectsAreEquals(value1, value2)) {\n return false;\n }\n\n // If it's not objects, just compare values\n if (!isBothAreObjects && value1 != value2) {\n return false;\n }\n }\n }\n return true;\n}\n\n/**\n * Tool function to determine if an parameter is an object\n * @param object \n * @returns \n */\nfunction isObject(object) {\n return object !== null && typeof object === \"object\";\n}\n"
},
"typeVersion": 2
},
{
"id": "548ae4ec-3d45-4880-a9a0-2abe48831e88",
"name": "Status error",
"type": "n8n-nodes-base.set",
"position": [
140,
80.5
],
"parameters": {
"fields": {
"values": [
{
"name": "name",
"stringValue": "={{ $('Current workflow').item.json.name }}"
},
{
"name": "status",
"stringValue": "=Error : {{ $json.error }}"
}
]
},
"include": "none",
"options": {}
},
"typeVersion": 3.2
},
{
"id": "06b4fe3e-ca4b-4ad5-a2dc-ca68ac74e7e5",
"name": "End Loop",
"type": "n8n-nodes-base.noOp",
"position": [
360,
370
],
"parameters": {},
"typeVersion": 1
},
{
"id": "1b5df0b1-9f85-422c-9ad7-4020086d49a1",
"name": "Create file",
"type": "n8n-nodes-base.gitlab",
"onError": "continueErrorOutput",
"position": [
-80,
-119.5
],
"parameters": {
"owner": "={{ $('Globals').first().json.repo.owner }}",
"branch": "={{ $('Globals').first().json.repo.branch }}",
"filePath": "={{ $json.id }}.json",
"resource": "file",
"repository": "={{ $('Globals').first().json.repo.name }}",
"fileContent": "={{ JSON.stringify($('Current workflow').item.json, null, 4) }}",
"commitMessage": "=Create file for workflow {{ $('Current workflow').item.json.name }}",
"additionalParameters": {
"author": {
"name": "n8n",
"email": "akhil@nuevesolutions.com"
}
}
},
"credentials": {
"gitlabApi": {
"id": "6NLmdaoq2NsT324y",
"name": "GitLab account"
}
},
"executeOnce": true,
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "06c2150b-491c-4b44-9b43-88b1e1df5793",
"name": "Extract From File",
"type": "n8n-nodes-base.extractFromFile",
"position": [
-960,
105.5
],
"parameters": {
"options": {},
"operation": "fromJson",
"destinationKey": "workflow-from-gitlab",
"binaryPropertyName": "file-from-gitlab"
},
"typeVersion": 1
},
{
"id": "6a9b5a29-6874-433c-849a-97e37bfba40d",
"name": "Commutateur",
"type": "n8n-nodes-base.switch",
"position": [
-300,
184.5
],
"parameters": {
"rules": {
"values": [
{
"outputKey": "new",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "9cd88022-6d97-409f-a37e-ae6b02b6269b",
"operator": {
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "new"
}
]
},
"renameOutput": true
},
{
"outputKey": "same",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "0ff6e053-e89d-49fa-b8c8-3a51ffe016d8",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "same"
}
]
},
"renameOutput": true
},
{
"outputKey": "diff",
"conditions": {
"options": {
"version": 1,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "b6b954c3-e74c-4f60-8e9e-ac79d4b741f3",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "diff"
}
]
},
"renameOutput": true
}
]
},
"options": {
"fallbackOutput": "extra",
"renameFallbackOutput": "error"
}
},
"typeVersion": 3
},
{
"id": "84a7f4b9-b76e-41ee-8413-26fb095627a8",
"name": "New file version",
"type": "n8n-nodes-base.gitlab",
"onError": "continueErrorOutput",
"position": [
-80,
280.5
],
"parameters": {
"owner": "={{ $('Globals').first().json.repo.owner }}",
"branch": "={{ $('Globals').first().json.repo.branch }}",
"filePath": "={{ $json['workflow-from-n8n'].id }}.json",
"resource": "file",
"operation": "edit",
"repository": "={{ $('Globals').first().json.repo.name }}",
"fileContent": "={{ JSON.stringify($json['workflow-from-n8n'], null, 4) }}",
"commitMessage": "=New file version for workflow {{ $json['workflow-from-n8n'].name }}"
},
"credentials": {
"gitlabApi": {
"id": "6NLmdaoq2NsT324y",
"name": "GitLab account"
}
},
"executeOnce": true,
"typeVersion": 1,
"alwaysOutputData": false
},
{
"id": "ec89cb60-e144-4b77-bea8-e32122a32ea1",
"name": "Error output to normal output",
"type": "n8n-nodes-base.noOp",
"position": [
-740,
520
],
"parameters": {},
"typeVersion": 1
},
{
"id": "f11d589b-ad66-4347-b9e8-6e56f003de5c",
"name": "Status diff",
"type": "n8n-nodes-base.set",
"position": [
140,
330.5
],
"parameters": {
"fields": {
"values": [
{
"name": "name",
"stringValue": "={{ $('Current workflow').item.json.name }}"
},
{
"name": "status",
"stringValue": "diff"
}
]
},
"include": "none",
"options": {}
},
"typeVersion": 3.2
},
{
"id": "67a1dfc1-f35e-4854-a61b-f9ba947d6371",
"name": "Status same",
"type": "n8n-nodes-base.set",
"position": [
140,
530.5
],
"parameters": {
"fields": {
"values": [
{
"name": "name",
"stringValue": "={{ $('Current workflow').item.json.name }}"
},
{
"name": "status",
"stringValue": "same"
}
]
},
"include": "none",
"options": {}
},
"typeVersion": 3.2
},
{
"id": "d788fe7a-c713-426b-b15b-9e3fb806c8f4",
"name": "Retrieve all workflows",
"type": "n8n-nodes-base.n8n",
"position": [
-1840,
205.5
],
"parameters": {
"filters": {},
"requestOptions": {}
},
"credentials": {
"n8nApi": {
"id": "Hp7Xh2HuDWQAiZR6",
"name": "n8n account"
}
},
"typeVersion": 1
},
{
"id": "19cd98bf-f055-43af-a86b-d0d77a331606",
"name": "Save each version in a different field",
"type": "n8n-nodes-base.set",
"position": [
-740,
105.5
],
"parameters": {
"fields": {
"values": [
{
"name": "workflow-from-gitlab",
"type": "objectValue",
"objectValue": "={{ $json['workflow-from-gitlab'] }}"
},
{
"name": "workflow-from-n8n",
"type": "objectValue",
"objectValue": "={{ $('Current workflow').item.json }}"
}
]
},
"options": {}
},
"typeVersion": 3.2
},
{
"id": "5b62ca2a-af1b-4d47-8750-526efe24949d",
"name": "Déclencheur planifié",
"type": "n8n-nodes-base.scheduleTrigger",
"position": [
-2500,
205.5
],
"parameters": {
"rule": {
"interval": [
{}
]
}
},
"typeVersion": 1.2
},
{
"id": "e0db3d90-cdbe-4854-968c-2bde224dd759",
"name": "GitLab",
"type": "n8n-nodes-base.gitlab",
"position": [
-2280,
205.5
],
"parameters": {
"owner": "{{change this to owner eg: akhil}}",
"resource": "repository",
"operation": "get",
"repository": "n8n-workflows"
},
"credentials": {
"gitlabApi": {
"id": "6NLmdaoq2NsT324y",
"name": "GitLab account"
}
},
"typeVersion": 1
}
],
"pinData": {},
"connections": {
"e0db3d90-cdbe-4854-968c-2bde224dd759": {
"main": [
[
{
"node": "91bb5db7-0bd4-4a17-859a-672515048d9e",
"type": "main",
"index": 0
}
]
]
},
"Switch": {
"main": [
[
{
"node": "1b5df0b1-9f85-422c-9ad7-4020086d49a1",
"type": "main",
"index": 0
}
],
[
{
"node": "67a1dfc1-f35e-4854-a61b-f9ba947d6371",
"type": "main",
"index": 0
}
],
[
{
"node": "84a7f4b9-b76e-41ee-8413-26fb095627a8",
"type": "main",
"index": 0
}
],
[
{
"node": "548ae4ec-3d45-4880-a9a0-2abe48831e88",
"type": "main",
"index": 0
}
]
]
},
"91bb5db7-0bd4-4a17-859a-672515048d9e": {
"main": [
[
{
"node": "d788fe7a-c713-426b-b15b-9e3fb806c8f4",
"type": "main",
"index": 0
}
]
]
},
"06b4fe3e-ca4b-4ad5-a2dc-ca68ac74e7e5": {
"main": [
[
{
"node": "5db89b68-76d1-461d-a49b-955373359830",
"type": "main",
"index": 0
}
]
]
},
"8944cbfa-e659-4683-a11f-c3510d0b34dc": {
"main": [
[
{
"node": "06c2150b-491c-4b44-9b43-88b1e1df5793",
"type": "main",
"index": 0
}
],
[
{
"node": "ec89cb60-e144-4b77-bea8-e32122a32ea1",
"type": "main",
"index": 0
}
]
]
},
"1b5df0b1-9f85-422c-9ad7-4020086d49a1": {
"main": [
[],
[
{
"node": "548ae4ec-3d45-4880-a9a0-2abe48831e88",
"type": "main",
"index": 0
}
]
]
},
"10f24280-16ce-406c-b5fe-2d715ed66b0c": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"f11d589b-ad66-4347-b9e8-6e56f003de5c": {
"main": [
[
{
"node": "06b4fe3e-ca4b-4ad5-a2dc-ca68ac74e7e5",
"type": "main",
"index": 0
}
]
]
},
"67a1dfc1-f35e-4854-a61b-f9ba947d6371": {
"main": [
[
{
"node": "06b4fe3e-ca4b-4ad5-a2dc-ca68ac74e7e5",
"type": "main",
"index": 0
}
]
]
},
"548ae4ec-3d45-4880-a9a0-2abe48831e88": {
"main": [
[
{
"node": "06b4fe3e-ca4b-4ad5-a2dc-ca68ac74e7e5",
"type": "main",
"index": 0
}
]
]
},
"04b6d718-d3bd-481c-8b7b-5b1188df2edf": {
"main": [
[
{
"node": "8944cbfa-e659-4683-a11f-c3510d0b34dc",
"type": "main",
"index": 0
}
]
]
},
"84a7f4b9-b76e-41ee-8413-26fb095627a8": {
"main": [
[
{
"node": "f11d589b-ad66-4347-b9e8-6e56f003de5c",
"type": "main",
"index": 0
}
],
[
{
"node": "548ae4ec-3d45-4880-a9a0-2abe48831e88",
"type": "main",
"index": 0
}
]
]
},
"Schedule Trigger": {
"main": [
[
{
"node": "e0db3d90-cdbe-4854-968c-2bde224dd759",
"type": "main",
"index": 0
}
]
]
},
"06c2150b-491c-4b44-9b43-88b1e1df5793": {
"main": [
[
{
"node": "19cd98bf-f055-43af-a86b-d0d77a331606",
"type": "main",
"index": 0
}
]
]
},
"5db89b68-76d1-461d-a49b-955373359830": {
"main": [
[
{
"node": "b8ed50c3-3b78-428a-997b-9efc109df984",
"type": "main",
"index": 0
}
],
[
{
"node": "04b6d718-d3bd-481c-8b7b-5b1188df2edf",
"type": "main",
"index": 0
}
]
]
},
"d788fe7a-c713-426b-b15b-9e3fb806c8f4": {
"main": [
[
{
"node": "5db89b68-76d1-461d-a49b-955373359830",
"type": "main",
"index": 0
}
]
]
},
"ec89cb60-e144-4b77-bea8-e32122a32ea1": {
"main": [
[
{
"node": "10f24280-16ce-406c-b5fe-2d715ed66b0c",
"type": "main",
"index": 0
}
]
]
},
"19cd98bf-f055-43af-a86b-d0d77a331606": {
"main": [
[
{
"node": "10f24280-16ce-406c-b5fe-2d715ed66b0c",
"type": "main",
"index": 0
}
]
]
}
}
}Foire aux questions
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, DevOps
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
Workflow n8n avancé synchronisé avec GitHub
Sauvegarde automatisée des workflows avec une détection intelligente des changements via GitHub
If
N8n
Set
+
If
N8n
Set
38 NœudsMaksym Brashenko
DevOps
Sauvegarde automatisée des workflows n8n vers GitHub avec suivi des suppressions
Sauvegarde automatisée des workflows n8n vers GitHub et suivi des suppressions
If
N8n
Set
+
If
N8n
Set
31 NœudsMarcial Ambriz
DevOps
Tableau de bord de synchronisation GitHub - V2
Tableau de versionning des workflows GitHub avec historique de commits et fonction de rollback
If
N8n
Set
+
If
N8n
Set
94 NœudsEduard
DevOps
[Modèle] AI Pet Shop v8
🐶 Assistant de magasin de pets IA - Intégration de GPT-4o, Google Calendar et WhatsApp/Instagram/Facebook
If
N8n
Set
+
If
N8n
Set
244 NœudsAmanda Benks
Ventes
Flux de travail GitHub dynamique
🔄 Workflow Repos8r : interface utilisateur de contrôle de version GitHub pour les flux de travail n8n
N8n
Set
Code
+
N8n
Set
Code
44 NœudsRealSimple Solutions
Ingénierie
Agent IA restaurant [Modèle]
🤖 Assistant IA pour WhatsApp, Instagram et Messenger
If
N8n
Set
+
If
N8n
Set
239 NœudsAmanda Benks
Autres
Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds19
Catégorie2
Types de nœuds9
Description de la difficulté
Auteur
Akhil Varma Gadiraju
@akhilv7Liens externes
Voir sur n8n.io →
Partager ce workflow