Copia de seguridad de credenciales en GitHub

Avanzado

Este es unDevOpsflujo de automatización del dominio deautomatización que contiene 18 nodos.Utiliza principalmente nodos como Set, Code, Cron, Merge, Github. Respaldar credenciales en GitHub

Requisitos previos
  • Personal Access Token de GitHub

Categoría

Vista previa del flujo de trabajo
Visualización de las conexiones entre nodos, con soporte para zoom y panorámica
Exportar flujo de trabajo
Copie la siguiente configuración JSON en n8n para importar y usar este flujo de trabajo
{
  "meta": {
    "instanceId": "d6b502dfa4d9dd072cdc5c2bb763558661053f651289291352a84403e01b3d1b",
    "templateCredsSetupCompleted": true
  },
  "nodes": [
    {
      "id": "4377c764-07f3-4304-8105-d3f009925917",
      "name": "Al hacer clic en 'ejecutar'",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        1780,
        520
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "10f6ea70-c2cb-4463-972c-e2fdef3e837a",
      "name": "Nota adhesiva",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1339.5461279763795,
        900
      ],
      "parameters": {
        "color": 6,
        "width": 2086.845881354743,
        "height": 750.8363163824032,
        "content": "## Subworkflow"
      },
      "typeVersion": 1
    },
    {
      "id": "d22236c2-578c-400b-b3e5-354498620c39",
      "name": "Retornar",
      "type": "n8n-nodes-base.set",
      "position": [
        3220,
        1100
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8d513345-6484-431f-afb7-7cf045c90f4f",
              "name": "Done",
              "type": "boolean",
              "value": true
            }
          ]
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "943eed85-d4cd-4ec5-b278-d143b0f6bd15",
      "name": "Obtener archivo",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2320,
        980
      ],
      "parameters": {
        "url": "={{ $json.download_url }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "124ebdd7-c2c1-4fec-89d3-596f034e0fe7",
      "name": "Si el archivo es demasiado grande",
      "type": "n8n-nodes-base.if",
      "position": [
        2120,
        1000
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 1,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "45ce825e-9fa6-430c-8931-9aaf22c42585",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.content }}",
              "rightValue": ""
            },
            {
              "id": "9619a55f-7fb1-4f24-b1a7-7aeb82365806",
              "operator": {
                "type": "string",
                "operation": "notExists",
                "singleValue": true
              },
              "leftValue": "={{ $json.error }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2
    },
    {
      "id": "751621b4-4f99-4178-a691-40fc7488874b",
      "name": "Combinar elementos",
      "type": "n8n-nodes-base.merge",
      "position": [
        2120,
        1260
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "8892eb02-0e8e-4617-85e6-e6f188361f95",
      "name": "isDiffOrNew",
      "type": "n8n-nodes-base.code",
      "position": [
        2320,
        1260
      ],
      "parameters": {
        "jsCode": "const orderJsonKeys = (jsonObj) => {\n  const ordered = {};\n  Object.keys(jsonObj).sort().forEach(key => {\n    ordered[key] = jsonObj[key];\n  });\n  return ordered;\n}\n\n// Check if file returned with content\nif (Object.keys($input.all()[0].json).includes(\"content\")) {\n  // Decode base64 content and parse JSON\n  const origWorkflow = JSON.parse(Buffer.from($input.all()[0].json.content, 'base64').toString());\n  const n8nWorkflow = $input.all()[1].json;\n  \n  // Order JSON objects\n  const orderedOriginal = orderJsonKeys(origWorkflow);\n  const orderedActual = orderJsonKeys(n8nWorkflow);\n\n  // Determine difference\n  if (JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual)) {\n    $input.all()[0].json.github_status = \"same\";\n  } else {\n    $input.all()[0].json.github_status = \"different\";\n    $input.all()[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);\n  }\n  $input.all()[0].json.content_decoded = orderedOriginal;\n// No file returned / new workflow\n} else if (Object.keys($input.all()[0].json).includes(\"data\")) {\n  const origWorkflow = JSON.parse($input.all()[0].json.data);\n  const n8nWorkflow = $input.all()[1].json;\n  \n  // Order JSON objects\n  const orderedOriginal = orderJsonKeys(origWorkflow);\n  const orderedActual = orderJsonKeys(n8nWorkflow);\n\n  // Determine difference\n  if (JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual)) {\n    $input.all()[0].json.github_status = \"same\";\n  } else {\n    $input.all()[0].json.github_status = \"different\";\n    $input.all()[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);\n  }\n  $input.all()[0].json.content_decoded = orderedOriginal;\n\n} else {\n  // Order JSON object\n  const n8nWorkflow = $input.all()[1].json;\n  const orderedActual = orderJsonKeys(n8nWorkflow);\n  \n  // Proper formatting\n  $input.all()[0].json.github_status = \"new\";\n  $input.all()[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);\n}\n\n// Return items\nreturn $input.all();"
      },
      "typeVersion": 1
    },
    {
      "id": "bfddb2a2-c149-4710-bd77-b368d641114d",
      "name": "Verificar estado",
      "type": "n8n-nodes-base.switch",
      "position": [
        2540,
        1260
      ],
      "parameters": {
        "rules": {
          "rules": [
            {
              "value2": "same"
            },
            {
              "output": 1,
              "value2": "different"
            },
            {
              "output": 2,
              "value2": "new"
            }
          ]
        },
        "value1": "={{$json.github_status}}",
        "dataType": "string"
      },
      "typeVersion": 1
    },
    {
      "id": "681e54af-b916-416d-9801-ac38a5882bcf",
      "name": "Mismo archivo - No hacer nada",
      "type": "n8n-nodes-base.noOp",
      "position": [
        2760,
        1100
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "38b2041d-1d56-436f-aa04-79d7241dcc74",
      "name": "El archivo es diferente",
      "type": "n8n-nodes-base.noOp",
      "position": [
        2760,
        1260
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "ae33280d-10d5-4882-be9b-7972394357e1",
      "name": "El archivo es nuevo",
      "type": "n8n-nodes-base.noOp",
      "position": [
        2760,
        1420
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "bea3995f-9f34-4119-a6cf-20281e70d685",
      "name": "Crear nuevo archivo",
      "type": "n8n-nodes-base.github",
      "position": [
        2980,
        1420
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Globals').item.json.repo.owner }}"
        },
        "filePath": "={{ $('Globals').item.json.repo.path }}{{$('Execute Workflow Trigger').first().json.id}}.json",
        "resource": "file",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Globals').item.json.repo.name }}"
        },
        "fileContent": "={{$('isDiffOrNew').item.json[\"n8n_data_stringy\"]}}",
        "commitMessage": "={{$('Execute Workflow Trigger').first().json.name}} ({{$json.github_status}})"
      },
      "credentials": {
        "githubApi": {
          "id": "3mfzXcMjoqNHsujs",
          "name": "GitHub account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d9172af3-55f8-4b99-b462-3e6e718b5a77",
      "name": "Editar archivo existente",
      "type": "n8n-nodes-base.github",
      "position": [
        2980,
        1240
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Globals').item.json.repo.owner }}"
        },
        "filePath": "={{ $('Globals').item.json.repo.path }}{{$('Execute Workflow Trigger').first().json.id}}.json",
        "resource": "file",
        "operation": "edit",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Globals').item.json.repo.name }}"
        },
        "fileContent": "={{$('isDiffOrNew').item.json[\"n8n_data_stringy\"]}}",
        "commitMessage": "={{$('Execute Workflow Trigger').first().json.name}} ({{$json.github_status}})"
      },
      "credentials": {
        "githubApi": {
          "id": "3mfzXcMjoqNHsujs",
          "name": "GitHub account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d9589e32-ed20-46e7-9427-1680c6222406",
      "name": "Iterar sobre elementos",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        2380,
        620
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "e1530650-aa76-4ab3-b5bb-cd6b805ea656",
      "name": "Activador programado",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        1780,
        720
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "hours",
              "hoursInterval": 2
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "79910589-f40f-46fa-a704-eaa65157a17a",
      "name": "Nota adhesiva1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1340,
        278.28654385738866
      ],
      "parameters": {
        "color": 4,
        "width": 365.19481715599653,
        "height": 596.4810912485963,
        "content": "## Backup to GitHub \nThis workflow will backup all instance credentials to GitHub.\n\nThe files are saved `ID.json` for the filename.\n\n### Setup\nOpen `Globals` node and update the values below 👇\n\n- **repo.owner:** your Github username\n- **repo.name:** the name of your repository\n- **repo.path:** the folder to use within the repository. If it doesn't exist it will be created.\n\n\nIf your username was `john-doe` and your repository was called `n8n-backups` and you wanted the credentials to go into a `credentials` folder you would set:\n\n- repo.owner - john-doe\n- repo.name - n8n-backups\n- repo.path - credentials/\n\n\nThe workflow calls itself using a subworkflow, to help reduce memory usage."
      },
      "typeVersion": 1
    },
    {
      "id": "e16c9874-1a35-41c4-8410-0c42efe17770",
      "name": "Nota adhesiva2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1740,
        440
      ],
      "parameters": {
        "color": 7,
        "width": 1028.7522287279464,
        "height": 434.88564057365943,
        "content": "## Main workflow loop"
      },
      "typeVersion": 1
    },
    {
      "id": "a1464b91-516a-4fd9-9235-20de50e74cb2",
      "name": "Obtener datos del archivo",
      "type": "n8n-nodes-base.github",
      "position": [
        1920,
        1000
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $json.repo.owner }}"
        },
        "filePath": "={{ $json.repo.path }}{{ $('Execute Workflow Trigger').item.json.id }}.json",
        "resource": "file",
        "operation": "get",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $json.repo.name }}"
        },
        "asBinaryProperty": false,
        "additionalParameters": {}
      },
      "credentials": {
        "githubApi": {
          "id": "3mfzXcMjoqNHsujs",
          "name": "GitHub account"
        }
      },
      "typeVersion": 1,
      "continueOnFail": true,
      "alwaysOutputData": true
    },
    {
      "id": "eb2fe87f-f3af-4215-ac1f-7c2b45e8aff6",
      "name": "Globales",
      "type": "n8n-nodes-base.set",
      "position": [
        1720,
        1160
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "6cf546c5-5737-4dbd-851b-17d68e0a3780",
              "name": "repo.owner",
              "type": "string",
              "value": "john-doe"
            },
            {
              "id": "452efa28-2dc6-4ea3-a7a2-c35d100d0382",
              "name": "repo.name",
              "type": "string",
              "value": "n8n-backup"
            },
            {
              "id": "81c4dc54-86bf-4432-a23f-22c7ea831e74",
              "name": "repo.path",
              "type": "string",
              "value": "credentials/"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "f4498ab4-1760-4849-9fe1-ecfcd7baa9f3",
      "name": "Ejecutar comando",
      "type": "n8n-nodes-base.executeCommand",
      "position": [
        2000,
        620
      ],
      "parameters": {
        "command": "npx n8n export:credentials --all --decrypted"
      },
      "typeVersion": 1
    },
    {
      "id": "d453a000-40ef-43f5-b108-5eb30422d1a3",
      "name": "JSON formatting",
      "type": "n8n-nodes-base.code",
      "position": [
        2180,
        620
      ],
      "parameters": {
        "jsCode": "// Function to beautify JSON\nfunction beautifyJson(jsonString) {\n  try {\n    // Parse the JSON string\n    const jsonObject = JSON.parse(jsonString);\n\n    // Format the JSON with indentation\n    return jsonObject; // Return the parsed object directly\n  } catch (error) {\n    // Return the error message if JSON is invalid\n    return `Invalid JSON: ${error.message}`;\n  }\n}\n\n// Retrieve the JSON object from the input data\nconst input = $input.all()[0].json;\n\n// Extract the JSON string from the stdout field\nconst jsonString = input.stdout.match(/\\[{.*}\\]/s);\n\n// Check if a valid JSON string is found\nif (!jsonString) {\n  return {\n    json: {\n      error: \"No valid JSON string found in stdout.\"\n    }\n  };\n}\n\n// Beautify the JSON\nconst beautifiedJson = beautifyJson(jsonString[0]);\n\n// Output the beautified JSON, ensuring each entry is in an object with a 'json' key\nconst output = beautifiedJson.map(entry => ({ json: entry }));\n\n// Return the output\nreturn output;\n"
      },
      "typeVersion": 2
    },
    {
      "id": "49dbf875-7345-4241-a7fc-f42e53aef64e",
      "name": "Nota adhesiva3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1680,
        1060
      ],
      "parameters": {
        "color": 4,
        "width": 150,
        "height": 80,
        "content": "## Edit this node 👇"
      },
      "typeVersion": 1
    },
    {
      "id": "98158f3e-7aca-456b-994c-4c795d31c18c",
      "name": "Ejecutar flujo de trabajo",
      "type": "n8n-nodes-base.executeWorkflow",
      "position": [
        2600,
        620
      ],
      "parameters": {
        "mode": "each",
        "options": {},
        "workflowId": "={{ $workflow.id }}"
      },
      "typeVersion": 1
    },
    {
      "id": "d8c52eb7-bcb0-49e7-bb32-7499b1ca22cd",
      "name": "Activador de ejecución de flujo de trabajo",
      "type": "n8n-nodes-base.executeWorkflowTrigger",
      "position": [
        1440,
        1280
      ],
      "parameters": {
        "inputSource": "passthrough"
      },
      "typeVersion": 1.1
    }
  ],
  "pinData": {},
  "connections": {
    "eb2fe87f-f3af-4215-ac1f-7c2b45e8aff6": {
      "main": [
        [
          {
            "node": "a1464b91-516a-4fd9-9235-20de50e74cb2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "943eed85-d4cd-4ec5-b278-d143b0f6bd15": {
      "main": [
        [
          {
            "node": "751621b4-4f99-4178-a691-40fc7488874b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ae33280d-10d5-4882-be9b-7972394357e1": {
      "main": [
        [
          {
            "node": "bea3995f-9f34-4119-a6cf-20281e70d685",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "751621b4-4f99-4178-a691-40fc7488874b": {
      "main": [
        [
          {
            "node": "8892eb02-0e8e-4617-85e6-e6f188361f95",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8892eb02-0e8e-4617-85e6-e6f188361f95": {
      "main": [
        [
          {
            "node": "bfddb2a2-c149-4710-bd77-b368d641114d",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bfddb2a2-c149-4710-bd77-b368d641114d": {
      "main": [
        [
          {
            "node": "681e54af-b916-416d-9801-ac38a5882bcf",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "38b2041d-1d56-436f-aa04-79d7241dcc74",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "ae33280d-10d5-4882-be9b-7972394357e1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a1464b91-516a-4fd9-9235-20de50e74cb2": {
      "main": [
        [
          {
            "node": "124ebdd7-c2c1-4fec-89d3-596f034e0fe7",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bea3995f-9f34-4119-a6cf-20281e70d685": {
      "main": [
        [
          {
            "node": "d22236c2-578c-400b-b3e5-354498620c39",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "f4498ab4-1760-4849-9fe1-ecfcd7baa9f3": {
      "main": [
        [
          {
            "node": "d453a000-40ef-43f5-b108-5eb30422d1a3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d453a000-40ef-43f5-b108-5eb30422d1a3": {
      "main": [
        [
          {
            "node": "d9589e32-ed20-46e7-9427-1680c6222406",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d9589e32-ed20-46e7-9427-1680c6222406": {
      "main": [
        [],
        [
          {
            "node": "98158f3e-7aca-456b-994c-4c795d31c18c",
            "type": "main",
            "index": 0
          },
          {
            "node": "98158f3e-7aca-456b-994c-4c795d31c18c",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "98158f3e-7aca-456b-994c-4c795d31c18c": {
      "main": [
        [
          {
            "node": "d9589e32-ed20-46e7-9427-1680c6222406",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e1530650-aa76-4ab3-b5bb-cd6b805ea656": {
      "main": [
        [
          {
            "node": "f4498ab4-1760-4849-9fe1-ecfcd7baa9f3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "38b2041d-1d56-436f-aa04-79d7241dcc74": {
      "main": [
        [
          {
            "node": "d9172af3-55f8-4b99-b462-3e6e718b5a77",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "124ebdd7-c2c1-4fec-89d3-596f034e0fe7": {
      "main": [
        [
          {
            "node": "943eed85-d4cd-4ec5-b278-d143b0f6bd15",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "751621b4-4f99-4178-a691-40fc7488874b",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d9172af3-55f8-4b99-b462-3e6e718b5a77": {
      "main": [
        [
          {
            "node": "d22236c2-578c-400b-b3e5-354498620c39",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4377c764-07f3-4304-8105-d3f009925917": {
      "main": [
        [
          {
            "node": "f4498ab4-1760-4849-9fe1-ecfcd7baa9f3",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "681e54af-b916-416d-9801-ac38a5882bcf": {
      "main": [
        [
          {
            "node": "d22236c2-578c-400b-b3e5-354498620c39",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d8c52eb7-bcb0-49e7-bb32-7499b1ca22cd": {
      "main": [
        [
          {
            "node": "eb2fe87f-f3af-4215-ac1f-7c2b45e8aff6",
            "type": "main",
            "index": 0
          },
          {
            "node": "751621b4-4f99-4178-a691-40fc7488874b",
            "type": "main",
            "index": 1
          }
        ]
      ]
    }
  }
}
Preguntas frecuentes

¿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 - 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.

Información del flujo de trabajo
Nivel de dificultad
Avanzado
Número de nodos18
Categoría1
Tipos de nodos11
Descripción de la dificultad

Adecuado para usuarios avanzados, flujos de trabajo complejos con 16+ nodos

Autor
Solomon

Solomon

@solomon

Freelance consultant from Brazil, specializing in automations and data analysis. I work with select clients, addressing their toughest projects. For business inquiries, email me at automations.solomon@gmail.com or message me on Telegram for a faster response.

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34