AutomationFlowsWeb Scraping › Automated GitHub Repository Manager

Automated GitHub Repository Manager

Original n8n title: N8n Workflow Github Manager

N8N-Workflow-Github-Manager. Uses github, httpRequest, n8n. Scheduled trigger; 38 nodes.

Cron / scheduled trigger★★★★★ complexity38 nodesGitHubHTTP Requestn8n
Web Scraping Trigger: Cron / scheduled Nodes: 38 Complexity: ★★★★★ Added:

This workflow follows the GitHub → HTTP Request 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": {
        "rule": {
          "interval": [
            {
              "triggerAtHour": 19
            }
          ]
        }
      },
      "id": "66f1d868-3d2f-4d01-a44d-65a1683c60a2",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        960,
        -336
      ],
      "typeVersion": 1.2
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "owner": {
          "__rl": true,
          "value": "={{ $('Set Github Data').item.json.repo_owner }}",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "={{ $('Set Github Data').item.json.repo_name }}",
          "mode": "name"
        },
        "filePath": "=index.json",
        "fileContent": "{}",
        "commitMessage": "=Index (Created) {{ new Date().toISOString().split('T')[0] }}"
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        1808,
        -176
      ],
      "id": "6683f526-0831-457c-9b3d-9149b6aa72c4",
      "name": "Create Index File",
      "retryOnFail": true,
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "operation": "get",
        "owner": {
          "__rl": true,
          "value": "={{ $json.repo_owner }}",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "={{ $json.repo_name }}",
          "mode": "name"
        },
        "filePath": "index.json",
        "asBinaryProperty": false,
        "additionalParameters": {}
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        1360,
        -336
      ],
      "id": "ef2313ca-a8d4-4518-bd7e-72500c90a6bc",
      "name": "Get Download Url for Index File",
      "retryOnFail": true,
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "url": "={{ $json.download_url }}",
        "options": {}
      },
      "id": "8643952a-3860-451c-96e3-4e4271c2bec0",
      "name": "Get Index File Content",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1584,
        -352
      ],
      "typeVersion": 4.2,
      "retryOnFail": true
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "3e028766-cfb2-4464-9a97-b0845f082ed4",
              "leftValue": "={{ $json.error }}",
              "rightValue": "=The resource you are requesting could not be found",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1584,
        -160
      ],
      "id": "b4d05bc7-36de-4cf3-9ff0-dac7faff26a2",
      "name": "Index File Not Found"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "452d7af0-1a81-4426-a171-0379eb83f575",
              "name": "repo_owner",
              "value": "your-github-username",
              "type": "string"
            },
            {
              "id": "eed5e0e0-4a5e-4df9-adec-a266d175e40d",
              "name": "repo_name",
              "value": "your-github-repository-name",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1168,
        -336
      ],
      "id": "f5544061-062b-4a5a-b98b-f8c274e78104",
      "name": "Set Github Data"
    },
    {
      "parameters": {},
      "type": "n8n-nodes-base.manualTrigger",
      "typeVersion": 1,
      "position": [
        992,
        752
      ],
      "id": "dfd491c1-6c20-4c99-801a-867d5b1e6376",
      "name": "When clicking \u2018Execute workflow\u2019"
    },
    {
      "parameters": {
        "amount": 3
      },
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1.1,
      "position": [
        2016,
        -176
      ],
      "id": "fb17c3b6-5501-4f1f-bd78-10b39d3cc135",
      "name": "Wait"
    },
    {
      "parameters": {
        "filters": {
          "excludePinnedData": true
        },
        "requestOptions": {}
      },
      "id": "8d2a68af-641f-43ff-96c0-5e4d1a3d419f",
      "name": "Get All Workflows",
      "type": "n8n-nodes-base.n8n",
      "position": [
        1792,
        -352
      ],
      "typeVersion": 1,
      "executeOnce": false,
      "retryOnFail": true,
      "alwaysOutputData": true,
      "credentials": {
        "n8nApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "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 }));"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        2016,
        -352
      ],
      "id": "ca083a23-d014-4623-8375-a58ed5cc4a08",
      "name": "C,E,D Checker"
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "owner": {
          "__rl": true,
          "value": "={{ $('Set Github Data').first().json.repo_owner }}",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "={{ $('Set Github Data').first().json.repo_name }}",
          "mode": "name"
        },
        "filePath": "={{ $json.path }}",
        "fileContent": "={{ JSON.stringify($json.data, null, 2) }}",
        "commitMessage": "={{ $json.name }} (Created) {{ new Date().toISOString().split('T')[0] }}"
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        2544,
        -624
      ],
      "id": "2ed6483e-158f-4865-aa19-8d9a6a9ad9a1",
      "name": "Create New Files",
      "retryOnFail": true,
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "operation": "edit",
        "owner": {
          "__rl": true,
          "value": "={{ $('Set Github Data').first().json.repo_owner }}",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "={{ $('Set Github Data').first().json.repo_name }}",
          "mode": "name"
        },
        "filePath": "index.json",
        "fileContent": "={{ JSON.stringify($json.data, null, 2) }}",
        "commitMessage": "=Index (Edited) {{ new Date().toISOString().split('T')[0] }}"
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        2544,
        -64
      ],
      "id": "61fedd05-149c-4257-9de2-5cc784009ade",
      "name": "Update Index File",
      "retryOnFail": true,
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "operation": "get",
        "owner": {
          "__rl": true,
          "value": "={{ $('Set Github Data').first().json.repo_owner }}",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "={{ $('Set Github Data').first().json.repo_name }}",
          "mode": "name"
        },
        "filePath": "={{ $json.path }}",
        "asBinaryProperty": false,
        "additionalParameters": {}
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        2544,
        -464
      ],
      "id": "0df1da12-7855-43c5-a039-7f9ec057ca4f",
      "name": "Get Download Url for Github File",
      "retryOnFail": true,
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "rules": {
          "values": [
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "create",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "id": "97023852-faa0-4c13-91fc-7d080beae826"
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Create"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "ae9ec2ae-f5d7-47be-85a5-7c13cf4b6688",
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "edit",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Edit"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "8f1e5618-6223-4ad3-afc8-b8e8d74b8f05",
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "delete",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Delete"
            },
            {
              "conditions": {
                "options": {
                  "caseSensitive": true,
                  "leftValue": "",
                  "typeValidation": "strict",
                  "version": 2
                },
                "conditions": [
                  {
                    "id": "b548ed0b-878d-45da-80c7-28347fa3d555",
                    "leftValue": "={{ $json.status }}",
                    "rightValue": "index",
                    "operator": {
                      "type": "string",
                      "operation": "equals",
                      "name": "filter.operator.equals"
                    }
                  }
                ],
                "combinator": "and"
              },
              "renameOutput": true,
              "outputKey": "Update Index"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3.3,
      "position": [
        2224,
        -384
      ],
      "id": "3b665fc8-6273-4223-ab7a-b1ab1cb524f8",
      "name": "Switch"
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "operation": "delete",
        "owner": {
          "__rl": true,
          "value": "={{ $('Set Github Data').first().json.repo_owner }}",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "={{ $('Set Github Data').first().json.repo_name }}",
          "mode": "name"
        },
        "filePath": "={{ $json.path }}",
        "commitMessage": "={{ $json.name }} (Deleted) {{ new Date().toISOString().split('T')[0] }}"
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        2544,
        -240
      ],
      "id": "4ca08961-1c75-4d40-8f85-203ef0e5ce1c",
      "name": "Delete Files",
      "retryOnFail": true,
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "url": "={{ $json.download_url }}",
        "options": {}
      },
      "id": "d9be1383-2cbe-467d-95b6-5193fd01080e",
      "name": "Get Github File Content",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2800,
        -464
      ],
      "typeVersion": 4.2
    },
    {
      "parameters": {
        "jsCode": "return $input.all().map(i => ({\n  json: {\n    githubData: JSON.parse(i.json.data || '{}')\n  }\n}));"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3024,
        -464
      ],
      "id": "a8b185c6-dd27-407a-8156-8fd3b10bbb65",
      "name": "Parse Github File Content"
    },
    {
      "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  });"
      },
      "type": "n8n-nodes-base.code",
      "typeVersion": 2,
      "position": [
        3472,
        -448
      ],
      "id": "a54da607-6234-4661-960e-1954b72d28a9",
      "name": "File Edit Checker",
      "executeOnce": false,
      "alwaysOutputData": true
    },
    {
      "parameters": {
        "mode": "combine",
        "combineBy": "combineByPosition",
        "options": {}
      },
      "type": "n8n-nodes-base.merge",
      "typeVersion": 3.2,
      "position": [
        3248,
        -448
      ],
      "id": "a830aab5-48fe-4e9f-a836-6a70dce2d625",
      "name": "Merge Github & n8n File"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "7f597ed3-ce0c-4830-97b8-3a07e9dda11f",
              "leftValue": "={{ $json.status !== null && $json.status !== undefined }}",
              "rightValue": "",
              "operator": {
                "type": "boolean",
                "operation": "true",
                "singleValue": true
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        3696,
        -448
      ],
      "id": "623fafcc-e4c7-4643-bfde-6b618cb39bd7",
      "name": "If File Edited"
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "operation": "edit",
        "owner": {
          "__rl": true,
          "value": "={{ $('Set Github Data').first().json.repo_owner }}",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "={{ $('Set Github Data').first().json.repo_name }}",
          "mode": "name"
        },
        "filePath": "={{ $json.path }}",
        "fileContent": "={{ JSON.stringify($json.data, null, 2) }}",
        "commitMessage": "={{ $json.name }} (Edited) {{ new Date().toISOString().split('T')[0] }}"
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        3920,
        -464
      ],
      "id": "00098dfc-2bc6-4492-9562-8122a536954f",
      "name": "Edit Files",
      "retryOnFail": true,
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "# n8n-Workflow-Github-Backup",
        "height": 1443,
        "width": 3270,
        "color": 7
      },
      "id": "23b09a8a-983f-477f-be9a-96fe59dca49f",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        -896
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "content": "## \ud83d\udccb 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",
        "height": 416,
        "width": 512,
        "color": 2
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        320,
        -48
      ],
      "id": "81fe00c0-4469-4f57-a8e7-441b5619b754",
      "name": "Workflow Summary"
    },
    {
      "parameters": {
        "content": "## \u2699\ufe0f SETUP REQUIREMENTS\n\n**1\ufe0f\u20e3 GitHub OAuth Credentials**\n- Go to *Credentials \u2192 New \u2192 GitHub OAuth2*\n- Create GitHub OAuth App:\n  - Settings \u2192 Developer settings \u2192 OAuth Apps\n  - Authorization callback URL: your n8n instance\n  - Enter Client ID & Secret in n8n\n\n\n**2\ufe0f\u20e3 GitHub Repository**\n- Create a new repository (public/private)\n- Copy repository owner and name\n\n\n**3\ufe0f\u20e3 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\ufe0f\u20e3 n8n API Credentials**\n- Go to *Settings \u2192 API*\n- Create new API key\n- Add as n8n credential in workflow\n\n\u2705 Test manually before enabling schedule",
        "height": 608,
        "width": 500,
        "color": 4
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        320,
        -704
      ],
      "id": "8d64b719-713f-4f0c-9054-55707357fab2",
      "name": "Setup Requirements"
    },
    {
      "parameters": {
        "content": "## \ud83d\udcc2 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",
        "height": 472,
        "width": 420,
        "color": 5
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1632,
        32
      ],
      "id": "3fd029b9-9573-4f10-b464-333728f5791a",
      "name": "Index System"
    },
    {
      "parameters": {
        "content": "## \ud83d\udd0d 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",
        "height": 456,
        "width": 400,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1808,
        -848
      ],
      "id": "9ab1adc8-5de8-4eba-9128-aed991abae8c",
      "name": "C,E,D Checker Logic"
    },
    {
      "parameters": {
        "content": "## \ud83d\udd00 SWITCH ROUTING\n\nRoutes items based on status:\n\n**Create Branch:**\n- New workflows \u2192 Create New Files\n\n\n**Edit Branch:**\n- Existing workflows \u2192 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 \u2192 Delete Files\n\n\n**Update Index Branch:**\n- Index changed \u2192 Update Index File\n\n\nEach branch processes independently.",
        "height": 496,
        "width": 360,
        "color": 7
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        2128,
        16
      ],
      "id": "3e687dee-c761-4cfc-b7b0-301e414a0cf8",
      "name": "Switch Routing"
    },
    {
      "parameters": {
        "content": "## \u270f\ufe0f 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",
        "height": 428,
        "width": 380,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        3456,
        -288
      ],
      "id": "fc8aa3ca-ab5b-463a-ba87-40a10e7486e1",
      "name": "Smart Edit Detection"
    },
    {
      "parameters": {
        "content": "## \ud83d\udcdd 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",
        "height": 404,
        "width": 360,
        "color": 3
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        2832,
        -240
      ],
      "id": "52fef552-2ada-4451-8909-08dcc301a6d2",
      "name": "Commit Messages"
    },
    {
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": true,
            "leftValue": "",
            "typeValidation": "strict",
            "version": 2
          },
          "conditions": [
            {
              "id": "3e028766-cfb2-4464-9a97-b0845f082ed4",
              "leftValue": "={{ $json.error }}",
              "rightValue": "=The resource you are requesting could not be found",
              "operator": {
                "type": "string",
                "operation": "equals",
                "name": "filter.operator.equals"
              }
            }
          ],
          "combinator": "and"
        },
        "options": {}
      },
      "type": "n8n-nodes-base.if",
      "typeVersion": 2.2,
      "position": [
        1632,
        976
      ],
      "id": "a9f5ca79-fb19-436b-92e7-87f167759636",
      "name": "Workflows Folder Not Found"
    },
    {
      "parameters": {
        "options": {}
      },
      "type": "n8n-nodes-base.splitInBatches",
      "typeVersion": 3,
      "position": [
        1632,
        736
      ],
      "id": "a2bb07be-ea57-4098-8f2e-94b62cdaf00b",
      "name": "Loop Over Items"
    },
    {
      "parameters": {
        "url": "={{ $json.download_url }}",
        "options": {}
      },
      "id": "0715c423-09e1-4743-84bf-0c3f133810e5",
      "name": "Get File Content",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1872,
        752
      ],
      "typeVersion": 4.2,
      "retryOnFail": true
    },
    {
      "parameters": {
        "authentication": "oAuth2",
        "resource": "file",
        "operation": "list",
        "owner": {
          "__rl": true,
          "value": "={{ $json.repo_owner }}",
          "mode": "name"
        },
        "repository": {
          "__rl": true,
          "value": "={{ $json.repo_name }}",
          "mode": "name"
        },
        "filePath": "workflows/"
      },
      "type": "n8n-nodes-base.github",
      "typeVersion": 1.1,
      "position": [
        1408,
        752
      ],
      "id": "bff04c86-1ace-4b5b-9ab6-bbe4f146846b",
      "name": "List Workflow Files",
      "retryOnFail": true,
      "credentials": {
        "githubOAuth2Api": {
          "name": "<your credential>"
        }
      },
      "onError": "continueErrorOutput"
    },
    {
      "parameters": {
        "operation": "create",
        "workflowObject": "={{ $json.data }}",
        "requestOptions": {}
      },
      "id": "1ec8abd6-051a-411f-a889-15bc605a8afb",
      "name": "Create Workflow",
      "type": "n8n-nodes-base.n8n",
      "position": [
        2096,
        752
      ],
      "typeVersion": 1,
      "executeOnce": false,
      "retryOnFail": true,
      "alwaysOutputData": false,
      "credentials": {
        "n8nApi": {
          "name": "<your credential>"
        }
      }
    },
    {
      "parameters": {
        "content": "## \ud83d\udd04 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 \u2192 stops gracefully\n- Ensure backup workflow ran at least once first",
        "height": 284,
        "width": 400,
        "color": 6
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        1136,
        944
      ],
      "id": "e839c8ca-d8cc-47cb-9ceb-05b9235e6e94",
      "name": "How It Works"
    },
    {
      "parameters": {
        "assignments": {
          "assignments": [
            {
              "id": "452d7af0-1a81-4426-a171-0379eb83f575",
              "name": "repo_owner",
              "value": "your-github-username",
              "type": "string"
            },
            {
              "id": "eed5e0e0-4a5e-4df9-adec-a266d175e40d",
              "name": "repo_name",
              "value": "your-github-repository-name",
              "type": "string"
            }
          ]
        },
        "options": {}
      },
      "type": "n8n-nodes-base.set",
      "typeVersion": 3.4,
      "position": [
        1200,
        752
      ],
      "id": "782b9b5e-067b-4fb1-ba54-64d2f6c813c4",
      "name": "Set Github Data1"
    },
    {
      "parameters": {
        "content": "# n8n-Workflow-Github-Restore",
        "height": 675,
        "width": 1494,
        "color": 7
      },
      "id": "a02ef593-96ca-42d1-b072-e96d82b044f8",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        864,
        592
      ],
      "typeVersion": 1
    },
    {
      "parameters": {
        "content": "## \ud83d\udccb 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",
        "height": 372,
        "width": 416,
        "color": 2
      },
      "type": "n8n-nodes-base.stickyNote",
      "typeVersion": 1,
      "position": [
        416,
        592
      ],
      "id": "9910bb0d-581e-4a82-94ad-3e2066c99625",
      "name": "Workflow Summary1"
    }
  ],
  "connections": {
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Set Github Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Index File": {
      "main": [
        [
          {
            "node": "Wait",
            "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 Index File Content": {
      "main": [
        [
          {
            "node": "Get All Workflows",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Index File Not Found": {
      "main": [
        [
          {
            "node": "Create Index File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Github Data": {
      "main": [
        [
          {
            "node": "Get Download Url for Index File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking \u2018Execute workflow\u2019": {
      "main": [
        [
          {
            "node": "Set Github Data1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait": {
      "main": [
        [
          {
            "node": "Set Github Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get All Workflows": {
      "main": [
        [
          {
            "node": "C,E,D Checker",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "C,E,D Checker": {
      "main": [
        [
          {
            "node": "Switch",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Download Url for Github File": {
      "main": [
        [
          {
            "node": "Get Github File Content",
            "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
          }
        ]
      ]
    },
    "Get Github File Content": {
      "main": [
        [
          {
            "node": "Parse Github File Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Parse Github File Content": {
      "main": [
        [
          {
            "node": "Merge Github & n8n File",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "File Edit Checker": {
      "main": [
        [
          {
            "node": "If File Edited",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge Github & n8n File": {
      "main": [
        [
          {
            "node": "File Edit Checker",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "If File Edited": {
      "main": [
        [
          {
            "node": "Edit Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Loop Over Items": {
      "main": [
        [],
        [
          {
            "node": "Get File Content",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get File Content": {
      "main": [
        [
          {
            "node": "Create Workflow",
            "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
          }
        ]
      ]
    },
    "Create Workflow": {
      "main": [
        [
          {
            "node": "Loop Over Items",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Github Data1": {
      "main": [
        [
          {
            "node": "List Workflow Files",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}

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

N8N-Workflow-Github-Manager. Uses github, httpRequest, n8n. Scheduled trigger; 38 nodes.

Source: https://github.com/anas-farooq8/n8n-Workflow-Github-Manager/blob/main/n8n-Workflow-Github-Manager.json — original creator credit. Request a take-down →

More Web Scraping workflows → · Browse all categories →

Related workflows

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

Web Scraping

This n8n template provides enterprise-level version control for your workflows using GitHub integration. Stop losing hours to broken workflows and manual exports – get proper commit history, visual di

n8n, Execute Workflow Trigger, HTTP Request +1
Web Scraping

As n8n instances scale, teams often lose track of sub-workflows—who uses them, where they are referenced, and whether they can be safely updated. This leads to inefficiencies like unnecessary copies o

HTTP Request, n8n, N8N Trigger +1
Web Scraping

Git Commit. Uses github, n8n, formTrigger, httpRequest. Event-driven trigger; 34 nodes.

GitHub, n8n, Form Trigger +2
Web Scraping

Remixed Backup your workflows to GitHub from Solomon's work. Check out his templates.

HTTP Request, GitHub, Execute Workflow Trigger +1
Web Scraping

This workflow provides everything you need to package and deploy multiple workflows from a single workflow you distribute.

n8n, Stop And Error, GitHub +1