Workflow: Code Schedule Export

Workflow Details

Download Workflow
{
    "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": "Schedule Trigger",
            "type": "n8n-nodes-base.scheduleTrigger",
            "position": [
                380,
                240
            ],
            "parameters": {
                "rule": {
                    "interval": [
                        {
                            "field": "minutes",
                            "minutesInterval": 45
                        }
                    ]
                }
            },
            "typeVersion": 1.1999999999999999555910790149937383830547332763671875
        },
        {
            "id": "ea026e96-0db1-41fd-b003-2f2bf4662696",
            "name": "Sticky Note",
            "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": "Sticky Note1",
            "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": "Sticky Note2",
            "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": "Sticky Note3",
            "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": "Sticky Note5",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                780,
                180
            ],
            "parameters": {
                "height": 80,
                "content": "Get all workflows"
            },
            "typeVersion": 1
        },
        {
            "id": "617bea19-341a-4e9d-b6fd-6b417e58d756",
            "name": "Sticky Note6",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                500,
                180
            ],
            "parameters": {
                "height": 80,
                "content": "Set variables"
            },
            "typeVersion": 1
        },
        {
            "id": "72f806d7-e30a-470b-9ba2-37fdc35de3c8",
            "name": "SetDataUpdateNode",
            "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.399999999999999911182158029987476766109466552734375
        },
        {
            "id": "bca5e2c4-7aa3-48df-9e5f-b31977970c28",
            "name": "SetDataCreateNode",
            "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.399999999999999911182158029987476766109466552734375
        },
        {
            "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.20000000000000017763568394002504646778106689453125,
            "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.20000000000000017763568394002504646778106689453125
        },
        {
            "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.20000000000000017763568394002504646778106689453125
        },
        {
            "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.20000000000000017763568394002504646778106689453125
        },
        {
            "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.20000000000000017763568394002504646778106689453125
        },
        {
            "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": "Sticky Note4",
            "type": "n8n-nodes-base.stickyNote",
            "position": [
                380,
                440
            ],
            "parameters": {
                "width": 560,
                "height": 1620,
                "content": "### **\ud83d\udccc Setup Guide for Backup Workflows to Git Repository on Gitea**\n\n#### **\ud83d\udd27 1. Configure Global Variables**\nGo to the **Globals** node and update the following:\n- **`repo.url`** \u2192 `https:\/\/your-gitea-instance.com` *(Replace with your actual Gitea URL)*\n- **`repo.name`** \u2192 `workflows` *(Repository name where backups will be stored)*\n- **`repo.owner`** \u2192 `octoleo` *(Gitea account that owns the repository)*\n\n\ud83d\udccc **These settings define where workflows will be backed up.**\n\n---\n\n#### **\ud83d\udd11 2. Set Up Gitea Authentication**\n1\ufe0f\u20e3 **In Gitea:**\n- Generate a **Personal Access Token** under **Settings \u2192 Applications \u2192 Generate Token**\n- Ensure the token has **repo read\/write permissions**\n\n2\ufe0f\u20e3 **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\ud83d\udccc **Ensure there is a space after `Bearer` before the token!**\n\n---\n\n#### **\ud83d\udd17 3. Connect Gitea Credentials to Git Nodes**\n- Open each of these **three Git nodes**:\n- **GetGitea** \u2192 Retrieves existing repository data\n- **PutGitea** \u2192 Updates workflows\n- **PostGitea** \u2192 Adds new workflows\n\n- Assign the **Gitea Token** credential to each node.\n\n\ud83d\udccc **These nodes handle pushing your workflows to Gitea.**\n\n---\n\n#### **\ud83c\udf10 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\ud83d\udccc **This ensures the workflow can fetch all available workflows from your system.**\n\n---\n\n#### **\ud83d\udee0\ufe0f 5. Test & Activate the Workflow**\n\u2705 **Run the workflow manually** \u2192 Check that workflows are being backed up correctly.\n\u2705 **Review the Gitea repository** \u2192 Ensure the files are updated.\n\u2705 **Enable the scheduled trigger** \u2192 Automates backups at defined intervals.\n\n\ud83d\udccc **The workflow automatically checks for changes before committing updates!**\n\n---\n\n### **\ud83d\ude80 Done! Your Workflows Are Now Backed Up Securely!**\n\ud83d\udcac 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": {
        "n8n": {
            "main": [
                [
                    {
                        "node": "ForEach",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Exist": {
            "main": [
                [
                    {
                        "node": "SetDataUpdateNode",
                        "type": "main",
                        "index": 0
                    }
                ],
                [
                    {
                        "node": "SetDataCreateNode",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Changed": {
            "main": [
                [
                    {
                        "node": "PutGitea",
                        "type": "main",
                        "index": 0
                    }
                ],
                [
                    {
                        "node": "ForEach",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "ForEach": {
            "main": [
                [],
                [
                    {
                        "node": "GetGitea",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Globals": {
            "main": [
                [
                    {
                        "node": "n8n",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "GetGitea": {
            "main": [
                [
                    {
                        "node": "Exist",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "PutGitea": {
            "main": [
                [
                    {
                        "node": "ForEach",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "PostGitea": {
            "main": [
                [
                    {
                        "node": "ForEach",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Schedule Trigger": {
            "main": [
                [
                    {
                        "node": "Globals",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "SetDataCreateNode": {
            "main": [
                [
                    {
                        "node": "Base64EncodeCreate",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "SetDataUpdateNode": {
            "main": [
                [
                    {
                        "node": "Base64EncodeUpdate",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Base64EncodeCreate": {
            "main": [
                [
                    {
                        "node": "PostGitea",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        },
        "Base64EncodeUpdate": {
            "main": [
                [
                    {
                        "node": "Changed",
                        "type": "main",
                        "index": 0
                    }
                ]
            ]
        }
    },
    "triggerCount": 1
}
Back to Workflows

Related Workflows

Stickynote Hackernews Automate Triggered
View
Extractfromfile Manual Process Webhook
View
Play with Spotify from Telegram
View
Code Filter Create Webhook
View
🔍🛠️ Tavily Search & Extract - Template
View
Airtable Create Triggered
View
🎥 Gemini AI Video Analysis
View
Spot Workplace Discrimination Patterns with AI
View
New WooCommerce refund to Slack
View
Format US Phone Number
View