AutomationFlowsDevOps › Backup Fluxos

Backup Fluxos

Backup_Fluxos. Uses github, itemLists, n8n, moveBinaryData. Manual trigger; 11 nodes.

Manual trigger★★★★☆ complexity11 nodesGitHubItem Listsn8nMove Binary Data
DevOps Trigger: Manual Nodes: 11 Complexity: ★★★★☆ Added:

This workflow follows the GitHub → n8n recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "nodes": [
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        256,
        -256
      ],
      "id": "c905e30a-348e-4ce8-a0e3-52d490a5bb69",
      "name": "When clicking 'Execute workflow'"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "cfg-1",
              "name": "githubOwner",
              "value": "synapiens",
              "type": "string"
            },
            {
              "id": "cfg-2",
              "name": "githubRepo",
              "value": "n8n_fluxos_srv_synapiens",
              "type": "string"
            },
            {
              "id": "cfg-3",
              "name": "githubBranch",
              "value": "main",
              "type": "string"
            },
            {
              "id": "cfg-4",
              "name": "githubToken",
              "value": "Bearer <redacted-credential>",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        480,
        -256
      ],
      "id": "8c5dfaca-9d9b-4a90-81e0-9e81abb3564c",
      "name": "Configura\u00e7\u00f5es"
    },
    {
      "parameters": {
        "filters": {},
        "requestOptions": {}
      },
      "type": "n8n-nodes-base.n8n",
      "typeVersion": 1,
      "position": [
        704,
        -256
      ],
      "id": "677c71a9-81b4-4b34-a799-ade97b72ce82",
      "name": "Lista Fluxos",
      "credentials": {
        "n8nApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 1
          },
          "conditions": [
            {
              "id": "filter-self",
              "leftValue": "={{ $json.id }}",
              "rightValue": "={{ $workflow.id }}",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.filter",
      "typeVersion": 2,
      "position": [
        272,
        80
      ],
      "id": "35d6dc90-5795-4eb3-9fb4-9eb858991cfb",
      "name": "Ignora pr\u00f3prio workflow"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        288,
        288
      ],
      "id": "c768c9e7-5d7c-402f-9b51-6eea77d66c72",
      "name": "Loop Fluxos"
    },
    {
      "parameters": {
        "operation": "get",
        "workflowId": "={{ $json.id }}",
        "requestOptions": {}
      },
      "type": "n8n-nodes-base.n8n",
      "typeVersion": 1,
      "position": [
        528,
        304
      ],
      "id": "cf8526e3-0845-41fe-8265-a9794a7fd58b",
      "name": "Get Workflow",
      "credentials": {
        "n8nApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "jsCode": "// \u2500\u2500 Configura\u00e7\u00f5es \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst workflow = $json;\nconst config   = $('Configura\u00e7\u00f5es').first().json;\n\n// \u2500\u2500 Gera base64 do conte\u00fado \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst content = JSON.stringify(workflow, null, 2);\nconst base64  = Buffer.from(content).toString('base64');\n\n// \u2500\u2500 Determina pasta \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nlet folderPath = '_sem_pasta';\nif (workflow.parentFolder && workflow.parentFolder.name) {\n  folderPath = workflow.parentFolder.name;\n} else if (workflow.folder && workflow.folder.name) {\n  folderPath = workflow.folder.name;\n} else if (workflow.tags && workflow.tags.length > 0) {\n  folderPath = workflow.tags[0].name;\n}\n\nconst sanitize = (s) => String(s)\n  .normalize('NFD')\n  .replace(/[\\u0300-\\u036f]/g, '')\n  .replace(/[^a-zA-Z0-9\\-_\\s]/g, '')\n  .trim()\n  .replace(/\\s+/g, '_');\n\nconst filePath = `workflows/${sanitize(folderPath)}/${sanitize(workflow.name)}.json`;\n\nconst headers = {\n  'Authorization'       : config.githubToken,\n  'Accept'              : 'application/vnd.github+json',\n  'X-GitHub-Api-Version': '2022-11-28',\n  'Content-Type'        : 'application/json'\n};\n\nconst url = `https://api.github.com/repos/${config.githubOwner}/${config.githubRepo}/contents/${filePath}`;\n\n// \u2500\u2500 Busca SHA atual \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst getSha = async () => {\n  try {\n    const resp = await this.helpers.httpRequest({\n      method: 'GET',\n      url,\n      headers,\n      returnFullResponse: true,\n      ignoreHttpStatusErrors: true\n    });\n    if (resp.statusCode === 200 && resp.body && resp.body.sha) {\n      return resp.body.sha;\n    }\n  } catch (e) {}\n  return null;\n};\n\n// \u2500\u2500 PUT com retry no 409 \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst salvar = async (sha, tentativa) => {\n  const payload = {\n    message: `chore: backup \"${workflow.name}\"`,\n    content : base64,\n    branch  : config.githubBranch\n  };\n  if (sha) payload.sha = sha;\n\n  const resp = await this.helpers.httpRequest({\n    method: 'PUT',\n    url,\n    headers,\n    body: payload,\n    returnFullResponse: true,\n    ignoreHttpStatusErrors: true\n  });\n\n  if (resp.statusCode === 409 && tentativa < 3) {\n    await new Promise(r => setTimeout(r, 1000 * tentativa));\n    const novoSha = await getSha();\n    return salvar(novoSha, tentativa + 1);\n  }\n\n  return { resp, sha };\n};\n\n// \u2500\u2500 Executa \u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\u2500\nconst shaInicial = await getSha();\nconst { resp } = await salvar(shaInicial, 1);\n\nif (resp.statusCode !== 200 && resp.statusCode !== 201) {\n  throw new Error(`GitHub ${resp.statusCode}: ${JSON.stringify(resp.body)}`);\n}\n\nreturn [{\n  json: {\n    workflowName : workflow.name,\n    filePath,\n    acao         : shaInicial ? 'ATUALIZADO' : 'CRIADO',\n    httpStatus   : resp.statusCode,\n    shaAnterior  : shaInicial || null,\n    commitSha    : resp.body && resp.body.commit ? resp.body.commit.sha : null\n  }\n}];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        800,
        304
      ],
      "id": "0b33ba77-7404-4f4d-a853-a7292a3dd1af",
      "name": "Prepara e Salva no GitHub",
      "continueOnFail": true
    },
    {
      "parameters": {
        "aggregate": "aggregateAllItemData",
        "options": {}
      },
      "type": "n8n-nodes-base.aggregate",
      "typeVersion": 1,
      "position": [
        288,
        -64
      ],
      "id": "420e56ff-cb27-41de-b8e2-5e1c1650041e",
      "name": "Aggregate"
    },
    {
      "parameters": {
        "content": "## \u2699\ufe0f Setup antes de executar\n\n**1. Node `Configura\u00e7\u00f5es`** \u2014 edite os 4 campos:\n- `githubOwner` \u2192 usu\u00e1rio/org do GitHub\n- `githubRepo` \u2192 nome do reposit\u00f3rio\n- `githubBranch` \u2192 branch alvo (ex: `main`)\n- `githubToken` \u2192 `Bearer ghp_SEU_TOKEN`\n\n---\n\n**2. Credencial N8N Hermes**\nNodes `Lista Fluxos` e `Get Workflow`\nusam a credencial `N8N Hermes` (n8nApi).\n\n---\n\n**3. O node `Ignora pr\u00f3prio workflow`**\nFiltra o workflow de backup da lista\npara evitar conflito ao salvar a si mesmo.\nO backup deste workflow deve ser feito\nmanualmente ou por outro agendador.\n\n---\n\n**4. Estrutura gerada no reposit\u00f3rio:**\n```\nworkflows/\n  NomeDaPasta/\n    NomeDoFluxo.json\n  _sem_pasta/\n    FluxoSemPasta.json\n```\n\n**5. Output por workflow:**\n```json\n{\n  \"acao\": \"CRIADO | ATUALIZADO\",\n  \"httpStatus\": 200,\n  \"commitSha\": \"abc123\"\n}\n```",
        "height": 660,
        "width": 480,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        -352,
        -304
      ],
      "id": "ae44f214-de4a-48a4-af42-115a3050345a",
      "name": "Instru\u00e7\u00f5es1"
    },
    {
      "parameters": {
        "jsCode": "const itens = $json.data || [];\n\nconst erros    = itens.filter(i => i.error || (i.httpStatus && i.httpStatus >= 400));\nconst criados  = itens.filter(i => i.acao === 'CRIADO');\nconst atualizados = itens.filter(i => i.acao === 'ATUALIZADO');\n\nconsole.log('\u2705 Criados:', criados.length);\nconsole.log('\ud83d\udd04 Atualizados:', atualizados.length);\nconsole.log('\u274c Erros:', erros.length, JSON.stringify(erros, null, 2));\n\nreturn [{ json: { criados: criados.length, atualizados: atualizados.length, erros } }];"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        480,
        -64
      ],
      "id": "baeab4a9-00cf-4046-9392-b918347a1bf9",
      "name": "Code in JavaScript"
    }
  ],
  "connections": {
    "When clicking 'Execute workflow'": {
      "main": [
        [
          {
            "node": "Configura\u00e7\u00f5es",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Configura\u00e7\u00f5es": {
      "main": [
        [
          {
            "node": "Lista Fluxos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Lista Fluxos": {
      "main": [
        [
          {
            "node": "Ignora pr\u00f3prio workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Ignora pr\u00f3prio workflow": {
      "main": [
        [
          {
            "node": "Loop Fluxos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Fluxos": {
      "main": [
        [
          {
            "node": "Aggregate",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Workflow": {
      "main": [
        [
          {
            "node": "Prepara e Salva no GitHub",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepara e Salva no GitHub": {
      "main": [
        [
          {
            "node": "Loop Fluxos",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Aggregate": {
      "main": [
        [
          {
            "node": "Code in JavaScript",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "meta": {
    "templateCredsSetupCompleted": true
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

Backup_Fluxos. Uses github, itemLists, n8n, moveBinaryData. Manual trigger; 11 nodes.

Source: https://github.com/clenildon-ferreira-avine/backup_avine/blob/6ca27632a7a78e0d9d4fe675d225b1987db41df9/backup_fluxos-AdK9UXpniwJ1FFST.json — original creator credit. Request a take-down →

More DevOps workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

DevOps

backup_workflow. Uses github, itemLists, n8n, moveBinaryData. Event-driven trigger; 19 nodes.

GitHub, Item Lists, n8n +1
DevOps

github. Uses github, itemLists, n8n, moveBinaryData. Event-driven trigger; 18 nodes.

GitHub, Item Lists, n8n +1
DevOps

[Gus] Backup workflows in github. Uses github, itemLists, n8n, moveBinaryData. Scheduled trigger; 18 nodes.

GitHub, Item Lists, n8n +1
DevOps

backup. Uses github, itemLists, moveBinaryData, n8n. Scheduled trigger; 17 nodes.

GitHub, Item Lists, Move Binary Data +1
DevOps

[bck-fluxos]. Uses github, itemLists, n8n, moveBinaryData. Scheduled trigger; 16 nodes.

GitHub, Item Lists, n8n +1