Copiar flujos de trabajo a un repositorio git en Gitea

Avanzado

Este es unOtherflujo de automatización del dominio deautomatización que contiene 20 nodos.Utiliza principalmente nodos como If, N8n, Set, Code, HttpRequest. Respaldar flujos de trabajo en un repositorio git en Gitea

Requisitos previos
  • Pueden requerirse credenciales de autenticación para la API de destino

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
{
  "id": "Ef2uEM6H19K2DGUO",
  "meta": {
    "templateId": "2532",
    "templateCredsSetupCompleted": true
  },
  "name": "Backup workflows to git repository on Gitea",
  "tags": [
    {
      "id": "UWNX4AzSneYNvTQI",
      "name": "Gitea",
      "createdAt": "2025-01-28T23:10:06.823Z",
      "updatedAt": "2025-01-28T23:10:06.823Z"
    },
    {
      "id": "4b7Bs9T0Cagsg5tT",
      "name": "Git",
      "createdAt": "2025-01-28T23:10:26.545Z",
      "updatedAt": "2025-01-28T23:10:26.545Z"
    },
    {
      "id": "HiN3ehC2KkAp5kVs",
      "name": "Backup",
      "createdAt": "2025-01-28T23:10:38.878Z",
      "updatedAt": "2025-01-28T23:10:38.878Z"
    }
  ],
  "nodes": [
    {
      "id": "639582ef-f13e-4844-bd10-647718079121",
      "name": "Globals",
      "type": "n8n-nodes-base.set",
      "position": [
        600,
        240
      ],
      "parameters": {
        "values": {
          "string": [
            {
              "name": "repo.url",
              "value": "https://git.vdm.dev"
            },
            {
              "name": "repo.name",
              "value": "workflows"
            },
            {
              "name": "repo.owner",
              "value": "n8n"
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 1
    },
    {
      "id": "9df89713-220e-43b9-b234-b8f5612629cf",
      "name": "n8n",
      "type": "n8n-nodes-base.n8n",
      "position": [
        840,
        240
      ],
      "parameters": {
        "filters": {},
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "ZjfxOLTTHX2CzbKa",
          "name": "Main N8N Account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4b2d375c-a339-404c-babd-555bd2fc4091",
      "name": "Disparador programado",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        380,
        240
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 45
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "ea026e96-0db1-41fd-b003-2f2bf4662696",
      "name": "Nota adhesiva",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2620,
        300
      ],
      "parameters": {
        "height": 80,
        "content": "Workflow changes committed to the repository"
      },
      "typeVersion": 1
    },
    {
      "id": "9c402daa-6d03-485d-b8a0-58f1b65d396d",
      "name": "Nota adhesiva1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2260,
        180
      ],
      "parameters": {
        "height": 80,
        "content": "Check if there are any changes in the workflow"
      },
      "typeVersion": 1
    },
    {
      "id": "1d9216d9-bf8d-4945-8a58-22fb1ffc9be8",
      "name": "Nota adhesiva2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1800,
        580
      ],
      "parameters": {
        "height": 80,
        "content": "Create a new file for the workflow"
      },
      "typeVersion": 1
    },
    {
      "id": "60a3953b-d9f1-4afd-b299-e314116b96c6",
      "name": "Nota adhesiva3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1300,
        200
      ],
      "parameters": {
        "height": 80,
        "content": "Check if file exists in the repository"
      },
      "typeVersion": 1
    },
    {
      "id": "f2340ad0-71a1-4c74-8d90-bcb974b8b305",
      "name": "Nota adhesiva5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        780,
        180
      ],
      "parameters": {
        "height": 80,
        "content": "Get all workflows"
      },
      "typeVersion": 1
    },
    {
      "id": "617bea19-341a-4e9d-b6fd-6b417e58d756",
      "name": "Nota adhesiva6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        500,
        180
      ],
      "parameters": {
        "height": 80,
        "content": "Set variables"
      },
      "typeVersion": 1
    },
    {
      "id": "72f806d7-e30a-470b-9ba2-37fdc35de3c8",
      "name": "EstablecerDataUpdateNode",
      "type": "n8n-nodes-base.set",
      "position": [
        1920,
        240
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0a6b769a-c66d-4784-92c7-a70caa28e1ba",
              "name": "item",
              "type": "object",
              "value": "={{ $node[\"ForEach\"].json }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bca5e2c4-7aa3-48df-9e5f-b31977970c28",
      "name": "EstablecerDataCreateNode",
      "type": "n8n-nodes-base.set",
      "position": [
        1220,
        640
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "0a6b769a-c66d-4784-92c7-a70caa28e1ba",
              "name": "item",
              "type": "object",
              "value": "={{ $node[\"ForEach\"].json }}"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "bf74b1ea-e066-462b-9c3d-ed4a44a09a33",
      "name": "Base64EncodeUpdate",
      "type": "n8n-nodes-base.code",
      "position": [
        2140,
        240
      ],
      "parameters": {
        "language": "python",
        "pythonCode": "import json\nimport base64\nfrom js import Object\n\n# Assuming _input.all() returns a JavaScript object\njs_object = _input.all()\n\n# Convert the JsProxy object to a Python dictionary\ndef js_to_py(js_obj):\n    if isinstance(js_obj, (str, int, float, bool)) or js_obj is None:\n        # Base types are already Python-compatible\n        return js_obj\n    elif isinstance(js_obj, list):\n        # Convert lists recursively\n        return [js_to_py(item) for item in js_obj]\n    elif hasattr(js_obj, \"__iter__\") and not isinstance(js_obj, str):\n        # Handle JsProxy objects (JavaScript objects or arrays)\n        if hasattr(js_obj, \"keys\"):\n            # If it has keys, treat it as a dictionary\n            return {key: js_to_py(js_obj[key]) for key in Object.keys(js_obj)}\n        else:\n            # Otherwise, treat it as a list\n            return [js_to_py(item) for item in js_obj]\n    else:\n        # Fallback for other types\n        return js_obj\n\n# Convert the JavaScript object to a Python dictionary\ninput_dict = js_to_py(js_object)\n\n# Step 0: get the correct data set of the workflow\ninner_data = input_dict[0].get('json').get('item')\n\n# Step 1: Convert the dictionary to a pretty-printed JSON string\njson_string = json.dumps(inner_data, indent=4)\n\n# Step 2: Encode the JSON string to bytes\njson_bytes = json_string.encode('utf-8')\n\n# Step 3: Convert the bytes to a base64 string\nbase64_string = base64.b64encode(json_bytes).decode('utf-8')\n\n# Step 5: Create the return object with the base64 string and its SHA-256 hash\nreturn_object = {\n    \"item\": base64_string\n}\n\n# Return the object\nreturn return_object"
      },
      "typeVersion": 2
    },
    {
      "id": "2d817c66-5aa0-45c9-b851-4b5e3dbecca4",
      "name": "Base64EncodeCreate",
      "type": "n8n-nodes-base.code",
      "position": [
        1520,
        640
      ],
      "parameters": {
        "language": "python",
        "pythonCode": "import json\nimport base64\nfrom js import Object\n\n# Assuming _input.all() returns a JavaScript object\njs_object = _input.all()\n\n# Convert the JsProxy object to a Python dictionary\ndef js_to_py(js_obj):\n    if isinstance(js_obj, (str, int, float, bool)) or js_obj is None:\n        # Base types are already Python-compatible\n        return js_obj\n    elif isinstance(js_obj, list):\n        # Convert lists recursively\n        return [js_to_py(item) for item in js_obj]\n    elif hasattr(js_obj, \"__iter__\") and not isinstance(js_obj, str):\n        # Handle JsProxy objects (JavaScript objects or arrays)\n        if hasattr(js_obj, \"keys\"):\n            # If it has keys, treat it as a dictionary\n            return {key: js_to_py(js_obj[key]) for key in Object.keys(js_obj)}\n        else:\n            # Otherwise, treat it as a list\n            return [js_to_py(item) for item in js_obj]\n    else:\n        # Fallback for other types\n        return js_obj\n\n# Convert the JavaScript object to a Python dictionary\ninput_dict = js_to_py(js_object)\n\n# Step 0: get the correct data set of the workflow\ninner_data = input_dict[0].get('json').get('item')\n\n# Step 1: Convert the dictionary to a pretty-printed JSON string\njson_string = json.dumps(inner_data, indent=4)\n\n# Step 2: Encode the JSON string to bytes\njson_bytes = json_string.encode('utf-8')\n\n# Step 3: Convert the bytes to a base64 string\nbase64_string = base64.b64encode(json_bytes).decode('utf-8')\n\n# Step 4: Create the return object with the base64 string in 'item'\nreturn_object = {\n    \"item\": base64_string\n}\n\n# Return the object\nreturn return_object"
      },
      "typeVersion": 2
    },
    {
      "id": "41a7da89-1c8c-4100-8c30-d0788962efc1",
      "name": "Exist",
      "type": "n8n-nodes-base.if",
      "position": [
        1640,
        260
      ],
      "parameters": {
        "options": {
          "ignoreCase": false
        },
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "or",
          "conditions": [
            {
              "id": "16a9182d-059d-4774-ba95-654fb4293fdb",
              "operator": {
                "type": "object",
                "operation": "notExists",
                "singleValue": true
              },
              "leftValue": "={{ $json.error }}",
              "rightValue": 404
            }
          ]
        }
      },
      "executeOnce": false,
      "typeVersion": 2.2,
      "alwaysOutputData": false
    },
    {
      "id": "ab9246eb-a253-4d76-b33b-5f8f12342542",
      "name": "Changed",
      "type": "n8n-nodes-base.if",
      "position": [
        2360,
        240
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "e0c66624-429a-4f1f-bf7b-1cc1b32bad7b",
              "operator": {
                "type": "string",
                "operation": "notEquals"
              },
              "leftValue": "={{ $json.item }}",
              "rightValue": "={{ $('GetGitea').item.json.content }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "4278a176-6496-4817-82f8-591539619673",
      "name": "PutGitea",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2700,
        360
      ],
      "parameters": {
        "url": "={{ $('Globals').item.json.repo.url }}/api/v1/repos/{{ $('Globals').item.json.repo.owner }}/{{ $('Globals').item.json.repo.name }}/contents/{{ encodeURIComponent($('GetGitea').item.json.name) }}",
        "method": "PUT",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "content",
              "value": "={{ $('Base64EncodeUpdate').item.json.item }}"
            },
            {
              "name": "sha",
              "value": "={{ $('GetGitea').item.json.sha }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "gTvBAgkOmqhl5Nmr",
          "name": "Gitea Token"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "12307a61-e7cc-42f9-a7c7-8abbcab9e3ab",
      "name": "GetGitea",
      "type": "n8n-nodes-base.httpRequest",
      "onError": "continueRegularOutput",
      "position": [
        1380,
        260
      ],
      "parameters": {
        "url": "={{ $('Globals').item.json.repo.url }}/api/v1/repos/{{ encodeURIComponent($('Globals').item.json.repo.owner) }}/{{ encodeURIComponent($('Globals').item.json.repo.name) }}/contents/{{ encodeURIComponent($json.name) }}.json",
        "options": {},
        "authentication": "genericCredentialType",
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "gTvBAgkOmqhl5Nmr",
          "name": "Gitea Token"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "24fda439-bb23-4392-a297-d8070907f9e6",
      "name": "PostGitea",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1920,
        640
      ],
      "parameters": {
        "url": "={{ $('Globals').item.json.repo.url }}/api/v1/repos/{{ $('Globals').item.json.repo.owner }}/{{ $('Globals').item.json.repo.name }}/contents/{{ encodeURIComponent($('ForEach').item.json.name) }}.json",
        "method": "POST",
        "options": {},
        "sendBody": true,
        "authentication": "genericCredentialType",
        "bodyParameters": {
          "parameters": [
            {
              "name": "content",
              "value": "={{ $json.item }}"
            }
          ]
        },
        "genericAuthType": "httpHeaderAuth"
      },
      "credentials": {
        "httpHeaderAuth": {
          "id": "gTvBAgkOmqhl5Nmr",
          "name": "Gitea Token"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "43a60315-d381-4ac4-be4c-f6a158651a00",
      "name": "ForEach",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1060,
        240
      ],
      "parameters": {
        "options": {}
      },
      "executeOnce": false,
      "typeVersion": 3
    },
    {
      "id": "88578dc4-2398-48d0-b0ba-2198b35bb994",
      "name": "Nota adhesiva4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        380,
        440
      ],
      "parameters": {
        "width": 560,
        "height": 1620,
        "content": "### **📌 Setup Guide for Backup Workflows to Git Repository on Gitea**\n\n#### **🔧 1. Configure Global Variables**\nGo to the **Globals** node and update the following:\n- **`repo.url`** → `https://your-gitea-instance.com` *(Replace with your actual Gitea URL)*\n- **`repo.name`** → `workflows` *(Repository name where backups will be stored)*\n- **`repo.owner`** → `octoleo` *(Gitea account that owns the repository)*\n\n📌 **These settings define where workflows will be backed up.**\n\n---\n\n#### **🔑 2. Set Up Gitea Authentication**\n1️⃣ **In Gitea:**\n- Generate a **Personal Access Token** under **Settings → Applications → Generate Token**\n- Ensure the token has **repo read/write permissions**\n\n2️⃣ **In the Credentials Manager:**\n- Create a new **Gitea Token** credential\n- Set the **Name** as `Authorization`\n- Set the **Value** as:\n```\nBearer YOUR_PERSONAL_ACCESS_TOKEN\n```\n📌 **Ensure there is a space after `Bearer` before the token!**\n\n---\n\n#### **🔗 3. Connect Gitea Credentials to Git Nodes**\n- Open each of these **three Git nodes**:\n- **GetGitea** → Retrieves existing repository data\n- **PutGitea** → Updates workflows\n- **PostGitea** → Adds new workflows\n\n- Assign the **Gitea Token** credential to each node.\n\n📌 **These nodes handle pushing your workflows to Gitea.**\n\n---\n\n#### **🌐 4. Set Up API Credentials for Workflow Retrieval**\n- Locate the API request node that **fetches workflows**.\n- Add your **API authentication credentials** (Token or Basic Auth).\n\n📌 **This ensures the workflow can fetch all available workflows from your system.**\n\n---\n\n#### **🛠️ 5. Test & Activate the Workflow**\n✅ **Run the workflow manually** → Check that workflows are being backed up correctly.\n✅ **Review the Gitea repository** → Ensure the files are updated.\n✅ **Enable the scheduled trigger** → Automates backups at defined intervals.\n\n📌 **The workflow automatically checks for changes before committing updates!**\n\n---\n\n### **🚀 Done! Your Workflows Are Now Backed Up Securely!**\n💬 Have issues? **Reach out on the forum for help!**"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "84ba3f3f-fbc8-4792-8e28-198f515fef4e",
  "staticData": {
    "node:Schedule Trigger": {
      "recurrenceRules": []
    }
  },
  "connections": {
    "9df89713-220e-43b9-b234-b8f5612629cf": {
      "main": [
        [
          {
            "node": "43a60315-d381-4ac4-be4c-f6a158651a00",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "41a7da89-1c8c-4100-8c30-d0788962efc1": {
      "main": [
        [
          {
            "node": "SetDataUpdateNode",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "SetDataCreateNode",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ab9246eb-a253-4d76-b33b-5f8f12342542": {
      "main": [
        [
          {
            "node": "4278a176-6496-4817-82f8-591539619673",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "43a60315-d381-4ac4-be4c-f6a158651a00",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "43a60315-d381-4ac4-be4c-f6a158651a00": {
      "main": [
        [],
        [
          {
            "node": "12307a61-e7cc-42f9-a7c7-8abbcab9e3ab",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "639582ef-f13e-4844-bd10-647718079121": {
      "main": [
        [
          {
            "node": "9df89713-220e-43b9-b234-b8f5612629cf",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "12307a61-e7cc-42f9-a7c7-8abbcab9e3ab": {
      "main": [
        [
          {
            "node": "41a7da89-1c8c-4100-8c30-d0788962efc1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "4278a176-6496-4817-82f8-591539619673": {
      "main": [
        [
          {
            "node": "43a60315-d381-4ac4-be4c-f6a158651a00",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "24fda439-bb23-4392-a297-d8070907f9e6": {
      "main": [
        [
          {
            "node": "43a60315-d381-4ac4-be4c-f6a158651a00",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "639582ef-f13e-4844-bd10-647718079121",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SetDataCreateNode": {
      "main": [
        [
          {
            "node": "2d817c66-5aa0-45c9-b851-4b5e3dbecca4",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "SetDataUpdateNode": {
      "main": [
        [
          {
            "node": "bf74b1ea-e066-462b-9c3d-ed4a44a09a33",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2d817c66-5aa0-45c9-b851-4b5e3dbecca4": {
      "main": [
        [
          {
            "node": "24fda439-bb23-4392-a297-d8070907f9e6",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bf74b1ea-e066-462b-9c3d-ed4a44a09a33": {
      "main": [
        [
          {
            "node": "ab9246eb-a253-4d76-b33b-5f8f12342542",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  },
  "triggerCount": 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 - Otros

¿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 nodos20
Categoría1
Tipos de nodos8
Descripción de la dificultad

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

Autor
Octoleo

Octoleo

@octoleo

Hi, I’m Llewellyn van der Merwe, also known as <<ewe>>yn, pioneering tools to automate freedom!

Enlaces externos
Ver en n8n.io

Compartir este flujo de trabajo

Categorías

Categorías: 34