Enregistrez vos workflows dans un dépôt GitHub

Avancé

Ceci est unDevOpsworkflow d'automatisation du domainecontenant 18 nœuds.Utilise principalement des nœuds comme If, N8n, Set, Code, Merge. Sauvegarde quotidienne du flux de travail vers GitHub et envoi d'une notification Slack

Prérequis
  • Token Bot Slack ou URL Webhook
  • Personal Access Token GitHub
  • Peut nécessiter les informations d'identification d'authentification de l'API cible

Catégorie

Aperçu du workflow
Visualisation des connexions entre les nœuds, avec support du zoom et du déplacement
Exporter le workflow
Copiez la configuration JSON suivante dans n8n pour importer et utiliser ce workflow
{
  "id": "gkf2gpDVeNbAoCYO",
  "name": "Save_your_workflows_into_a_GitHub_repository",
  "nodes": [
    {
      "id": "d5efec23-eefc-443b-9e6d-4f41ee240d88",
      "name": "Retour",
      "type": "n8n-nodes-base.set",
      "position": [
        1680,
        440
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "8d513345-6484-431f-afb7-7cf045c90f4f",
              "name": "Done",
              "type": "boolean",
              "value": true
            }
          ]
        }
      },
      "typeVersion": 3.3
    },
    {
      "id": "ede04e40-7152-40f8-9860-942b15fba268",
      "name": "Fusionner les éléments",
      "type": "n8n-nodes-base.merge",
      "position": [
        800,
        240
      ],
      "parameters": {},
      "typeVersion": 2
    },
    {
      "id": "bbf6dea6-eee2-452d-9607-37d7fa90f3cc",
      "name": "isDiffOrNew",
      "type": "n8n-nodes-base.code",
      "position": [
        1020,
        240
      ],
      "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}\n\n// Check if file returned with content\nif (Object.keys($input.all()[0].json).includes(\"content\")) {\n  // Decode base64 content and parse JSON\n  const origWorkflow = JSON.parse(Buffer.from($input.all()[0].json.content, 'base64').toString());\n  const n8nWorkflow = $input.all()[1].json;\n  \n  // Order JSON objects\n  const orderedOriginal = orderJsonKeys(origWorkflow);\n  const orderedActual = orderJsonKeys(n8nWorkflow);\n\n  // Determine difference\n  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 workflow\n} 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 objects\n  const orderedOriginal = orderJsonKeys(origWorkflow);\n  const orderedActual = orderJsonKeys(n8nWorkflow);\n\n  // Determine difference\n  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\n} else {\n  // Order JSON object\n  const n8nWorkflow = $input.all()[1].json;\n  const orderedActual = orderJsonKeys(n8nWorkflow);\n  \n  // Proper formatting\n  $input.all()[0].json.github_status = \"new\";\n  $input.all()[0].json.n8n_data_stringy = JSON.stringify(orderedActual, null, 2);\n}\n\n// Return items\nreturn $input.all();\n"
      },
      "typeVersion": 1
    },
    {
      "id": "e72473e3-d4e5-4306-99c2-5961515060f2",
      "name": "Créer un nouveau fichier",
      "type": "n8n-nodes-base.github",
      "position": [
        1460,
        240
      ],
      "webhookId": "b440dead-fad0-4546-8ca7-201aa2ea2936",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Config').item.json.repo_owner }}"
        },
        "filePath": "={{ $('Config').item.json.sub_path }}/{{$('Loop Over Items').item.json.name}}.json",
        "resource": "file",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Config').item.json.repo_name }}"
        },
        "fileContent": "={{$('isDiffOrNew').item.json[\"n8n_data_stringy\"]}}",
        "commitMessage": "={{$('Loop Over Items').item.json.name}} ({{$json.github_status}})"
      },
      "credentials": {
        "githubApi": {
          "id": "Vn9CKICKNoIL3HqJ",
          "name": "GitHub account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "ce6f990e-4900-442d-9998-810dace92943",
      "name": "Modifier le fichier existant",
      "type": "n8n-nodes-base.github",
      "position": [
        1460,
        40
      ],
      "webhookId": "1dfc4103-7c23-4814-a0b5-dd4f5a96d36b",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Config').item.json.repo_owner }}"
        },
        "filePath": "={{ $('Config').item.json.sub_path }}/{{$('Loop Over Items').item.json.name}}.json",
        "resource": "file",
        "operation": "edit",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "n8n-workflows"
        },
        "fileContent": "={{$('isDiffOrNew').item.json[\"n8n_data_stringy\"]}}",
        "commitMessage": "={{$('Loop Over Items').item.json.name}} ({{$json.github_status}})"
      },
      "credentials": {
        "githubApi": {
          "id": "Vn9CKICKNoIL3HqJ",
          "name": "GitHub account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "06d3f09c-ca08-4a4a-825b-6cb2e8ef3c39",
      "name": "Filtre",
      "type": "n8n-nodes-base.filter",
      "position": [
        -300,
        240
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "bb64ed2c-5193-4b8f-a9e8-55cb83ea244c",
              "operator": {
                "type": "dateTime",
                "operation": "afterOrEquals"
              },
              "leftValue": "={{ $json.updatedAt }}",
              "rightValue": "={{ $now.minus(1, 'days') }}"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "3803f1ca-9296-46ce-8e35-01d8c5f9812c",
      "name": "Note adhésive 3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1660,
        80
      ],
      "parameters": {
        "width": 400,
        "height": 120,
        "content": "# Links\n- ## [Github Folder](https://github.com/AndrewBoichenko/n8n-workflows/)"
      },
      "typeVersion": 1
    },
    {
      "id": "ea1096b7-ac85-41ef-98b9-88e2f50b9d44",
      "name": "Note adhésive 4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1660,
        240
      ],
      "parameters": {
        "width": 400,
        "height": 340,
        "content": "# How it works \nThis workflow will backup all instance workflows to GitHub every 24 hours.\n\nThe files are saved into folders using `repo_path` for the directory path and `ID.json` for the filename.\nThe Repo Owner, Repo Name and Main folder are set using the `Config` node in the subworkflow. \n\nThe workflow runs calls itself to help reduce memory usage, Once the workflow has completed it will send an optional notification to Slack.\n\nPlease check out my other items on [gumroad](https://boanse.gumroad.com/?section=k_Sn6LcT_dzJFnp5jmsM5A%3D%3D)\nYou might also like something else☺️"
      },
      "typeVersion": 1
    },
    {
      "id": "c4139649-c1fd-4c1a-b90f-92ecac409fa2",
      "name": "Commutateur",
      "type": "n8n-nodes-base.switch",
      "position": [
        1240,
        240
      ],
      "parameters": {
        "rules": {
          "values": [
            {
              "outputKey": "Different",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "6655f56f-b447-43eb-84a2-be8b71524af7",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.github_status}}",
                    "rightValue": "different"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "New",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "fd0fcdea-e8c0-42be-ba51-5cd2b71ed247",
                    "operator": {
                      "name": "filter.operator.equals",
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.github_status}}",
                    "rightValue": "new"
                  }
                ]
              },
              "renameOutput": true
            },
            {
              "outputKey": "Same",
              "conditions": {
                "options": {
                  "version": 2,
                  "leftValue": "",
                  "caseSensitive": true,
                  "typeValidation": "strict"
                },
                "combinator": "and",
                "conditions": [
                  {
                    "id": "ca3b1c68-d756-4de5-b69b-147526e19e35",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    },
                    "leftValue": "={{$json.github_status}}",
                    "rightValue": "same"
                  }
                ]
              },
              "renameOutput": true
            }
          ]
        },
        "options": {}
      },
      "typeVersion": 3.2
    },
    {
      "id": "3ddd66d9-36a6-4aef-aa99-0a28421f0410",
      "name": "Obtenir les flux de travail",
      "type": "n8n-nodes-base.n8n",
      "position": [
        -520,
        240
      ],
      "parameters": {
        "filters": {},
        "requestOptions": {}
      },
      "credentials": {
        "n8nApi": {
          "id": "pltwIg9VHoXLGnS2",
          "name": "n8n account"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "36774b8c-4e8a-411d-8d22-a58870d17152",
      "name": "Configuration",
      "type": "n8n-nodes-base.set",
      "position": [
        -740,
        240
      ],
      "parameters": {
        "options": {},
        "assignments": {
          "assignments": [
            {
              "id": "03f51f9c-4681-4423-91d2-d32f4c18d6bc",
              "name": "repo_owner",
              "type": "string",
              "value": ""
            },
            {
              "id": "0c9b521a-b698-4b43-9eb0-bbf744760158",
              "name": "repo_name",
              "type": "string",
              "value": "n8n-workflows"
            },
            {
              "id": "91627e70-a71a-4be0-a6f6-b04d5c8469d8",
              "name": "repo_path",
              "type": "string",
              "value": "n8n-workflows"
            },
            {
              "id": "983a2c87-9d69-4d64-ab88-ec1b1117c6e6",
              "name": "sub_path",
              "type": "string",
              "value": "folder"
            }
          ]
        },
        "includeOtherFields": true
      },
      "typeVersion": 3.4
    },
    {
      "id": "ecb7924b-23f3-480d-aede-79edaa55be2a",
      "name": "Déclencheur planifié",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1180,
        240
      ],
      "parameters": {
        "rule": {
          "interval": [
            {}
          ]
        }
      },
      "typeVersion": 1.2
    },
    {
      "id": "a58a2c07-0162-433f-93e5-9fceabec5edc",
      "name": "Obtenir un fichier",
      "type": "n8n-nodes-base.github",
      "onError": "continueRegularOutput",
      "position": [
        140,
        40
      ],
      "webhookId": "c12420d3-b858-4ee4-81c4-9adc03e30865",
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Config').item.json.repo_owner }}"
        },
        "filePath": "={{ $('Config').item.json.sub_path }}/{{$('Loop Over Items').item.json.name}}.json",
        "resource": "file",
        "operation": "get",
        "repository": {
          "__rl": true,
          "mode": "name",
          "value": "={{ $('Config').item.json.repo_name }}"
        },
        "asBinaryProperty": false,
        "additionalParameters": {}
      },
      "credentials": {
        "githubApi": {
          "id": "Vn9CKICKNoIL3HqJ",
          "name": "GitHub account"
        }
      },
      "typeVersion": 1.1,
      "alwaysOutputData": true
    },
    {
      "id": "97b1e70b-a584-46af-87de-2be74333c285",
      "name": "Le fichier est-il trop volumineux ?",
      "type": "n8n-nodes-base.if",
      "position": [
        360,
        40
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "628f6e8f-d817-4c53-89ec-b1acbb3dfef8",
              "operator": {
                "type": "string",
                "operation": "empty",
                "singleValue": true
              },
              "leftValue": "={{ $json.content }}",
              "rightValue": ""
            },
            {
              "id": "63fc68bb-63d0-40a8-92e4-2a62b5a71812",
              "operator": {
                "type": "string",
                "operation": "notExists",
                "singleValue": true
              },
              "leftValue": "={{ $json.error }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "78dd800a-e7df-4834-9e38-e0d8c5aa0c34",
      "name": "Obtenir le fichier",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        580,
        40
      ],
      "parameters": {
        "url": "={{ $json.download_url }}",
        "options": {}
      },
      "typeVersion": 4.2
    },
    {
      "id": "60ca8287-488e-4174-97e9-10bac6ae36e9",
      "name": "Message de départ",
      "type": "n8n-nodes-base.slack",
      "disabled": true,
      "position": [
        -960,
        240
      ],
      "webhookId": "c02eb407-5547-4aa0-9ebf-46dab67b63b6",
      "parameters": {
        "text": "=Information_source:  Starting Workflow Backup [{{ $execution.id }}]",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#notifications"
        },
        "otherOptions": {
          "includeLinkToWorkflow": false
        }
      },
      "credentials": {
        "slackApi": {
          "id": "kyf7L2n90PzYIt0V",
          "name": "Slack account"
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "5f35553a-4e02-4a3f-a027-1d73860489ef",
      "name": "Notification d'achèvement",
      "type": "n8n-nodes-base.slack",
      "disabled": true,
      "position": [
        140,
        -160
      ],
      "webhookId": "a0c6e8c8-5d71-40fa-b02b-63a7ed5726c4",
      "parameters": {
        "text": "=✅ Backup has completed - {{ $('Get Workflows').all().length }} workflows have been processed.",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "name",
          "value": "#notifications"
        },
        "otherOptions": {}
      },
      "credentials": {
        "slackApi": {
          "id": "kyf7L2n90PzYIt0V",
          "name": "Slack account"
        }
      },
      "executeOnce": true,
      "typeVersion": 2.2
    },
    {
      "id": "1adaa738-6b43-403d-8ddd-6b1556c8e344",
      "name": "Boucler sur les éléments",
      "type": "n8n-nodes-base.splitInBatches",
      "position": [
        -80,
        240
      ],
      "parameters": {
        "options": {}
      },
      "typeVersion": 3
    }
  ],
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9109e6e5-12be-4a1f-850d-2b32a360ce87",
  "connections": {
    "36774b8c-4e8a-411d-8d22-a58870d17152": {
      "main": [
        [
          {
            "node": "3ddd66d9-36a6-4aef-aa99-0a28421f0410",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "06d3f09c-ca08-4a4a-825b-6cb2e8ef3c39": {
      "main": [
        [
          {
            "node": "1adaa738-6b43-403d-8ddd-6b1556c8e344",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d5efec23-eefc-443b-9e6d-4f41ee240d88": {
      "main": [
        [
          {
            "node": "1adaa738-6b43-403d-8ddd-6b1556c8e344",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c4139649-c1fd-4c1a-b90f-92ecac409fa2": {
      "main": [
        [
          {
            "node": "ce6f990e-4900-442d-9998-810dace92943",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "e72473e3-d4e5-4306-99c2-5961515060f2",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "d5efec23-eefc-443b-9e6d-4f41ee240d88",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "78dd800a-e7df-4834-9e38-e0d8c5aa0c34": {
      "main": [
        [
          {
            "node": "ede04e40-7152-40f8-9860-942b15fba268",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "a58a2c07-0162-433f-93e5-9fceabec5edc": {
      "main": [
        [
          {
            "node": "97b1e70b-a584-46af-87de-2be74333c285",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ede04e40-7152-40f8-9860-942b15fba268": {
      "main": [
        [
          {
            "node": "bbf6dea6-eee2-452d-9607-37d7fa90f3cc",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "bbf6dea6-eee2-452d-9607-37d7fa90f3cc": {
      "main": [
        [
          {
            "node": "c4139649-c1fd-4c1a-b90f-92ecac409fa2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "3ddd66d9-36a6-4aef-aa99-0a28421f0410": {
      "main": [
        [
          {
            "node": "06d3f09c-ca08-4a4a-825b-6cb2e8ef3c39",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "e72473e3-d4e5-4306-99c2-5961515060f2": {
      "main": [
        [
          {
            "node": "d5efec23-eefc-443b-9e6d-4f41ee240d88",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "1adaa738-6b43-403d-8ddd-6b1556c8e344": {
      "main": [
        [
          {
            "node": "5f35553a-4e02-4a3f-a027-1d73860489ef",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "a58a2c07-0162-433f-93e5-9fceabec5edc",
            "type": "main",
            "index": 0
          },
          {
            "node": "ede04e40-7152-40f8-9860-942b15fba268",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "ecb7924b-23f3-480d-aede-79edaa55be2a": {
      "main": [
        [
          {
            "node": "60ca8287-488e-4174-97e9-10bac6ae36e9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "60ca8287-488e-4174-97e9-10bac6ae36e9": {
      "main": [
        [
          {
            "node": "36774b8c-4e8a-411d-8d22-a58870d17152",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "ce6f990e-4900-442d-9998-810dace92943": {
      "main": [
        [
          {
            "node": "d5efec23-eefc-443b-9e6d-4f41ee240d88",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "97b1e70b-a584-46af-87de-2be74333c285": {
      "main": [
        [
          {
            "node": "78dd800a-e7df-4834-9e38-e0d8c5aa0c34",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "ede04e40-7152-40f8-9860-942b15fba268",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Foire aux questions

Comment utiliser ce workflow ?

Copiez le code de configuration JSON ci-dessus, créez un nouveau workflow dans votre instance n8n et sélectionnez "Importer depuis le JSON", collez la configuration et modifiez les paramètres d'authentification selon vos besoins.

Dans quelles scénarios ce workflow est-il adapté ?

Avancé - DevOps

Est-ce payant ?

Ce workflow est entièrement gratuit et peut être utilisé directement. Veuillez noter que les services tiers utilisés dans le workflow (comme l'API OpenAI) peuvent nécessiter un paiement de votre part.

Informations sur le workflow
Niveau de difficulté
Avancé
Nombre de nœuds18
Catégorie1
Types de nœuds13
Description de la difficulté

Adapté aux utilisateurs avancés, avec des workflows complexes contenant 16+ nœuds

Auteur
Liens externes
Voir sur n8n.io

Partager ce workflow

Catégories

Catégories: 34