{
  "name": "Version control n8n workflows in GitLab with customer tag organization",
  "nodes": [
    {
      "id": "2aaa2725-24b6-46bb-9f9e-153049095183",
      "name": "When clicking ‘Execute workflow’",
      "type": "n8n-nodes-base.manualTrigger",
      "position": [
        -1136,
        -128
      ]
    },
    {
      "id": "a6a535bb-a39c-43e7-8121-16187772dacd",
      "name": "Schedule Trigger",
      "type": "n8n-nodes-base.scheduleTrigger",
      "position": [
        -1136,
        64
      ]
    },
    {
      "id": "da551fd3-0e10-47f8-8325-5ca0b7bd375d",
      "name": "Prepare Workflow JSON for UI-Compatible Export",
      "type": "n8n-nodes-base.code",
      "position": [
        1056,
        32
      ]
    },
    {
      "id": "092317f4-3c1e-4c9b-af35-fdeabc9e578f",
      "name": "Clean & Normalize Workflow Name",
      "type": "n8n-nodes-base.code",
      "position": [
        800,
        32
      ]
    },
    {
      "id": "4bed4024-392c-4027-907c-0f534dea3466",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        656,
        -640
      ],
      "parameters": {
        "width": 912,
        "height": 912,
        "content": "\n\n## 🟨 Prepare Workflow Data 🛠️\n\n### 🎯 Goal\nClean and prepare workflow data for a consistent and stable GitLab export.  \nThe GitLab file path is always based on the workflow **ID** (rename-proof).  \nT"
      }
    },
    {
      "id": "91eb911b-8a50-4db7-b987-c79ee6cc6e67",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -240,
        -640
      ],
      "parameters": {
        "width": 806,
        "height": 912,
        "content": "\n\n## 🟩 Gather Workflows from n8n 📂\n\n### 🎯 Goal  \nIdentify which workflows should be backed up, using tag-based filtering directly in the API call.\n\n### 🔗 Node  \nFetch Workflows from n8n → retrieves on"
      }
    },
    {
      "id": "33a61637-4c62-4349-8a55-115ca7b5adbc",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1264,
        -640
      ],
      "parameters": {
        "width": 934,
        "height": 912,
        "content": "\n\n## 🟪 Start / Trigger & Configure ⚡\n\n### 🎯 Goal\nStart the backup manually or via CRON schedule and initialize GitLab + execution variables.  \n\n### 🔗 Nodes\n- **When clicking 'Execute workflow'** → man"
      }
    },
    {
      "id": "a8d0f8cc-70c5-4713-bb03-8d219feedbae",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1664,
        -1648
      ],
      "parameters": {
        "width": 896,
        "height": 1920,
        "content": "\n\n## 🟩 GitLab File Management 📑\n\n### 🎯 Goal\nCompare the current workflow version with the GitLab repository and decide whether to create, update, or skip.  \nThe GitLab file path is always derived from"
      }
    },
    {
      "id": "a0718c04-0981-472d-86f1-d96412dc4b79",
      "name": "Fetch Workflows from n8n",
      "type": "n8n-nodes-base.n8n",
      "position": [
        112,
        -32
      ]
    },
    {
      "id": "79f360ed-86cc-40fe-a105-b3ef23120e97",
      "name": "Fetch Existing File from GitLab",
      "type": "n8n-nodes-base.gitlab",
      "position": [
        1824,
        -32
      ]
    },
    {
      "id": "15cd412a-dd8f-4b71-ab54-849a6a535af8",
      "name": "Update Existing File in GitLab",
      "type": "n8n-nodes-base.gitlab",
      "position": [
        2320,
        -208
      ]
    },
    {
      "id": "da9f550c-bd0f-4bc2-b221-cab11a8d7be6",
      "name": "Create New File in GitLab",
      "type": "n8n-nodes-base.gitlab",
      "position": [
        2096,
        64
      ]
    },
    {
      "id": "5ddc1294-9b87-42d8-93b8-f5e695dbf8bb",
      "name": "Normalize Backup Output",
      "type": "n8n-nodes-base.set",
      "position": [
        3392,
        -16
      ]
    },
    {
      "id": "9939f6ff-8915-47f3-8a87-6ff204fd2c0d",
      "name": "Set Global GitLab Variables",
      "type": "n8n-nodes-base.set",
      "position": [
        -640,
        -32
      ]
    },
    {
      "id": "2ea3ccb3-8123-4f49-82be-c4b90e0c5f20",
      "name": "Prepare GitLab File Path",
      "type": "n8n-nodes-base.code",
      "position": [
        1312,
        32
      ]
    },
    {
      "id": "9f4fd524-5c9b-4ba6-bef2-a6da86f64c7d",
      "name": "Compare Workflow with GitLab Version",
      "type": "n8n-nodes-base.if",
      "position": [
        2096,
        -128
      ]
    },
    {
      "id": "71fc8901-e3ea-4540-9384-51525834964b",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2656,
        -1648
      ],
      "parameters": {
        "width": 1280,
        "height": 1920,
        "content": "\n\n## 🟦 Output & Logging 📊\n\n### 🎯 Goal\nStandardize results for reporting and monitoring.  \n\n### 🔗 Nodes\n- **Mark as Created** → enriches each workflow output with `status = created`.  \n- **Mark as Upda"
      }
    },
    {
      "id": "fcc49db9-286c-4f06-8e4e-dc1f11a0488c",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1264,
        -1648
      ],
      "parameters": {
        "width": 1328,
        "height": 912,
        "content": "\n\n# 📘 n8n → GitLab Backup (with `[client]`) — Cheat Sheet\n\n## 1️⃣ Purpose\n- Versioned history, centralized repo, internal vs client separation.\n\n## 2️⃣ Client Management\n- Default path: `workflow_defi"
      }
    },
    {
      "id": "178c79f8-345e-4d33-a8aa-4eb31da592b7",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        64,
        -1648
      ],
      "parameters": {
        "width": 1504,
        "height": 912,
        "content": "\n\n## 6️⃣ Name Normalization\n- Extract `[client: Name]` tag → route file to subfolder `<client>/` (or `unassigned/` if none).  \n- File name is fixed to `<workflowId>.json` to preserve history across re"
      }
    },
    {
      "id": "75b2037f-bad5-4988-9f82-73665e4ae0eb",
      "name": "Mark as Created",
      "type": "n8n-nodes-base.set",
      "position": [
        2928,
        64
      ]
    },
    {
      "id": "e995304e-5611-4905-9a33-b6fdd70d3655",
      "name": "Mark as Updated",
      "type": "n8n-nodes-base.set",
      "position": [
        2928,
        -96
      ]
    },
    {
      "id": "69533d20-2a48-4cb4-810d-e65c2a4aa71c",
      "name": "Mark as Unchanged",
      "type": "n8n-nodes-base.set",
      "position": [
        2768,
        -16
      ]
    },
    {
      "id": "7af2d653-0358-4b5a-847c-8b1851aa2721",
      "name": "Summarize Backup Results",
      "type": "n8n-nodes-base.code",
      "position": [
        3712,
        -16
      ]
    },
    {
      "id": "90c21f27-3af6-416f-978e-2ff38c300c7a",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        3168,
        -32
      ]
    }
  ],
  "connections": {
    "Merge": {
      "main": [
        [
          {
            "node": "Normalize Backup Output",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark as Created": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 2
          }
        ]
      ]
    },
    "Mark as Updated": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Schedule Trigger": {
      "main": [
        [
          {
            "node": "Set Global GitLab Variables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Mark as Unchanged": {
      "main": [
        [
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "Normalize Backup Output": {
      "main": [
        [
          {
            "node": "Summarize Backup Results",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Workflows from n8n": {
      "main": [
        [
          {
            "node": "Clean & Normalize Workflow Name",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare GitLab File Path": {
      "main": [
        [
          {
            "node": "Fetch Existing File from GitLab",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create New File in GitLab": {
      "main": [
        [
          {
            "node": "Mark as Created",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Set Global GitLab Variables": {
      "main": [
        [
          {
            "node": "Fetch Workflows from n8n",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update Existing File in GitLab": {
      "main": [
        [
          {
            "node": "Mark as Updated",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Clean & Normalize Workflow Name": {
      "main": [
        [
          {
            "node": "Prepare Workflow JSON for UI-Compatible Export",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Fetch Existing File from GitLab": {
      "main": [
        [
          {
            "node": "Compare Workflow with GitLab Version",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Create New File in GitLab",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Compare Workflow with GitLab Version": {
      "main": [
        [
          {
            "node": "Update Existing File in GitLab",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Mark as Unchanged",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "When clicking ‘Execute workflow’": {
      "main": [
        [
          {
            "node": "Set Global GitLab Variables",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Prepare Workflow JSON for UI-Compatible Export": {
      "main": [
        [
          {
            "node": "Prepare GitLab File Path",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}