Flujo de trabajo de n8n para copias de seguridad diarias automáticas en un repositorio de GitLab
Este es unEngineering, DevOpsflujo de automatización del dominio deautomatización que contiene 19 nodos.Utiliza principalmente nodos como N8n, Set, Code, Gitlab, Switch. Workflow n8n para copia de seguridad diaria automática en un repositorio de GitLab
- •Personal Access Token de GitLab
Nodos utilizados (19)
Categoría
{
"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": "Interruptor",
"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": "Disparador programado",
"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
}
]
]
}
}
}¿Cómo usar este flujo de trabajo?
Copie el código de configuración JSON de arriba, cree un nuevo flujo de trabajo en su instancia de n8n y seleccione "Importar desde JSON", pegue la configuración y luego modifique la configuración de credenciales según sea necesario.
¿En qué escenarios es adecuado este flujo de trabajo?
Avanzado - Ingeniería, DevOps
¿Es de pago?
Este flujo de trabajo es completamente gratuito, puede importarlo y usarlo directamente. Sin embargo, tenga en cuenta que los servicios de terceros utilizados en el flujo de trabajo (como la API de OpenAI) pueden requerir un pago por su cuenta.
Flujos de trabajo relacionados recomendados
Akhil Varma Gadiraju
@akhilv7Compartir este flujo de trabajo