{
  "meta": {
    "instanceId": "0cf1013c00750bfab7ca7f6a76bf0e8c2407d7a4a9a4e66c4888ec456837f043"
  },
  "nodes": [
    {
      "id": "66f1d868-3d2f-4d01-a44d-65a1683c60a2",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        960,
        -336
      ],
      "parameters": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 19
            }
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "6683f526-0831-457c-9b3d-9149b6aa72c4",
      "name": "Create Index File",
      "type": "n8n-nodes-base.github",
      "position": [
        1808,
        -176
      ],
      "webhookId": "b1c00612-30d6-402d-a737-b9d06e473053",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').item.json.repo_owner }}"
        },
        "filePath": "=index.json",
        "resource": "file",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').item.json.repo_name }}"
        },
        "fileContent": "{}",
        "commitMessage": "=Index (Created) {{ new Date().toISOString().split('T')[0] }}",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "UBHtZxEV1OPvxU9F",
          "name": "GitHub account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "ef2313ca-a8d4-4518-bd7e-72500c90a6bc",
      "name": "Get Download Url for Index File",
      "type": "n8n-nodes-base.github",
      "onError": "continueErrorOutput",
      "position": [
        1360,
        -336
      ],
      "webhookId": "6e7d3020-5558-4a80-9647-3c5a9de59a29",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $json.repo_owner }}"
        },
        "filePath": "index.json",
        "resource": "file",
        "operation": "get",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $json.repo_name }}"
        },
        "authentication": "oAuth2",
        "asBinaryProperty": false,
        "additionalParameters": {}
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "UBHtZxEV1OPvxU9F",
          "name": "GitHub account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "8643952a-3860-451c-96e3-4e4271c2bec0",
      "name": "Get Index File Content",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1584,
        -352
      ],
      "parameters": {
        "url": "={{ $json.download_url }}",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 4.2
    },
    {
      "id": "b4d05bc7-36de-4cf3-9ff0-dac7faff26a2",
      "name": "Index File Not Found",
      "type": "n8n-nodes-base.if",
      "position": [
        1584,
        -160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3e028766-cfb2-4464-9a97-b0845f082ed4",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.error }}",
              "rightValue": "=The resource you are requesting could not be found"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f5544061-062b-4a5a-b98b-f8c274e78104",
      "name": "Set Github Data",
      "type": "n8n-nodes-base.set",
      "position": [
        1168,
        -336
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "452d7af0-1a81-4426-a171-0379eb83f575",
              "name": "repo_owner",
              "type": "string",
              "value": "your-github-username"
            },
            {
              "id": "eed5e0e0-4a5e-4df9-adec-a266d175e40d",
              "name": "repo_name",
              "type": "string",
              "value": "your-github-repository-name"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "dfd491c1-6c20-4c99-801a-867d5b1e6376",
      "name": "When clicking ‘Execute workflow’",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        992,
        752
      ],
      "parameters": {},
      "typeVersion": 1
    },
    {
      "id": "fb17c3b6-5501-4f1f-bd78-10b39d3cc135",
      "name": "Wait",
      "type": "n8n-nodes-base.wait",
      "position": [
        2016,
        -176
      ],
      "webhookId": "6d7f1445-a6c5-4ebb-bae3-a4ebbeed5f95",
      "parameters": {
        "amount": 3
      },
      "typeVersion": 1.1
    },
    {
      "id": "8d2a68af-641f-43ff-96c0-5e4d1a3d419f",
      "name": "Get All Workflows",
      "type": "n8n-nodes-base.n8n",
      "position": [
        1792,
        -352
      ],
      "parameters": {
        "filters": {
          "excludePinnedData": true
        },
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "K60r3zn5x560PMdo",
          "name": "Github Backup"
        }
      },
      "executeOnce": false,
      "retryOnFail": true,
      "typeVersion": 1,
      "alwaysOutputData": true
    },
    {
      "id": "ca083a23-d014-4623-8375-a58ed5cc4a08",
      "name": "C,E,D Checker",
      "type": "n8n-nodes-base.code",
      "position": [
        2016,
        -352
      ],
      "parameters": {
        "jsCode": "// =======================\n// READ INPUTS\n// =======================\n\n// Current workflows from n8n\nconst workflows = $input.all()\n  .map(i => i.json)\n  .filter(w => w && typeof w.id === 'string' && typeof w.name === 'string');\n\nconst indexData = JSON.parse($('Get Index File Content').first()?.json?.data || '{}');\n\n// =======================\n// PREPARE STATE\n// =======================\n\nconst results = [];\nconst updatedIndex = { ...indexData };\n\n// Track only REAL workflow IDs from index\nconst existingIds = new Set(Object.keys(indexData));\n\n// =======================\n// STEP 1: CREATE / EDIT / RENAME\n// =======================\n\nfor (const workflow of workflows) {\n  const id = workflow.id;\n  const name = workflow.name || 'unnamed';\n  const path = `workflows/${name}.json`;\n\n  // -------- CREATE --------\n  if (!indexData[id]) {\n    updatedIndex[id] = { name, file_path: path };\n\n    results.push({\n      status: 'create',\n      workflowId: id,\n      name,\n      path,\n      data: workflow\n    });\n\n    continue;\n  }\n\n  // -------- RENAME --------\n  if (indexData[id].name !== name) {\n    // delete old file\n    results.push({\n      status: 'delete',\n      workflowId: id,\n      name: indexData[id].name,\n      path: indexData[id].file_path\n    });\n\n    // create new file\n    results.push({\n      status: 'create',\n      workflowId: id,\n      name,\n      path,\n      data: workflow\n    });\n\n    updatedIndex[id] = { name, file_path: path };\n    existingIds.delete(id);\n    continue;\n  }\n\n  // -------- EDIT --------\n  results.push({\n    status: 'edit',\n    workflowId: id,\n    name,\n    path: indexData[id].file_path,\n    data: workflow\n  });\n\n  existingIds.delete(id);\n}\n\n// =======================\n// STEP 2: DELETE REMOVED WORKFLOWS\n// =======================\n\nfor (const id of existingIds) {\n  results.push({\n    status: 'delete',\n    workflowId: id,\n    name: indexData[id].name,\n    path: indexData[id].file_path\n  });\n\n  delete updatedIndex[id];\n}\n\n// =======================\n// STEP 3: INDEX UPDATE (ONLY IF CHANGED)\n// =======================\n\nif (JSON.stringify(indexData) !== JSON.stringify(updatedIndex)) {\n  results.push({\n    status: 'index',\n    data: updatedIndex\n  });\n}\n\n// =======================\n// OUTPUT FOR N8N\n// =======================\n\nreturn results.map(r => ({ json: r }));"
      },
      "typeVersion": 2
    },
    {
      "id": "2ed6483e-158f-4865-aa19-8d9a6a9ad9a1",
      "name": "Create New Files",
      "type": "n8n-nodes-base.github",
      "position": [
        2544,
        -624
      ],
      "webhookId": "b1c00612-30d6-402d-a737-b9d06e473053",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').first().json.repo_owner }}"
        },
        "filePath": "={{ $json.path }}",
        "resource": "file",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').first().json.repo_name }}"
        },
        "fileContent": "={{ JSON.stringify($json.data, null, 2) }}",
        "commitMessage": "={{ $json.name }} (Created) {{ new Date().toISOString().split('T')[0] }}",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "UBHtZxEV1OPvxU9F",
          "name": "GitHub account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "61fedd05-149c-4257-9de2-5cc784009ade",
      "name": "Update Index File",
      "type": "n8n-nodes-base.github",
      "position": [
        2544,
        -64
      ],
      "webhookId": "0cfd3844-d625-413e-9760-c352d50d4c79",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').first().json.repo_owner }}"
        },
        "filePath": "index.json",
        "resource": "file",
        "operation": "edit",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').first().json.repo_name }}"
        },
        "fileContent": "={{ JSON.stringify($json.data, null, 2) }}",
        "commitMessage": "=Index (Edited) {{ new Date().toISOString().split('T')[0] }}",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "UBHtZxEV1OPvxU9F",
          "name": "GitHub account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "0df1da12-7855-43c5-a039-7f9ec057ca4f",
      "name": "Get Download Url for Github File",
      "type": "n8n-nodes-base.github",
      "position": [
        2544,
        -464
      ],
      "webhookId": "6e7d3020-5558-4a80-9647-3c5a9de59a29",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').first().json.repo_owner }}"
        },
        "filePath": "={{ $json.path }}",
        "resource": "file",
        "operation": "get",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').first().json.repo_name }}"
        },
        "authentication": "oAuth2",
        "asBinaryProperty": false,
        "additionalParameters": {}
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "UBHtZxEV1OPvxU9F",
          "name": "GitHub account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "3b665fc8-6273-4223-ab7a-b1ab1cb524f8",
      "name": "Switch",
      "type": "n8n-nodes-base.switch",
      "position": [
        2224,
        -384
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Create",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "97023852-faa0-4c13-91fc-7d080beae826",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "create"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Edit",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "ae9ec2ae-f5d7-47be-85a5-7c13cf4b6688",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "edit"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Delete",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "8f1e5618-6223-4ad3-afc8-b8e8d74b8f05",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "delete"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Update Index",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "b548ed0b-878d-45da-80c7-28347fa3d555",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "index"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.3
    },
    {
      "id": "4ca08961-1c75-4d40-8f85-203ef0e5ce1c",
      "name": "Delete Files",
      "type": "n8n-nodes-base.github",
      "position": [
        2544,
        -240
      ],
      "webhookId": "b1c00612-30d6-402d-a737-b9d06e473053",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').first().json.repo_owner }}"
        },
        "filePath": "={{ $json.path }}",
        "resource": "file",
        "operation": "delete",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').first().json.repo_name }}"
        },
        "commitMessage": "={{ $json.name }} (Deleted) {{ new Date().toISOString().split('T')[0] }}",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "UBHtZxEV1OPvxU9F",
          "name": "GitHub account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "d9be1383-2cbe-467d-95b6-5193fd01080e",
      "name": "Get Github File Content",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2800,
        -464
      ],
      "parameters": {
        "url": "={{ $json.download_url }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "a8b185c6-dd27-407a-8156-8fd3b10bbb65",
      "name": "Parse Github File Content",
      "type": "n8n-nodes-base.code",
      "position": [
        3024,
        -464
      ],
      "parameters": {
        "jsCode": "return $input.all().map(i => ({\n  json: {\n    githubData: JSON.parse(i.json.data || '{}')\n  }\n}));"
      },
      "typeVersion": 2
    },
    {
      "id": "a54da607-6234-4661-960e-1954b72d28a9",
      "name": "File Edit Checker",
      "type": "n8n-nodes-base.code",
      "position": [
        3472,
        -448
      ],
      "parameters": {
        "jsCode": "const normalize = (obj) =>\n  JSON.stringify(obj, (_, value) =>\n    value && typeof value === 'object' && !Array.isArray(value)\n      ? Object.keys(value)\n          .sort()\n          .reduce((o, k) => {\n            o[k] = value[k];\n            return o;\n          }, {})\n      : value\n  );\n\nreturn $input.all()\n  .filter(item =>\n    normalize(item.json.githubData) !== normalize(item.json.data)\n  )\n  .map(item => {\n    const { githubData, ...rest } = item.json;\n    return { json: rest };\n  });"
      },
      "executeOnce": false,
      "typeVersion": 2,
      "alwaysOutputData": true
    },
    {
      "id": "a830aab5-48fe-4e9f-a836-6a70dce2d625",
      "name": "Merge Github & n8n File",
      "type": "n8n-nodes-base.merge",
      "position": [
        3248,
        -448
      ],
      "parameters": {
        "mode": "combine",
        "options": {},
        "combineBy": "combineByPosition"
      },
      "typeVersion": 3.2
    },
    {
      "id": "623fafcc-e4c7-4643-bfde-6b618cb39bd7",
      "name": "If File Edited",
      "type": "n8n-nodes-base.if",
      "position": [
        3696,
        -448
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "7f597ed3-ce0c-4830-97b8-3a07e9dda11f",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              },
              "leftValue": "={{ $json.status !== null && $json.status !== undefined }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "00098dfc-2bc6-4492-9562-8122a536954f",
      "name": "Edit Files",
      "type": "n8n-nodes-base.github",
      "position": [
        3920,
        -464
      ],
      "webhookId": "0cfd3844-d625-413e-9760-c352d50d4c79",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').first().json.repo_owner }}"
        },
        "filePath": "={{ $json.path }}",
        "resource": "file",
        "operation": "edit",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Set Github Data').first().json.repo_name }}"
        },
        "fileContent": "={{ JSON.stringify($json.data, null, 2) }}",
        "commitMessage": "={{ $json.name }} (Edited) {{ new Date().toISOString().split('T')[0] }}",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "UBHtZxEV1OPvxU9F",
          "name": "GitHub account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "23b09a8a-983f-477f-be9a-96fe59dca49f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        -896
      ],
      "parameters": {
        "color": 7,
        "width": 3270,
        "height": 1443,
        "content": "# n8n-Workflow-Github-Backup"
      },
      "typeVersion": 1
    },
    {
      "id": "81fe00c0-4469-4f57-a8e7-441b5619b754",
      "name": "Workflow Summary",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        320,
        -48
      ],
      "parameters": {
        "color": 2,
        "width": 512,
        "height": 416,
        "content": "## 📋 WORKFLOW SUMMARY\n\n**Purpose:** Automatically backup n8n workflows to GitHub\n\n**Flow:**\n1. Trigger (Schedule/Manual)\n2. Get/Create index.json in GitHub\n3. Fetch all n8n workflows\n4. Compare with GitHub index\n5. Create/Edit/Delete files as needed\n6. Update index.json\n\n\n**Features:**\n- Daily automatic backups (7 PM)\n- Detects new, edited, renamed, and deleted workflows\n- Maintains an index for tracking\n- Smart comparison to avoid unnecessary commits"
      },
      "typeVersion": 1
    },
    {
      "id": "8d64b719-713f-4f0c-9054-55707357fab2",
      "name": "Setup Requirements",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        320,
        -704
      ],
      "parameters": {
        "color": 4,
        "width": 500,
        "height": 608,
        "content": "## ⚙️ SETUP REQUIREMENTS\n\n**1️⃣ GitHub OAuth Credentials**\n- Go to *Credentials → New → GitHub OAuth2*\n- Create GitHub OAuth App:\n  - Settings → Developer settings → OAuth Apps\n  - Authorization callback URL: your n8n instance\n  - Enter Client ID & Secret in n8n\n\n\n**2️⃣ GitHub Repository**\n- Create a new repository (public/private)\n- Copy repository owner and name\n\n\n**3️⃣ Configure Workflow**\n- Edit \"Set Github Data\" node:\n  - `repo_owner`: your GitHub username\n  - `repo_name`: your repository name\n- Connect GitHub OAuth credentials to all GitHub nodes\n\n\n**4️⃣ n8n API Credentials**\n- Go to *Settings → API*\n- Create new API key\n- Add as n8n credential in workflow\n\n✅ Test manually before enabling schedule"
      },
      "typeVersion": 1
    },
    {
      "id": "3fd029b9-9573-4f10-b464-333728f5791a",
      "name": "Index System",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1632,
        32
      ],
      "parameters": {
        "color": 5,
        "width": 420,
        "height": 472,
        "content": "## 📂 INDEX SYSTEM\n\n**index.json structure:**\n```json\n{\n  \"workflow_id_1\": {\n    \"name\": \"Workflow Name\",\n    \"file_path\": \"workflows/Workflow Name.json\"\n  },\n  \"workflow_id_2\": { ... }\n}\n```\n\n**Purpose:**\n- Tracks which workflows exist in GitHub\n- Maps workflow IDs to file paths\n- Enables detection of renames and deletes\n\n**First Run:**\n- If index.json doesn't exist, it's created automatically\n- 3-second wait allows file creation to complete"
      },
      "typeVersion": 1
    },
    {
      "id": "9ab1adc8-5de8-4eba-9128-aed991abae8c",
      "name": "C,E,D Checker Logic",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1808,
        -848
      ],
      "parameters": {
        "color": 6,
        "width": 400,
        "height": 456,
        "content": "## 🔍 C,E,D CHECKER\n\n**Compare & Decision Logic:**\n\nFor each n8n workflow:\n- **CREATE:** New workflow not in index\n- **RENAME:** Workflow name changed\n  - Deletes old file\n  - Creates new file with new name\n- **EDIT:** Existing workflow (checked later for actual changes)\n\n\nFor workflows in index but not in n8n:\n- **DELETE:** Workflow removed from n8n\n\n\nFor index itself:\n- **UPDATE INDEX:** If any changes detected\n\n**Output:** Array of actions to take"
      },
      "typeVersion": 1
    },
    {
      "id": "3e687dee-c761-4cfc-b7b0-301e414a0cf8",
      "name": "Switch Routing",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2128,
        16
      ],
      "parameters": {
        "color": 7,
        "width": 360,
        "height": 496,
        "content": "## 🔀 SWITCH ROUTING\n\nRoutes items based on status:\n\n**Create Branch:**\n- New workflows → Create New Files\n\n\n**Edit Branch:**\n- Existing workflows → Smart edit check\n- Fetches GitHub version\n- Compares with n8n version\n- Only commits if actually different\n\n\n**Delete Branch:**\n- Removed workflows → Delete Files\n\n\n**Update Index Branch:**\n- Index changed → Update Index File\n\n\nEach branch processes independently."
      },
      "typeVersion": 1
    },
    {
      "id": "fc8aa3ca-ab5b-463a-ba87-40a10e7486e1",
      "name": "Smart Edit Detection",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        3456,
        -288
      ],
      "parameters": {
        "color": 6,
        "width": 380,
        "height": 428,
        "content": "## ✏️ SMART EDIT DETECTION\n\n**Why needed:**\n- n8n changes timestamps/metadata on save\n- Prevents unnecessary commits\n\n\n**Process:**\n1. Fetch current file from GitHub\n2. Parse both GitHub & n8n versions\n3. Normalize JSON (sort keys)\n4. Compare stringified versions\n5. Only commit if truly different\n\n\n**Benefits:**\n- Cleaner commit history\n- No spam commits\n- Saves GitHub API calls"
      },
      "typeVersion": 1
    },
    {
      "id": "52fef552-2ada-4451-8909-08dcc301a6d2",
      "name": "Commit Messages",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2832,
        -240
      ],
      "parameters": {
        "color": 3,
        "width": 360,
        "height": 404,
        "content": "## 📝 COMMIT MESSAGES\n\nAuto-generated commit messages:\n\n**Format:** `[Workflow Name] ([Action]) YYYY-MM-DD`\n\n**Examples:**\n- `My Workflow (Created) 2026-01-15`\n- `My Workflow (Edited) 2026-01-15`\n- `My Workflow (Deleted) 2026-01-15`\n- `Index (Edited) 2026-01-15`\n\n\n**Benefits:**\n- Clear action history\n- Easy to track changes\n- Searchable by date"
      },
      "typeVersion": 1
    },
    {
      "id": "a9f5ca79-fb19-436b-92e7-87f167759636",
      "name": "Workflows Folder Not Found",
      "type": "n8n-nodes-base.if",
      "position": [
        1632,
        976
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3e028766-cfb2-4464-9a97-b0845f082ed4",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.error }}",
              "rightValue": "=The resource you are requesting could not be found"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "a2bb07be-ea57-4098-8f2e-94b62cdaf00b",
      "name": "Loop Over Items",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        1632,
        736
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    },
    {
      "id": "0715c423-09e1-4743-84bf-0c3f133810e5",
      "name": "Get File Content",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1872,
        752
      ],
      "parameters": {
        "url": "={{ $json.download_url }}",
        "options": {}
      },
      "retryOnFail": true,
      "typeVersion": 4.2
    },
    {
      "id": "bff04c86-1ace-4b5b-9ab6-bbe4f146846b",
      "name": "List Workflow Files",
      "type": "n8n-nodes-base.github",
      "onError": "continueErrorOutput",
      "position": [
        1408,
        752
      ],
      "webhookId": "b4034155-275a-407e-8168-e9e9c7b1babe",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $json.repo_owner }}"
        },
        "filePath": "workflows/",
        "resource": "file",
        "operation": "list",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $json.repo_name }}"
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "UBHtZxEV1OPvxU9F",
          "name": "GitHub account"
        }
      },
      "retryOnFail": true,
      "typeVersion": 1.1
    },
    {
      "id": "1ec8abd6-051a-411f-a889-15bc605a8afb",
      "name": "Create Workflow",
      "type": "n8n-nodes-base.n8n",
      "position": [
        2096,
        752
      ],
      "parameters": {
        "operation": "create",
        "requestOptions": {},
        "workflowObject": "={{ $json.data }}"
      },
      "credentials": {
        "n8nApi": {
          "id": "K60r3zn5x560PMdo",
          "name": "Github Backup"
        }
      },
      "executeOnce": false,
      "retryOnFail": true,
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "e839c8ca-d8cc-47cb-9ceb-05b9235e6e94",
      "name": "How It Works",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1136,
        944
      ],
      "parameters": {
        "color": 6,
        "width": 400,
        "height": 284,
        "content": "## 🔄 HOW IT WORKS\n\n**Sequential Processing:**\n- Loops through files one at a time\n- Downloads JSON from GitHub\n- Creates workflow in n8n\n- Prevents conflicts and rate limits\n\n**Error Handling:**\n- If `workflows/` folder not found → stops gracefully\n- Ensure backup workflow ran at least once first"
      },
      "typeVersion": 1
    },
    {
      "id": "782b9b5e-067b-4fb1-ba54-64d2f6c813c4",
      "name": "Set Github Data1",
      "type": "n8n-nodes-base.set",
      "position": [
        1200,
        752
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "452d7af0-1a81-4426-a171-0379eb83f575",
              "name": "repo_owner",
              "type": "string",
              "value": "your-github-username"
            },
            {
              "id": "eed5e0e0-4a5e-4df9-adec-a266d175e40d",
              "name": "repo_name",
              "type": "string",
              "value": "your-github-repository-name"
            }
          ]
        }
      },
      "typeVersion": 3.4
    },
    {
      "id": "a02ef593-96ca-42d1-b072-e96d82b044f8",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        592
      ],
      "parameters": {
        "color": 7,
        "width": 1494,
        "height": 675,
        "content": "# n8n-Workflow-Github-Restore"
      },
      "typeVersion": 1
    },
    {
      "id": "9910bb0d-581e-4a82-94ad-3e2066c99625",
      "name": "Workflow Summary1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        416,
        592
      ],
      "parameters": {
        "color": 2,
        "width": 416,
        "height": 372,
        "content": "## 📋 WORKFLOW SUMMARY\n\n**Purpose:** Restore n8n workflows from GitHub backup\n\n**Flow:**\n1. Manual trigger\n2. Set GitHub repo details\n3. List workflow files from GitHub\n4. Loop through each file\n5. Download & create workflow in n8n\n\n\n**Use Cases:**\n- New n8n instance setup\n- Disaster recovery\n- Cloning workflows to another environment"
      },
      "typeVersion": 1
    }
  ],
  "pinData": {},
  "connections": {
    "Wait": {
      "main": [
        [
          {
            "node": "Set Github Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Switch": {
      "main": [
        [
          {
            "node": "Create New Files",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Get Download Url for Github File",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge Github & n8n File",
            "type": "main",
            "index": 1
          }
        ],
        [
          {
            "node": "Delete Files",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Update Index File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "C,E,D Checker": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If File Edited": {
      "main": [
        [
          {
            "node": "Edit Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Workflow": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Get File Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Github Data": {
      "main": [
        [
          {
            "node": "Get Download Url for Index File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get File Content": {
      "main": [
        [
          {
            "node": "Create Workflow",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Set Github Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Github Data1": {
      "main": [
        [
          {
            "node": "List Workflow Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Index File": {
      "main": [
        [
          {
            "node": "Wait",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File Edit Checker": {
      "main": [
        [
          {
            "node": "If File Edited",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get All Workflows": {
      "main": [
        [
          {
            "node": "C,E,D Checker",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "List Workflow Files": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Workflows Folder Not Found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Index File Not Found": {
      "main": [
        [
          {
            "node": "Create Index File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Index File Content": {
      "main": [
        [
          {
            "node": "Get All Workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Github File Content": {
      "main": [
        [
          {
            "node": "Parse Github File Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Github & n8n File": {
      "main": [
        [
          {
            "node": "File Edit Checker",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Github File Content": {
      "main": [
        [
          {
            "node": "Merge Github & n8n File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Download Url for Index File": {
      "main": [
        [
          {
            "node": "Get Index File Content",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Index File Not Found",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Download Url for Github File": {
      "main": [
        [
          {
            "node": "Get Github File Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Execute workflow’": {
      "main": [
        [
          {
            "node": "Set Github Data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}