Backups de WorkFlows en GitHub
Itops
JFC
(@JF_Car)
El tiempo que dedicamos a la construcción y mantenimiento de nuestros WorkFlows puede ser muy importante, en caso de desastre, es importante poder recuperar estos workflows. --- Creditos a https://t.me/P4bl0C
Creado: 2024-11-27
22 nodos
Instrucciones
Editar Workflow
Visualización del Workflow
{
"meta": {
"instanceId": "08b7c45495aaa3612df600822e44f3d213ac41891a4f0921909837df27d3b120"
},
"nodes": [
{
"parameters": {
"dataType": "string",
"value1": "={{$json[\"github_status\"]}}",
"rules": {
"rules": [
{
"value2": "same"
},
{
"value2": "different",
"output": 1
},
{
"value2": "new",
"output": 2
}
]
}
},
"name": "github_status",
"type": "n8n-nodes-base.switch",
"position": [
1600,
960
],
"typeVersion": 1,
"id": "4db8911b-2915-4145-be2f-78bad0af8b56"
},
{
"parameters": {
"values": {
"string": [
{
"name": "repo.owner",
"value": "GuruYosh"
},
{
"name": "repo.name",
"value": "Backups"
},
{
"name": "repo.path",
"value": "N8N/workflows/"
}
]
},
"options": {}
},
"name": "Globals",
"type": "n8n-nodes-base.set",
"position": [
400,
980
],
"typeVersion": 1,
"id": "6fb902ab-5cb4-4b9c-b086-6685f66cd5b6"
},
{
"parameters": {},
"id": "70c2d47e-2644-4d16-aaf8-c1804e2fe071",
"name": "The End",
"type": "n8n-nodes-base.noOp",
"typeVersion": 1,
"position": [
2660,
1140
]
},
{
"parameters": {
"filters": {},
"requestOptions": {}
},
"id": "9dde67a2-1ec5-401a-b1b5-a0a37b6d04db",
"name": "n8n",
"type": "n8n-nodes-base.n8n",
"typeVersion": 1,
"position": [
580,
980
],
"credentials": {
"n8nApi": {
"id": "35",
"name": "N8N-Silica JF"
}
}
},
{
"parameters": {
"authentication": "oAuth2",
"resource": "file",
"operation": "get",
"owner": "={{$node[\"Globals\"].json[\"repo\"][\"owner\"]}}",
"repository": "={{$node[\"Globals\"].json[\"repo\"][\"name\"]}}",
"filePath": "={{$node[\"Globals\"].json[\"repo\"][\"path\"]}}{{ $json.id }}_{{$json[\"name\"]}}.json",
"asBinaryProperty": false,
"additionalParameters": {}
},
"name": "Buscar en GitHub",
"type": "n8n-nodes-base.github",
"position": [
1040,
820
],
"typeVersion": 1,
"alwaysOutputData": true,
"id": "5a910989-b0b4-43df-8f2d-d23b3265b2d7",
"retryOnFail": true,
"maxTries": 5,
"waitBetweenTries": 5000,
"credentials": {
"githubOAuth2Api": {
"id": "26",
"name": "JF GitHub n8n-silica"
}
},
"continueOnFail": true
},
{
"parameters": {},
"name": "Fusiona Datos",
"type": "n8n-nodes-base.merge",
"position": [
1260,
960
],
"typeVersion": 1,
"id": "a3ea516f-3dde-4d5e-baa6-41f171307d33"
},
{
"parameters": {
"batchSize": 1,
"options": {}
},
"name": "Lotes por WF",
"type": "n8n-nodes-base.splitInBatches",
"position": [
820,
980
],
"typeVersion": 1,
"id": "e7a0cfd5-7da4-4444-bcec-2a39ed041d12"
},
{
"parameters": {},
"name": "Diferente",
"type": "n8n-nodes-base.noOp",
"position": [
1920,
1000
],
"typeVersion": 1,
"id": "c8417d36-7b52-45d5-8347-9701ed4f51e8"
},
{
"parameters": {
"authentication": "oAuth2",
"resource": "file",
"operation": "edit",
"owner": "={{$node[\"Globals\"].json[\"repo\"][\"owner\"]}}",
"repository": "={{$node[\"Globals\"].json[\"repo\"][\"name\"]}}",
"filePath": "={{$node[\"Globals\"].json[\"repo\"][\"path\"]}}{{ $node[\"Lotes por WF\"].json.id }}_{{$node[\"Lotes por WF\"].json[\"name\"]}}.json",
"fileContent": "={{$node[\"Comparar WF con GitHub\"].json[\"n8n_data_stringy\"]}}",
"commitMessage": "=[N8N Backup] [{{$node[\"Comparar WF con GitHub\"].json[\"estado\"]}}] {{ $json.id }}_{{$node[\"Lotes por WF\"].json[\"name\"]}}.json ({{$node[\"Comparar WF con GitHub\"].json[\"github_status\"]}})"
},
"name": "Edita en GitHub",
"type": "n8n-nodes-base.github",
"position": [
2160,
1000
],
"typeVersion": 1,
"id": "49a4e7b3-2930-44b2-ac69-7d8cebb7311c",
"retryOnFail": true,
"maxTries": 5,
"waitBetweenTries": 5000,
"credentials": {
"githubOAuth2Api": {
"id": "26",
"name": "JF GitHub n8n-silica"
}
}
},
{
"parameters": {
"authentication": "oAuth2",
"resource": "file",
"owner": "={{$node[\"Globals\"].json[\"repo\"][\"owner\"]}}",
"repository": "={{$node[\"Globals\"].json[\"repo\"][\"name\"]}}",
"filePath": "={{$node[\"Globals\"].json[\"repo\"][\"path\"]}}{{ $node[\"Lotes por WF\"].json.id }}_{{$node[\"Lotes por WF\"].json[\"name\"]}}.json",
"fileContent": "={{ $json[\"n8n_data_stringy\"] }}",
"commitMessage": "=[N8N Backup] [{{$node[\"Comparar WF con GitHub\"].json[\"estado\"]}}] {{ $node[\"Lotes por WF\"].json.id }}_{{$node[\"Lotes por WF\"].json[\"name\"]}}.json ({{$node[\"Comparar WF con GitHub\"].json[\"github_status\"]}})"
},
"name": "Crea en GitHub",
"type": "n8n-nodes-base.github",
"position": [
2160,
1160
],
"typeVersion": 1,
"id": "6b32fc2b-c23b-438e-b3e7-552f1db0a6b9",
"retryOnFail": true,
"maxTries": 5,
"waitBetweenTries": 5000,
"credentials": {
"githubOAuth2Api": {
"id": "26",
"name": "JF GitHub n8n-silica"
}
}
},
{
"parameters": {
"conditions": {
"boolean": [
{
"value1": true,
"value2": "={{$node[\"Lotes por WF\"].context[\"noItemsLeft\"]}}"
}
]
}
},
"name": "Bucle de Control para lote",
"type": "n8n-nodes-base.if",
"position": [
2400,
1160
],
"typeVersion": 1,
"id": "5b95ae7b-2d44-4ce6-83ac-996387735c7c"
},
{
"parameters": {
"content": "# INIT\n\nDatos repositorio de **GitHub**",
"height": 621.3144785981041,
"width": 331.5593220338984
},
"id": "8e2a51d8-2819-4ed4-954e-c91ae322d844",
"name": "Note",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
180,
748.6032605573109
]
},
{
"parameters": {
"content": "# N8N\nTrae todos los WF de n8n",
"height": 620.3050847457627,
"width": 161.28813559322032
},
"id": "3e9a51b2-7401-4abb-b7ae-6e59f5bc5593",
"name": "Note1",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
540,
747.5254237288137
]
},
{
"parameters": {
"content": "# Bucle para procesar workflows\n#\n#\n#\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\nPor cada workflow:\n- se busca en github si existe y se traen los datos\n- se traen los datos del workflow desde **n8n**\n- se comparan ambos y se evalua",
"height": 622.8135593220339,
"width": 1089.1186440677966
},
"id": "aac77a85-0fdf-42ad-b3f8-73bae1a030b5",
"name": "Note2",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
720,
746.1355932203388
]
},
{
"parameters": {
"content": "# GitHub\n- si es igual no se hace nada\n- si es diferente se edita\n- si es nuevo se crea",
"height": 620.484738330209,
"width": 494.61016949152537
},
"id": "21ba9f88-7de3-445a-a664-068836da85b9",
"name": "Note3",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
1840,
741.355013173701
]
},
{
"parameters": {
"content": "# Control de bucle\nProceso por lotes",
"height": 618.0822608445854,
"width": 198.61016949152545
},
"id": "5bbfdab4-5345-4658-ac26-3762a308f35b",
"name": "Note4",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2360,
747.3898305084745
]
},
{
"parameters": {
"content": "# FIN\n\nA tomar por culo bicicleta",
"height": 618.8010971342262,
"width": 256.3050847457627
},
"id": "4f8c00e6-aa1a-4c3a-81a0-9be111e21676",
"name": "Note5",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
2580,
746.7118014581329
]
},
{
"parameters": {
"content": "# BACKUP DE LOS WORKFLOWS DE N8N EN UN REPOSITORIO DE GITHUB\n",
"height": 80,
"width": 1257.1864406779666
},
"id": "d977f050-54d0-469c-8d6c-bc6adc2ffee6",
"name": "Note6",
"type": "n8n-nodes-base.stickyNote",
"typeVersion": 1,
"position": [
540,
640
]
},
{
"parameters": {},
"name": "Nuevo",
"type": "n8n-nodes-base.noOp",
"position": [
1920,
1160
],
"typeVersion": 1,
"id": "b3a45a8e-c1e6-4d0a-b08c-25550b5c08f3"
},
{
"parameters": {},
"name": "Igual",
"type": "n8n-nodes-base.noOp",
"position": [
2160,
860
],
"typeVersion": 1,
"id": "ec66c9bf-68aa-4ccb-8e74-634536e8ac09"
},
{
"parameters": {
"jsCode": "// Compatibilidad nuevo nodo CODE\n\nlet items = $input.all();\n\nvar statusWF = \"Activo\";\nif (!(items[1].json.active)) { statusWF = \"Parado\"}\nitems[0].json.estado = statusWF;\n\n// File Returned with Content\nif (Object.keys(items[0].json).includes(\"content\")) {\n // Get JSON Objects\n var origWorkflow = eval(\"(\"+Buffer.from(items[0].json.content, 'base64').toString()+\")\");\n \n var n8nWorkflow = (items[1].json);\n var n8nWFActive = (items[1].json.active);\n\n // Order JSON Objects\n var orderedOriginal = {}\n var orderedActual = {}\n \n Object.keys(origWorkflow).sort().forEach(function(key) {\n orderedOriginal[key] = origWorkflow[key];\n });\n \n Object.keys(n8nWorkflow).sort().forEach(function(key) {\n orderedActual[key] = n8nWorkflow[key];\n });\n \n // Determine Difference\n if ( JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual) ) {\n items[0].json.github_status = \"same\";\n items[0].json.content_decoded = orderedOriginal;\n } else {\n items[0].json.github_status = \"different\";\n items[0].json.content_decoded = orderedOriginal;\n items[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);\n }\n// No File Returned / New Workflow\n} else {\n // Order JSON Object\n var n8nWorkflow = (items[1].json);\n var orderedActual = {}\n Object.keys(n8nWorkflow).sort().forEach(function(key) {\n orderedActual[key] = n8nWorkflow[key];\n });\n \n // Proper Formatting\n items[0].json.github_status = \"new\";\n items[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);\n}\n\n// Return Items\nreturn items;"
},
"id": "1bd71a15-8386-4bb7-843f-9ab9b9927096",
"name": "Comparar WF con GitHub",
"type": "n8n-nodes-base.code",
"typeVersion": 1,
"position": [
1420,
960
]
},
{
"parameters": {
"triggerTimes": {
"item": [
{
"hour": 5
}
]
}
},
"name": "Cron 2300",
"type": "n8n-nodes-base.cron",
"position": [
200,
980
],
"typeVersion": 1,
"id": "f80a1fd7-ef29-41c8-b378-7ea022f23691"
}
],
"connections": {
"github_status": {
"main": [
[
{
"node": "Igual",
"type": "main",
"index": 0
}
],
[
{
"node": "Diferente",
"type": "main",
"index": 0
}
],
[
{
"node": "Nuevo",
"type": "main",
"index": 0
}
]
]
},
"Globals": {
"main": [
[
{
"node": "n8n",
"type": "main",
"index": 0
}
]
]
},
"n8n": {
"main": [
[
{
"node": "Lotes por WF",
"type": "main",
"index": 0
}
]
]
},
"Buscar en GitHub": {
"main": [
[
{
"node": "Fusiona Datos",
"type": "main",
"index": 0
}
]
]
},
"Fusiona Datos": {
"main": [
[
{
"node": "Comparar WF con GitHub",
"type": "main",
"index": 0
}
]
]
},
"Lotes por WF": {
"main": [
[
{
"node": "Buscar en GitHub",
"type": "main",
"index": 0
},
{
"node": "Fusiona Datos",
"type": "main",
"index": 1
}
]
]
},
"Diferente": {
"main": [
[
{
"node": "Edita en GitHub",
"type": "main",
"index": 0
}
]
]
},
"Edita en GitHub": {
"main": [
[
{
"node": "Bucle de Control para lote",
"type": "main",
"index": 0
}
]
]
},
"Crea en GitHub": {
"main": [
[
{
"node": "Bucle de Control para lote",
"type": "main",
"index": 0
}
]
]
},
"Bucle de Control para lote": {
"main": [
[
{
"node": "The End",
"type": "main",
"index": 0
}
],
[
{
"node": "Lotes por WF",
"type": "main",
"index": 0
}
]
]
},
"Nuevo": {
"main": [
[
{
"node": "Crea en GitHub",
"type": "main",
"index": 0
}
]
]
},
"Igual": {
"main": [
[
{
"node": "Bucle de Control para lote",
"type": "main",
"index": 0
}
]
]
},
"Comparar WF con GitHub": {
"main": [
[
{
"node": "github_status",
"type": "main",
"index": 0
}
]
]
},
"Cron 2300": {
"main": [
[
{
"node": "Globals",
"type": "main",
"index": 0
}
]
]
}
},
"pinData": {}
}