{ "kind": "open-flow-workflow", "version": 1, "name": "Back Up n8n Workflows to GitLab", "content": { "modelVersion": 14, "document": { "bindings": {}, "graph": { "nodes": { "n_f071401369b7072a": { "name": "Back up now", "kind": "start", "inputDefs": [] }, "n_4cd8360806a13945": { "name": "Every Saturday at 21:30 UTC", "kind": "cron", "cronTimes": [ { "type": "cron", "expression": "30 21 * * 6", "timezone": "UTC" } ] }, "n_45fa6d1f031c6f8d": { "inputs": { "owner": { "kind": "value", "value": "YOUR_GITLAB_OWNER" }, "project": { "kind": "value", "value": "YOUR_GITLAB_PROJECT" }, "path": { "kind": "value", "value": "YOUR_BACKUP_DIRECTORY" }, "tag": { "kind": "value", "value": "gitlab_backup_enabled" } }, "name": "Configure the backup", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "owner" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "project" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "path" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "tag" } ], "outputs": [ { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "owner" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "project" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "path" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "tag" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "projectEndpoint" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "branchEndpoint" } ], "name": "Configure the backup", "moduleId": "n_406bd90743c8b6e3", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_dd4c19e8c07dbb99": { "inputs": { "endpoint": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_45fa6d1f031c6f8d", "output": "projectEndpoint" } ] } }, "name": "Check the GitLab project", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "name": "Check the GitLab project", "executor": { "providerId": "gitlab", "method": "GET", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "none", "kind": "connector-proxy" } } }, "n_2d30d219833b553a": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_dd4c19e8c07dbb99", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_dd4c19e8c07dbb99", "output": "statusCode" } ] }, "bodyEncoding": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_dd4c19e8c07dbb99", "output": "bodyEncoding" } ] }, "expected": { "kind": "value", "value": "project" }, "kind": { "kind": "value", "value": "project" } }, "name": "Confirm the project", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "expected" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "kind" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "ok" } ], "name": "Confirm the project", "moduleId": "n_e4465b52431cc920", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_034155e97ea01616": { "inputs": { "endpoint": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_45fa6d1f031c6f8d", "output": "branchEndpoint" } ] } }, "name": "Check the main branch", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "name": "Check the main branch", "executor": { "providerId": "gitlab", "method": "GET", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "none", "kind": "connector-proxy" } } }, "n_f7a611505ccd45e7": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_034155e97ea01616", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_034155e97ea01616", "output": "statusCode" } ] }, "bodyEncoding": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_034155e97ea01616", "output": "bodyEncoding" } ] }, "expected": { "kind": "value", "value": "main" }, "kind": { "kind": "value", "value": "branch" } }, "name": "Confirm the branch", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "expected" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "kind" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "ok" } ], "name": "Confirm the branch", "moduleId": "n_12ef047390ae4df7", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_1478180fdedd4b84": { "inputs": { "tag": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_45fa6d1f031c6f8d", "output": "tag" } ] }, "previous": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_1478180fdedd4b84", "output": "state" } ] } }, "name": "Read tagged workflows", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "tag" }, { "jsonSchema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "cursor": { "type": [ "string", "null" ] }, "seen": { "type": "array", "items": { "type": "string" } } }, "required": [ "items", "cursor", "seen" ], "additionalProperties": false }, "nullable": true, "handle": "previous" } ], "outputs": [ { "jsonSchema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "cursor": { "type": [ "string", "null" ] }, "seen": { "type": "array", "items": { "type": "string" } } }, "required": [ "items", "cursor", "seen" ], "additionalProperties": false }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" } ], "name": "Read tagged workflows", "moduleId": "n_1a09396202d86fb7", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [ { "action": "n8n.list_workflows" } ] } ] } }, "n_68e27e1a3d868632": { "inputs": {}, "name": "More workflow pages?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "more", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_1478180fdedd4b84", "output": "more" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_4415d42146bb315e": { "inputs": { "state": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_1478180fdedd4b84", "output": "state" } ] }, "path": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_45fa6d1f031c6f8d", "output": "path" } ] }, "projectEndpoint": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_45fa6d1f031c6f8d", "output": "projectEndpoint" } ] } }, "name": "Check backup filenames", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "object", "properties": { "items": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "cursor": { "type": [ "string", "null" ] }, "seen": { "type": "array", "items": { "type": "string" } } }, "required": [ "items", "cursor", "seen" ], "additionalProperties": false }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "path" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "projectEndpoint" } ], "outputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "items" } ], "name": "Check backup filenames", "moduleId": "n_447b98e9c41c042a", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_b71863d78a253c8b": { "inputs": { "items": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4415d42146bb315e", "output": "items" } ] }, "previous": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b71863d78a253c8b", "output": "state" } ] } }, "name": "Prepare the next workflow", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "nullable": false, "handle": "items" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": true, "handle": "previous" } ], "outputs": [ { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "state" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "more" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "item" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "endpoint" } ], "name": "Prepare the next workflow", "moduleId": "n_4da77a3c385857c8", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_bf58d016068e9339": { "inputs": {}, "name": "More workflows?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "more", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_b71863d78a253c8b", "output": "more" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_b8532b47456a7548": { "inputs": { "endpoint": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b71863d78a253c8b", "output": "endpoint" } ] } }, "name": "Read the GitLab file", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "name": "Read the GitLab file", "executor": { "providerId": "gitlab", "method": "GET", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "none", "kind": "connector-proxy" } } }, "n_003a30301c6d9331": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b8532b47456a7548", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b8532b47456a7548", "output": "statusCode" } ] }, "bodyEncoding": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b8532b47456a7548", "output": "bodyEncoding" } ] }, "item": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b71863d78a253c8b", "output": "item" } ] } }, "name": "Compare the backup", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "item" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "exists" }, { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "changed" }, { "jsonSchema": { "type": "string", "minLength": 1 }, "nullable": false, "handle": "endpoint" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "createBody" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "updateBody" } ], "name": "Compare the backup", "moduleId": "n_e4d9e7e5c5f2b540", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_c31a4a9377339ca7": { "inputs": {}, "name": "Backup changed?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_003a30301c6d9331", "output": "changed" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_04fbf805af775255": { "inputs": {}, "name": "File already exists?", "kind": "condition", "matchMode": "first", "cases": [ { "output": "yes", "groups": [ { "expressions": [ { "left": { "kind": "source", "source": { "kind": "node", "nodeId": "n_003a30301c6d9331", "output": "exists" } }, "operator": "==", "right": { "kind": "value", "value": true } } ] } ] } ] }, "n_4dea82b4182b48ef": { "inputs": { "endpoint": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_003a30301c6d9331", "output": "endpoint" } ] }, "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_003a30301c6d9331", "output": "createBody" } ] } }, "name": "Create the backup file", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" }, { "jsonSchema": {}, "nullable": true, "handle": "body" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "name": "Create the backup file", "executor": { "providerId": "gitlab", "method": "POST", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "json", "kind": "connector-proxy" } } }, "n_d7d9e1921b448d43": { "inputs": { "endpoint": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_003a30301c6d9331", "output": "endpoint" } ] }, "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_003a30301c6d9331", "output": "updateBody" } ] } }, "name": "Update the backup file", "kind": "task", "task": { "inputs": [ { "jsonSchema": { "type": "string" }, "nullable": false, "handle": "endpoint" }, { "jsonSchema": {}, "nullable": true, "handle": "body" } ], "outputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "type": "object", "additionalProperties": { "type": "string" } }, "nullable": false, "handle": "headers" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" } ], "name": "Update the backup file", "executor": { "providerId": "gitlab", "method": "PUT", "query": { "mode": "fields", "names": [] }, "headers": { "mode": "fields", "names": [] }, "bodyFormat": "json", "kind": "connector-proxy" } } }, "n_1fe231c67d77b82b": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4dea82b4182b48ef", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4dea82b4182b48ef", "output": "statusCode" } ] }, "bodyEncoding": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_4dea82b4182b48ef", "output": "bodyEncoding" } ] }, "item": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b71863d78a253c8b", "output": "item" } ] } }, "name": "Confirm the new backup", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "item" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "ok" } ], "name": "Confirm the new backup", "moduleId": "n_3ac9a5192b822f86", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } }, "n_64fd0910ef1a9781": { "inputs": { "body": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d7d9e1921b448d43", "output": "body" } ] }, "statusCode": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d7d9e1921b448d43", "output": "statusCode" } ] }, "bodyEncoding": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_d7d9e1921b448d43", "output": "bodyEncoding" } ] }, "item": { "kind": "sources", "sources": [ { "kind": "node", "nodeId": "n_b71863d78a253c8b", "output": "item" } ] } }, "name": "Confirm the updated backup", "kind": "task", "task": { "inputs": [ { "jsonSchema": {}, "nullable": true, "handle": "body" }, { "jsonSchema": { "type": "integer" }, "nullable": false, "handle": "statusCode" }, { "jsonSchema": { "const": "base64" }, "nullable": true, "handle": "bodyEncoding" }, { "jsonSchema": { "type": "object", "additionalProperties": true }, "nullable": false, "handle": "item" } ], "outputs": [ { "jsonSchema": { "type": "boolean" }, "nullable": false, "handle": "ok" } ], "name": "Confirm the updated backup", "moduleId": "n_716e2124767f3c03", "capabilities": [ { "kind": "connector", "mode": "independent", "actions": [] } ] } } }, "edges": [ { "source": "n_f071401369b7072a", "target": "n_45fa6d1f031c6f8d" }, { "source": "n_4cd8360806a13945", "target": "n_45fa6d1f031c6f8d" }, { "source": "n_45fa6d1f031c6f8d", "target": "n_dd4c19e8c07dbb99" }, { "source": "n_dd4c19e8c07dbb99", "target": "n_2d30d219833b553a" }, { "source": "n_2d30d219833b553a", "target": "n_034155e97ea01616" }, { "source": "n_034155e97ea01616", "target": "n_f7a611505ccd45e7" }, { "source": "n_f7a611505ccd45e7", "target": "n_1478180fdedd4b84" }, { "source": "n_1478180fdedd4b84", "target": "n_68e27e1a3d868632" }, { "source": "n_68e27e1a3d868632", "target": "n_1478180fdedd4b84", "sourceHandle": "more" }, { "source": "n_68e27e1a3d868632", "target": "n_4415d42146bb315e", "sourceHandle": "otherwise" }, { "source": "n_4415d42146bb315e", "target": "n_b71863d78a253c8b" }, { "source": "n_b71863d78a253c8b", "target": "n_bf58d016068e9339" }, { "source": "n_bf58d016068e9339", "target": "n_b8532b47456a7548", "sourceHandle": "more" }, { "source": "n_b8532b47456a7548", "target": "n_003a30301c6d9331" }, { "source": "n_003a30301c6d9331", "target": "n_c31a4a9377339ca7" }, { "source": "n_c31a4a9377339ca7", "target": "n_04fbf805af775255", "sourceHandle": "yes" }, { "source": "n_c31a4a9377339ca7", "target": "n_b71863d78a253c8b", "sourceHandle": "otherwise" }, { "source": "n_04fbf805af775255", "target": "n_d7d9e1921b448d43", "sourceHandle": "yes" }, { "source": "n_04fbf805af775255", "target": "n_4dea82b4182b48ef", "sourceHandle": "otherwise" }, { "source": "n_4dea82b4182b48ef", "target": "n_1fe231c67d77b82b" }, { "source": "n_d7d9e1921b448d43", "target": "n_64fd0910ef1a9781" }, { "source": "n_1fe231c67d77b82b", "target": "n_b71863d78a253c8b" }, { "source": "n_64fd0910ef1a9781", "target": "n_b71863d78a253c8b" } ] } }, "modules": { "n_406bd90743c8b6e3": { "name": "Configure the backup", "imports": [], "source": "export default function config({owner,project,path,tag}){for(const [k,v]of Object.entries({owner,project,path,tag}))if(typeof v!=='string'||!v.trim()||v.startsWith('YOUR_'))throw Error('Configure '+k);if(owner.split('/').some(x=>!x||x==='.'||x==='..'||!/^[A-Za-z0-9_.-]+$/.test(x))||project==='.'||project==='..'||!/^[A-Za-z0-9_.-]+$/.test(project)||path.startsWith('/')||path.endsWith('/')||path.split('/').some(x=>!x||x==='.'||x==='..')||tag.split(',').some(x=>!x.trim()))throw Error('Invalid repository configuration');const p='/projects/'+encodeURIComponent(owner+'/'+project);return{owner,project,path,tag:tag.split(',').map(x=>x.trim()).join(','),projectEndpoint:p,branchEndpoint:p+'/repository/branches/main'}}\n" }, "n_e4465b52431cc920": { "name": "Confirm the project", "imports": [], "source": "export default function validate({body,statusCode,bodyEncoding,expected,kind}){if(statusCode!==200||bodyEncoding||!body||typeof body!=='object')throw Error('GitLab '+kind+' is unavailable');if(kind==='branch'&&body.name!==expected)throw Error('GitLab branch mismatch');if(kind==='project'&&!(typeof body.id==='number'||typeof body.id==='string'))throw Error('Invalid GitLab project');return{ok:true}}\n" }, "n_12ef047390ae4df7": { "name": "Confirm the branch", "imports": [], "source": "export default function validate({body,statusCode,bodyEncoding,expected,kind}){if(statusCode!==200||bodyEncoding||!body||typeof body!=='object')throw Error('GitLab '+kind+' is unavailable');if(kind==='branch'&&body.name!==expected)throw Error('GitLab branch mismatch');if(kind==='project'&&!(typeof body.id==='number'||typeof body.id==='string'))throw Error('Invalid GitLab project');return{ok:true}}\n" }, "n_1a09396202d86fb7": { "name": "Read tagged workflows", "imports": [], "source": "export default async function pages({tag,previous},context){const s=previous??{items:[],cursor:null,seen:[]};const r=await context.actions.call('n8n.list_workflows',{tags:tag.split(',').map(x=>x.trim()),limit:100,...(s.cursor?{cursor:s.cursor}:{})});if(!Array.isArray(r?.data))throw Error('Invalid workflow page');const c=r.nextCursor;if(c!==null&&(typeof c!=='string'||!c||s.seen.includes(c)))throw Error('Invalid or repeated cursor');return{state:{items:s.items.concat(r.data),cursor:c,seen:c?[...s.seen,c]:s.seen},more:c!==null}}\n" }, "n_447b98e9c41c042a": { "name": "Check backup filenames", "imports": [], "source": "export default function plan({state,path,projectEndpoint}){if(!Array.isArray(state.items))throw Error('Invalid workflows');const seen=new Set(),items=[];for(const w of state.items){if(!w||typeof w.name!=='string'||!w.name.trim()||typeof w.id!=='string'||!w.id)throw Error('Invalid workflow');const n=w.name.replace(/[^a-zA-Z0-9]/g,'')+'.json';if(n==='.json'||seen.has(n))throw Error('Workflow filenames collide or are empty');seen.add(n);const filePath=path+'/'+n;items.push({workflow:w,filePath,endpoint:projectEndpoint+'/repository/files/'+encodeURIComponent(filePath),content:JSON.stringify(w,null,4)})}return{items}}\n" }, "n_4da77a3c385857c8": { "name": "Prepare the next workflow", "imports": [], "source": "export default function next({items,previous}){const i=previous?.index??0;if(!Array.isArray(items))throw Error('Invalid backup plan');return i=300||bodyEncoding||body?.file_path!==item.filePath||body?.branch!=='main')throw Error('GitLab write not confirmed');return{ok:true}}\n" }, "n_716e2124767f3c03": { "name": "Confirm the updated backup", "imports": [], "source": "export default function confirm({body,statusCode,bodyEncoding,item}){if(statusCode<200||statusCode>=300||bodyEncoding||body?.file_path!==item.filePath||body?.branch!=='main')throw Error('GitLab write not confirmed');return{ok:true}}\n" } } }, "presentation": { "designer": { "version": 1, "flow": { "direction": "vertical" } } } }