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 →
{
"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.
githubOAuth2Apin8nApi
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 →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
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
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
Git Commit. Uses github, n8n, formTrigger, httpRequest. Event-driven trigger; 34 nodes.
Remixed Backup your workflows to GitHub from Solomon's work. Check out his templates.
This workflow provides everything you need to package and deploy multiple workflows from a single workflow you distribute.