Darmowy szablon automatyzacji

Utwórz kopię zapasową swoich przepływów pracy w GitHub — w (podfolderach)

3356
25 dni temu
25
bloków

Opis automatyzacji

Ten szablon automatyzacji, oparty na pracy Jonathana i Solomona, umożliwia tworzenie kopii zapasowych workflow w repozytorium GitHub. Główną funkcjonalnością jest eksport wszystkich workflow za pomocą węzła API n8n, a następnie sprawdzenie ich obecności w repozytorium GitHub.

Jak to działa

Workflow wykonuje następujące kroki:

  • Eksportuje wszystkie workflow za pomocą węzła API n8n.
  • Iteruje po danych i sprawdza w GitHub, czy plik o danym ID już istnieje.
  • W zależności od wyniku sprawdzenia:
    • Aktualizuje istniejący plik w GitHub.
    • Tworzy nowy plik, jeśli nie istnieje.
    • Ignoruje pliki, które nie uległy zmianie.
  • Dodatkowo, węzeł Set organizuje workflow w podfolderach repozytorium GitHub na podstawie przypisanych tagów.

Dla kogo jest to rozwiązanie

Rozwiązanie przeznaczone jest dla użytkowników, którzy chcą:

  • Tworzyć kopie zapasowe workflow poza serwerem.
  • Zabezpieczyć swoje workflow przed utratą danych.
  • Migrować workflow na inny serwer.

Przykłady zastosowań

Ten szablon automatyzacji znajduje zastosowanie w wielu scenariuszach związanych z zarządzaniem workflow w n8n. Oto najczęstsze przypadki użycia:

  • Regularne tworzenie kopii zapasowych workflow w chmurze.
  • Migracja workflow między różnymi instancjami n8n.
  • Wersjonowanie zmian w workflow za pomocą systemu kontroli wersji.
  • Współpraca zespołowa nad workflow poprzez udostępnianie ich w repozytorium.
  • Automatyczne organizowanie workflow w logiczne kategorie na podstawie tagów.
  • Tworzenie archiwum starych workflow w celu zachowania historii zmian.
  • Integracja z systemem CI/CD do automatycznego wdrażania workflow.

   Skopiuj kod szablonu   
{"meta":{"instanceId":"a7dcffb2764d1b10c84b837267686e7094bf753c8ca242421ba2029587943438","templateId":"2652"},"nodes":[{"id":"42cc4260-626e-4f83-b1c3-c78c99b78b38","name":"On clicking 'execute'","type":"n8n-nodes-base.manualTrigger","position":[820,486.1164603611751],"parameters":{},"typeVersion":1},{"id":"f21386ff-f8db-4f5d-a44c-15484d1e4ab7","name":"Sticky Note","type":"n8n-nodes-base.stickyNote","position":[380,866.1164603611751],"parameters":{"color":6,"width":2547,"height":751,"content":"## Subworkflow"},"typeVersion":1},{"id":"82851e4a-33a1-461b-965f-f51efcb5af90","name":"n8n","type":"n8n-nodes-base.n8n","position":[1080,580],"parameters":{"filters":{},"requestOptions":{}},"credentials":{"n8nApi":{"id":"hYWXj2T43Yhf6coc","name":"Hirempire"}},"typeVersion":1},{"id":"90cac8e2-9509-4d48-9038-bb653ffbdf9d","name":"Return","type":"n8n-nodes-base.set","position":[2720,1080],"parameters":{"options":{},"assignments":{"assignments":[{"id":"8d513345-6484-431f-afb7-7cf045c90f4f","name":"Done","type":"boolean","value":true}]}},"typeVersion":3.3},{"id":"11046021-89ba-4e61-b03f-d606e7dd0a56","name":"Get File","type":"n8n-nodes-base.httpRequest","position":[1820,960],"parameters":{"url":"={{ $json.download_url }}","options":{}},"typeVersion":4.2},{"id":"08af670c-ac82-422f-9938-c649dfdfbcf6","name":"If file too large","type":"n8n-nodes-base.if","position":[1620,980],"parameters":{"options":{},"conditions":{"options":{"version":1,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"45ce825e-9fa6-430c-8931-9aaf22c42585","operator":{"type":"string","operation":"empty","singleValue":true},"leftValue":"={{ $json.content }}","rightValue":""},{"id":"9619a55f-7fb1-4f24-b1a7-7aeb82365806","operator":{"type":"string","operation":"notExists","singleValue":true},"leftValue":"={{ $json.error }}","rightValue":""}]}},"typeVersion":2},{"id":"795fd895-94b2-46f1-b559-748b0db01c49","name":"Merge Items","type":"n8n-nodes-base.merge","position":[1620,1240],"parameters":{},"typeVersion":2},{"id":"3d3399f3-bbfb-48ab-8644-91b28e731026","name":"isDiffOrNew","type":"n8n-nodes-base.code","position":[1820,1240],"parameters":{"jsCode":"const orderJsonKeys = (jsonObj) => {n const ordered = {};n Object.keys(jsonObj).sort().forEach(key => {n ordered[key] = jsonObj[key];n });n return ordered;n}nn// Check if file returned with contentnif (Object.keys($input.all()[0].json).includes("content")) {n // Decode base64 content and parse JSONn const origWorkflow = JSON.parse(Buffer.from($input.all()[0].json.content, 'base64').toString());n const n8nWorkflow = $input.all()[1].json;n n // Order JSON objectsn const orderedOriginal = orderJsonKeys(origWorkflow);n const orderedActual = orderJsonKeys(n8nWorkflow);nn // Determine differencen if (JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual)) {n $input.all()[0].json.github_status = "same";n } else {n $input.all()[0].json.github_status = "different";n $input.all()[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);n }n $input.all()[0].json.content_decoded = orderedOriginal;n// No file returned / new workflown} else if (Object.keys($input.all()[0].json).includes("data")) {n const origWorkflow = JSON.parse($input.all()[0].json.data);n const n8nWorkflow = $input.all()[1].json;n n // Order JSON objectsn const orderedOriginal = orderJsonKeys(origWorkflow);n const orderedActual = orderJsonKeys(n8nWorkflow);nn // Determine differencen if (JSON.stringify(orderedOriginal) === JSON.stringify(orderedActual)) {n $input.all()[0].json.github_status = "same";n } else {n $input.all()[0].json.github_status = "different";n $input.all()[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);n }n $input.all()[0].json.content_decoded = orderedOriginal;nn} else {n // Order JSON objectn const n8nWorkflow = $input.all()[1].json;n const orderedActual = orderJsonKeys(n8nWorkflow);n n // Proper formattingn $input.all()[0].json.github_status = "new";n $input.all()[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);n}nn// Return itemsnreturn $input.all();"},"typeVersion":1},{"id":"2f2f42d0-d27c-4856-a263-4d5e9eda2c4c","name":"Check Status","type":"n8n-nodes-base.switch","position":[2040,1240],"parameters":{"rules":{"rules":[{"value2":"same"},{"output":1,"value2":"different"},{"output":2,"value2":"new"}]},"value1":"={{$json.github_status}}","dataType":"string"},"typeVersion":1},{"id":"5316029f-f32f-4a8d-95de-50ee57051a08","name":"Same file - Do nothing","type":"n8n-nodes-base.noOp","position":[2260,1080],"parameters":{},"typeVersion":1},{"id":"37c5983b-48fe-41d5-8e3a-eb56dec2140b","name":"File is different","type":"n8n-nodes-base.noOp","position":[2260,1240],"parameters":{},"typeVersion":1},{"id":"a4dcce9e-b0d0-4b9e-ab16-9142e641c73d","name":"File is new","type":"n8n-nodes-base.noOp","position":[2260,1400],"parameters":{},"typeVersion":1},{"id":"03fcfdc4-2e52-42f0-a129-3ebaf8dd8fc1","name":"Create new file","type":"n8n-nodes-base.github","position":[2480,1400],"parameters":{"owner":{"__rl":true,"mode":"name","value":"={{ $('Globals').item.json.repo.owner }}"},"filePath":"={{ $('Globals').item.json.repo.path }}{{$('Execute Workflow Trigger').first().json.id}}.json","resource":"file","repository":{"__rl":true,"mode":"name","value":"={{ $('Globals').item.json.repo.name }}"},"fileContent":"={{$('isDiffOrNew').item.json["n8n_data_stringy"]}}","commitMessage":"={{$('Execute Workflow Trigger').first().json.name}} ({{$json.github_status}})"},"credentials":{"githubApi":{"id":"YDLAGVFazg3z5vF9","name":"islamnazmi"}},"typeVersion":1},{"id":"dd35cc39-4ab4-4d53-b439-b425a2177e8f","name":"Edit existing file","type":"n8n-nodes-base.github","position":[2480,1220],"parameters":{"owner":{"__rl":true,"mode":"name","value":"={{ $('Globals').item.json.repo.owner }}"},"filePath":"={{ $('Globals').item.json.repo.path }}{{$('Execute Workflow Trigger').first().json.id}}.json","resource":"file","operation":"edit","repository":{"__rl":true,"mode":"name","value":"={{ $('Globals').item.json.repo.name }}"},"fileContent":"={{$('isDiffOrNew').item.json["n8n_data_stringy"]}}","commitMessage":"={{$('Execute Workflow Trigger').first().json.name}} ({{$json.github_status}})"},"credentials":{"githubApi":{"id":"YDLAGVFazg3z5vF9","name":"islamnazmi"}},"typeVersion":1},{"id":"d05e2a25-24be-43fb-baa4-9c3391840e70","name":"Loop Over Items","type":"n8n-nodes-base.splitInBatches","position":[1280,586.1164603611751],"parameters":{"options":{}},"typeVersion":3},{"id":"2a139d59-1387-4899-88b3-21106cd01099","name":"Schedule Trigger","type":"n8n-nodes-base.scheduleTrigger","position":[820,686.1164603611751],"parameters":{"rule":{"interval":[{"triggerAtHour":7}]}},"typeVersion":1.2},{"id":"04e6c245-3117-4ef8-a181-754e616e958b","name":"Sticky Note1","type":"n8n-nodes-base.stickyNote","position":[380,240],"parameters":{"color":4,"width":371.1995072042308,"height":600.88409546716,"content":"## Backup to GitHub nThis workflow will backup all instance workflows to GitHub.nnThe files are saved `ID.json` for the filename.nn### SetupnOpen `Globals` node and update the values below 👇nn- **repo.owner:** your Github usernamen- **repo.name:** the name of your repositoryn- **repo.path:** the folder to use within the repository. If it doesn't exist it will be created.nnnIf your username was `john-doe` and your repository was called `n8n-backups` and you wanted the workflows to go into a `workflows` folder you would set:nn- repo.owner - john-doen- repo.name - n8n-backupsn- repo.path - workflows/nnnThe workflow calls itself using a subworkflow, to help reduce memory usage."},"typeVersion":1},{"id":"3d996985-0064-4749-85a1-2191c73746c9","name":"Sticky Note2","type":"n8n-nodes-base.stickyNote","position":[780,406.1164603611751],"parameters":{"color":7,"width":886.4410237965205,"height":434.88564057365943,"content":"## Main workflow loop"},"typeVersion":1},{"id":"c9bfa393-e120-4bfe-b957-702756b91aaf","name":"Get file data","type":"n8n-nodes-base.github","position":[1420,980],"parameters":{"owner":{"__rl":true,"mode":"name","value":"={{ $json.repo.owner }}"},"filePath":"={{ $json.repo.path }}{{ $('Execute Workflow Trigger').item.json.id }}.json","resource":"file","operation":"get","repository":{"__rl":true,"mode":"name","value":"={{ $json.repo.name }}"},"asBinaryProperty":false,"additionalParameters":{}},"credentials":{"githubApi":{"id":"YDLAGVFazg3z5vF9","name":"islamnazmi"}},"typeVersion":1,"continueOnFail":true,"alwaysOutputData":true},{"id":"d42ddc37-3bd9-4f19-8831-695bec4d0137","name":"Globals","type":"n8n-nodes-base.set","position":[1200,1140],"parameters":{"options":{},"assignments":{"assignments":[{"id":"6cf546c5-5737-4dbd-851b-17d68e0a3780","name":"repo.owner","type":"string","value":"islamnazmi"},{"id":"452efa28-2dc6-4ea3-a7a2-c35d100d0382","name":"repo.name","type":"string","value":"n8n"},{"id":"81c4dc54-86bf-4432-a23f-22c7ea831e74","name":"repo.path","type":"string","value":"=workflows/{{ $json.tags[0].name }}"}]}},"typeVersion":3.4},{"id":"e970c63c-2aa2-46f9-be04-f045b6a938de","name":"Sticky Note3","type":"n8n-nodes-base.stickyNote","position":[1180,1020],"parameters":{"color":4,"width":150,"height":80,"content":"## Edit this node 👇"},"typeVersion":1},{"id":"5b1991f7-0351-44de-908d-9aa8b8262d60","name":"Execute Workflow Trigger","type":"n8n-nodes-base.executeWorkflowTrigger","position":[480,1320],"parameters":{"inputSource":"passthrough"},"typeVersion":1.1},{"id":"8e5b3f71-0c5e-4e78-a3f7-0b574c9ddf06","name":"Execute Workflow","type":"n8n-nodes-base.executeWorkflow","position":[1500,580],"parameters":{"mode":"each","options":{},"workflowId":{"__rl":true,"mode":"id","value":"={{ $workflow.id }}"},"workflowInputs":{"value":{},"schema":[],"mappingMode":"defineBelow","matchingColumns":[],"attemptToConvertTypes":false,"convertFieldsToString":true}},"typeVersion":1.2},{"id":"399bd193-4886-4292-be71-6f996f00a6d2","name":"/","type":"n8n-nodes-base.set","position":[960,1040],"parameters":{"options":{},"assignments":{"assignments":[{"id":"12cad226-e091-4bbb-aed9-a8e01311772c","name":"tags[0].name","type":"string","value":"={{ $('Execute Workflow Trigger').item.json.tags[0].name }}/"}]}},"typeVersion":3.4},{"id":"e90328e1-4ada-424b-879a-20fb2a7270c0","name":"tag?","type":"n8n-nodes-base.switch","position":[720,1140],"parameters":{"rules":{"values":[{"outputKey":"tag","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"operator":{"type":"object","operation":"exists","singleValue":true},"leftValue":"={{ $json.tags[0] }}","rightValue":""}]},"renameOutput":true},{"outputKey":"none","conditions":{"options":{"version":2,"leftValue":"","caseSensitive":true,"typeValidation":"strict"},"combinator":"and","conditions":[{"id":"2656fbe3-fe35-4770-9c03-9a455ec618e4","operator":{"type":"object","operation":"notExists","singleValue":true},"leftValue":"={{ $json.tags[0] }}","rightValue":""}]},"renameOutput":true}]},"options":{}},"typeVersion":3.2}],"pinData":{},"connections":{"/":{"main":[[{"node":"Globals","type":"main","index":0}]]},"n8n":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"tag?":{"main":[[{"node":"/","type":"main","index":0}],[{"node":"Globals","type":"main","index":0}]]},"Globals":{"main":[[{"node":"Get file data","type":"main","index":0}]]},"Get File":{"main":[[{"node":"Merge Items","type":"main","index":0}]]},"File is new":{"main":[[{"node":"Create new file","type":"main","index":0}]]},"Merge Items":{"main":[[{"node":"isDiffOrNew","type":"main","index":0}]]},"isDiffOrNew":{"main":[[{"node":"Check Status","type":"main","index":0}]]},"Check Status":{"main":[[{"node":"Same file - Do nothing","type":"main","index":0}],[{"node":"File is different","type":"main","index":0}],[{"node":"File is new","type":"main","index":0}]]},"Get file data":{"main":[[{"node":"If file too large","type":"main","index":0}]]},"Create new file":{"main":[[{"node":"Return","type":"main","index":0}]]},"Loop Over Items":{"main":[[],[{"node":"Execute Workflow","type":"main","index":0}]]},"Execute Workflow":{"main":[[{"node":"Loop Over Items","type":"main","index":0}]]},"Schedule Trigger":{"main":[[{"node":"n8n","type":"main","index":0}]]},"File is different":{"main":[[{"node":"Edit existing file","type":"main","index":0}]]},"If file too large":{"main":[[{"node":"Get File","type":"main","index":0}],[{"node":"Merge Items","type":"main","index":0}]]},"Edit existing file":{"main":[[{"node":"Return","type":"main","index":0}]]},"On clicking 'execute'":{"main":[[{"node":"n8n","type":"main","index":0}]]},"Same file - Do nothing":{"main":[[{"node":"Return","type":"main","index":0}]]},"Execute Workflow Trigger":{"main":[[{"node":"Merge Items","type":"main","index":1},{"node":"tag?","type":"main","index":0}]]}}}
  • API
  • Request
  • URL
  • Build
  • cURL
  • cpde
  • Javascript
  • JS
  • Python
  • Script
  • Custom Code
  • Function
Planeta AI 2025 
magic-wandmenu linkedin facebook pinterest youtube rss twitter instagram facebook-blank rss-blank linkedin-blank pinterest youtube twitter instagram