oharu121 commited on
Commit
fb16c52
·
1 Parent(s): a0b5b79

chore(n8n): sync workflow 'git-sync-workflow' [auto-sync]

Browse files
Files changed (1) hide show
  1. workflows/git-sync-workflow.json +34 -872
workflows/git-sync-workflow.json CHANGED
@@ -1,10 +1,8 @@
1
  {
2
- "updatedAt": "2026-01-19T15:09:35.204Z",
3
- "createdAt": "2026-01-15T17:34:16.824Z",
4
  "id": "0WxkD9-eMPQr7WJy6LiDV",
5
  "name": "git-sync-workflow",
 
6
  "active": true,
7
- "isArchived": false,
8
  "nodes": [
9
  {
10
  "parameters": {
@@ -52,7 +50,7 @@
52
  "type": "n8n-nodes-base.httpRequest",
53
  "typeVersion": 4.2,
54
  "position": [
55
- -416,
56
  144
57
  ],
58
  "id": "4e6dabc2-f6f2-4141-b0ae-6be37bc342da",
@@ -78,7 +76,7 @@
78
  "type": "n8n-nodes-base.httpRequest",
79
  "typeVersion": 4.2,
80
  "position": [
81
- 32,
82
  144
83
  ],
84
  "id": "cd6044ea-f6eb-4533-9ac8-e2df8feae10d",
@@ -95,7 +93,7 @@
95
  "type": "n8n-nodes-base.noOp",
96
  "typeVersion": 1,
97
  "position": [
98
- -416,
99
  336
100
  ],
101
  "id": "80a3d37f-da98-4828-bc64-aac6074aa490",
@@ -126,7 +124,7 @@
126
  "type": "n8n-nodes-base.code",
127
  "typeVersion": 2,
128
  "position": [
129
- -192,
130
  144
131
  ],
132
  "id": "be4eaaf3-5c16-4f8b-847d-322685081b5e",
@@ -155,7 +153,7 @@
155
  "type": "n8n-nodes-base.httpRequest",
156
  "typeVersion": 4.3,
157
  "position": [
158
- -1088,
159
  240
160
  ],
161
  "id": "ecf243ba-d6a0-4c72-a8e4-44ba232b11fe",
@@ -169,12 +167,12 @@
169
  },
170
  {
171
  "parameters": {
172
- "jsCode": "const workflows = $('Get All Workflows').all();\nconst commits = $('Get GitHub Commits').all();\n\nconsole.log(\"workflows arr: \", workflows)\nconsole.log(\"commits arr: \", workflows)\nconst results = [];\nfor (let i = 0; i < workflows.length; i++) {\n const wf = workflows[i].json;\n const commit = commits[i].json;\n \n const n8nUpdatedAt = new Date(wf.updatedAt);\n const githubCommitDate = new Date(commit.commit.committer.date);\n \n const needsSync = n8nUpdatedAt > githubCommitDate;\n \n results.push({\n json: {\n ...wf,\n filename: wf.name + '.json',\n needsSync,\n reason: needsSync ? 'updated' : 'already synced'\n }\n });\n}\n\nreturn results;"
173
  },
174
  "type": "n8n-nodes-base.code",
175
  "typeVersion": 2,
176
  "position": [
177
- -864,
178
  240
179
  ],
180
  "id": "21c15c6f-2a70-49b8-8e4c-0cd3ba404492",
@@ -207,11 +205,24 @@
207
  "type": "n8n-nodes-base.if",
208
  "typeVersion": 2.2,
209
  "position": [
210
- -640,
211
  240
212
  ],
213
  "id": "8d02eba5-2aa2-44ac-b28f-622f7169de8c",
214
  "name": "Need Sync?"
 
 
 
 
 
 
 
 
 
 
 
 
 
215
  }
216
  ],
217
  "connections": {
@@ -219,7 +230,7 @@
219
  "main": [
220
  [
221
  {
222
- "node": "Get GitHub Commits",
223
  "type": "main",
224
  "index": 0
225
  }
@@ -303,6 +314,17 @@
303
  }
304
  ]
305
  ]
 
 
 
 
 
 
 
 
 
 
 
306
  }
307
  },
308
  "settings": {
@@ -314,866 +336,6 @@
314
  "templateCredsSetupCompleted": true
315
  },
316
  "pinData": {},
317
- "versionId": "e5392e8b-1af3-458b-b9de-521448e6aa94",
318
- "activeVersionId": "04dba160-9177-42d6-8df5-025c1fad9dfa",
319
- "triggerCount": 1,
320
- "shared": [
321
- {
322
- "updatedAt": "2026-01-15T17:34:16.824Z",
323
- "createdAt": "2026-01-15T17:34:16.824Z",
324
- "role": "workflow:owner",
325
- "workflowId": "0WxkD9-eMPQr7WJy6LiDV",
326
- "projectId": "1yHpLTrY34GY4WHm"
327
- }
328
- ],
329
- "activeVersion": {
330
- "updatedAt": "2026-01-17T16:20:23.412Z",
331
- "createdAt": "2026-01-17T16:07:14.599Z",
332
- "versionId": "04dba160-9177-42d6-8df5-025c1fad9dfa",
333
- "workflowId": "0WxkD9-eMPQr7WJy6LiDV",
334
- "nodes": [
335
- {
336
- "parameters": {
337
- "filters": {},
338
- "requestOptions": {}
339
- },
340
- "type": "n8n-nodes-base.n8n",
341
- "typeVersion": 1,
342
- "position": [
343
- -192,
344
- 160
345
- ],
346
- "id": "daa532fa-55b4-4a63-9b0a-c15bcc68e3fe",
347
- "name": "Get All Workflows",
348
- "credentials": {
349
- "n8nApi": {
350
- "id": "6fnLt2dVUQGp0JYd",
351
- "name": "n8n account"
352
- }
353
- }
354
- },
355
- {
356
- "parameters": {
357
- "jsCode": "// Get stored state from static data\nconst staticData = $getWorkflowStaticData('global');\nconst storedWorkflows = staticData.workflows || {};\n\n// Current workflows from n8n API\nconst currentWorkflows = $input.all()\n .map(item => item.json)\n\n// Build current state map\nconst currentMap = {};\nfor (const wf of currentWorkflows) {\n currentMap[wf.id] = {\n id: wf.id,\n name: wf.name,\n updatedAt: wf.updatedAt,\n workflow: wf\n };\n}\n\n// Detect changes\nconst created = [];\nconst updated = [];\nconst deleted = [];\n\n// Find created and updated workflows\nfor (const id in currentMap) {\n const current = currentMap[id];\n const stored = storedWorkflows[id];\n \n if (!stored) {\n // New workflow\n created.push(current);\n } else if (stored.updatedAt !== current.updatedAt) {\n // Updated workflow\n updated.push(current);\n }\n}\n\n// Find deleted workflows\nfor (const id in storedWorkflows) {\n if (!currentMap[id]) {\n deleted.push(storedWorkflows[id]);\n }\n}\n\n// Helper: sanitize workflow name for filename\nfunction sanitizeName(name) {\n return name\n .toLowerCase()\n .replace(/[^a-z0-9\\s-]/g, '')\n .replace(/\\s+/g, '-')\n .replace(/-+/g, '-')\n .replace(/^-|-$/g, '');\n}\n\n// Prepare output items\nconst changes = {\n created: created.map(wf => ({\n ...wf,\n filename: sanitizeName(wf.name) + '.json',\n action: 'create'\n })),\n updated: updated.map(wf => ({\n ...wf,\n filename: sanitizeName(wf.name) + '.json',\n action: 'update'\n })),\n deleted: deleted.map(wf => ({\n ...wf,\n filename: sanitizeName(wf.name) + '.json',\n action: 'delete'\n })),\n hasChanges: created.length > 0 || updated.length > 0 || deleted.length > 0,\n currentMap: currentMap,\n summary: `Created: ${created.length}, Updated: ${updated.length}, Deleted: ${deleted.length}`\n};\n\nreturn [{ json: changes }];"
358
- },
359
- "type": "n8n-nodes-base.code",
360
- "typeVersion": 2,
361
- "position": [
362
- 32,
363
- 160
364
- ],
365
- "id": "76d0dbcb-2da3-4d04-88f0-03ca66b9ebb5",
366
- "name": "Detect Changes"
367
- },
368
- {
369
- "parameters": {
370
- "conditions": {
371
- "options": {
372
- "caseSensitive": true,
373
- "leftValue": "",
374
- "typeValidation": "strict",
375
- "version": 2
376
- },
377
- "conditions": [
378
- {
379
- "id": "has-changes-condition",
380
- "leftValue": "={{ $json.hasChanges }}",
381
- "rightValue": true,
382
- "operator": {
383
- "type": "boolean",
384
- "operation": "equals"
385
- }
386
- }
387
- ],
388
- "combinator": "and"
389
- },
390
- "options": {}
391
- },
392
- "type": "n8n-nodes-base.if",
393
- "typeVersion": 2.2,
394
- "position": [
395
- 256,
396
- 160
397
- ],
398
- "id": "8d02eba5-2aa2-44ac-b28f-622f7169de8c",
399
- "name": "Has Changes?"
400
- },
401
- {
402
- "parameters": {
403
- "jsCode": "// Combine all changes into individual items for processing\nconst input = $input.first().json;\nconst allChanges = [\n ...input.created,\n ...input.updated,\n ...input.deleted\n];\n\n// Also pass along the currentMap for later storage\n// And encode workflow content to base64 for GitHub API\nreturn allChanges.map(change => {\n let contentBase64 = null;\n if (change.action !== 'delete' && change.workflow) {\n // Pretty print the workflow JSON and encode to base64\n const jsonStr = JSON.stringify(change.workflow, null, 2);\n contentBase64 = Buffer.from(jsonStr).toString('base64');\n }\n return {\n json: {\n ...change,\n contentBase64: contentBase64,\n currentMap: input.currentMap\n }\n };\n});"
404
- },
405
- "type": "n8n-nodes-base.code",
406
- "typeVersion": 2,
407
- "position": [
408
- 480,
409
- 64
410
- ],
411
- "id": "1a53420a-e811-4882-81df-1c24c9fd2315",
412
- "name": "Split Into Items"
413
- },
414
- {
415
- "parameters": {
416
- "url": "=https://api.github.com/repos/oharu121/n8n-workflow/contents/workflows/{{ $json.filename }}",
417
- "authentication": "genericCredentialType",
418
- "genericAuthType": "httpBearerAuth",
419
- "sendQuery": true,
420
- "queryParameters": {
421
- "parameters": [
422
- {
423
- "name": "ref",
424
- "value": "n8n-sync"
425
- }
426
- ]
427
- },
428
- "options": {
429
- "response": {
430
- "response": {
431
- "neverError": true,
432
- "responseFormat": "json"
433
- }
434
- }
435
- }
436
- },
437
- "type": "n8n-nodes-base.httpRequest",
438
- "typeVersion": 4.2,
439
- "position": [
440
- 704,
441
- 64
442
- ],
443
- "id": "4e6dabc2-f6f2-4141-b0ae-6be37bc342da",
444
- "name": "Get File SHA",
445
- "credentials": {
446
- "httpBearerAuth": {
447
- "id": "6JPGyoToOxOcHftx",
448
- "name": "n8n sync github token"
449
- }
450
- }
451
- },
452
- {
453
- "parameters": {
454
- "conditions": {
455
- "options": {
456
- "caseSensitive": true,
457
- "leftValue": "",
458
- "typeValidation": "strict",
459
- "version": 2
460
- },
461
- "conditions": [
462
- {
463
- "id": "is-delete-condition",
464
- "leftValue": "={{ $('Split Into Items').item.json.action }}",
465
- "rightValue": "delete",
466
- "operator": {
467
- "type": "string",
468
- "operation": "equals"
469
- }
470
- }
471
- ],
472
- "combinator": "and"
473
- },
474
- "options": {}
475
- },
476
- "type": "n8n-nodes-base.if",
477
- "typeVersion": 2.2,
478
- "position": [
479
- 928,
480
- 64
481
- ],
482
- "id": "a110401e-0f76-41c8-a8e3-63837e7149f6",
483
- "name": "Is Delete?"
484
- },
485
- {
486
- "parameters": {
487
- "method": "DELETE",
488
- "url": "=https://api.github.com/repos/oharu121/n8n-workflow/contents/workflows/{{ $json.filename }}",
489
- "authentication": "genericCredentialType",
490
- "genericAuthType": "httpBearerAuth",
491
- "sendBody": true,
492
- "specifyBody": "json",
493
- "jsonBody": "={\n \"message\": \"chore(n8n): remove workflow '{{ $json.name }}' [auto-sync]\",\n \"sha\": \"{{ $('Get File SHA').item.json.sha }}\",\n \"branch\": \"n8n-sync\"\n}",
494
- "options": {}
495
- },
496
- "type": "n8n-nodes-base.httpRequest",
497
- "typeVersion": 4.2,
498
- "position": [
499
- 1376,
500
- -32
501
- ],
502
- "id": "5c9baae8-21f8-4b4d-9848-d50e946c35c6",
503
- "name": "Delete File",
504
- "credentials": {
505
- "httpHeaderAuth": {
506
- "id": "IWWp65Bj7tNkqAlg",
507
- "name": "Header Auth account"
508
- },
509
- "httpBearerAuth": {
510
- "id": "6JPGyoToOxOcHftx",
511
- "name": "n8n sync github token"
512
- }
513
- }
514
- },
515
- {
516
- "parameters": {
517
- "method": "PUT",
518
- "url": "=https://api.github.com/repos/oharu121/n8n-workflow/contents/workflows/{{ $('Split Into Items').item.json.filename }}\n",
519
- "authentication": "genericCredentialType",
520
- "genericAuthType": "httpBearerAuth",
521
- "sendBody": true,
522
- "specifyBody": "json",
523
- "jsonBody": "={{ $json.requestBody }}",
524
- "options": {}
525
- },
526
- "type": "n8n-nodes-base.httpRequest",
527
- "typeVersion": 4.2,
528
- "position": [
529
- 1376,
530
- 160
531
- ],
532
- "id": "cd6044ea-f6eb-4533-9ac8-e2df8feae10d",
533
- "name": "Create/Update File",
534
- "credentials": {
535
- "httpBearerAuth": {
536
- "id": "6JPGyoToOxOcHftx",
537
- "name": "n8n sync github token"
538
- }
539
- }
540
- },
541
- {
542
- "parameters": {
543
- "aggregate": "aggregateAllItemData",
544
- "options": {}
545
- },
546
- "type": "n8n-nodes-base.aggregate",
547
- "typeVersion": 1,
548
- "position": [
549
- 1600,
550
- 64
551
- ],
552
- "id": "049c6fcc-7505-406b-834d-1de7311330fe",
553
- "name": "Aggregate Results"
554
- },
555
- {
556
- "parameters": {
557
- "url": "=https://api.github.com/repos/oharu121/n8n-workflow/pulls",
558
- "authentication": "genericCredentialType",
559
- "genericAuthType": "httpBearerAuth",
560
- "sendQuery": true,
561
- "queryParameters": {
562
- "parameters": [
563
- {
564
- "name": "head",
565
- "value": "=oharu121:n8n-sync"
566
- },
567
- {
568
- "name": "base",
569
- "value": "main"
570
- },
571
- {
572
- "name": "state",
573
- "value": "open"
574
- }
575
- ]
576
- },
577
- "options": {}
578
- },
579
- "type": "n8n-nodes-base.httpRequest",
580
- "typeVersion": 4.2,
581
- "position": [
582
- 1824,
583
- 64
584
- ],
585
- "id": "8cd401f7-0176-4eeb-b89c-a1870a3dd0aa",
586
- "name": "Check Existing PR",
587
- "alwaysOutputData": true,
588
- "credentials": {
589
- "httpBearerAuth": {
590
- "id": "6JPGyoToOxOcHftx",
591
- "name": "n8n sync github token"
592
- }
593
- }
594
- },
595
- {
596
- "parameters": {
597
- "conditions": {
598
- "options": {
599
- "caseSensitive": true,
600
- "leftValue": "",
601
- "typeValidation": "strict",
602
- "version": 2
603
- },
604
- "conditions": [
605
- {
606
- "id": "no-pr-condition",
607
- "leftValue": "={{ !$json.number }}",
608
- "rightValue": 0,
609
- "operator": {
610
- "type": "boolean",
611
- "operation": "false",
612
- "singleValue": true
613
- }
614
- }
615
- ],
616
- "combinator": "and"
617
- },
618
- "options": {}
619
- },
620
- "type": "n8n-nodes-base.if",
621
- "typeVersion": 2.2,
622
- "position": [
623
- 2048,
624
- 64
625
- ],
626
- "id": "5de350cb-256f-40b9-b86a-c8a7fc81be86",
627
- "name": "PR Exists?"
628
- },
629
- {
630
- "parameters": {
631
- "method": "POST",
632
- "url": "=https://api.github.com/repos/oharu121/n8n-workflow/pulls",
633
- "authentication": "genericCredentialType",
634
- "genericAuthType": "httpBearerAuth",
635
- "sendBody": true,
636
- "specifyBody": "json",
637
- "jsonBody": "={\n \"title\": \"chore(n8n): workflow sync [auto]\",\n \"head\": \"n8n-sync\",\n \"base\": \"main\",\n \"body\": \"## Automated n8n Workflow Sync\\n\\nThis PR was automatically created by the git-sync workflow.\\n\\n### Changes\\nWorkflows have been synchronized from the n8n instance.\\n\\n---\\n*Auto-generated by git-sync-workflow*\"\n}",
638
- "options": {}
639
- },
640
- "type": "n8n-nodes-base.httpRequest",
641
- "typeVersion": 4.2,
642
- "position": [
643
- 2272,
644
- 160
645
- ],
646
- "id": "9325213c-e9f5-4bbd-9fa6-8f545bb1bddf",
647
- "name": "Create PR",
648
- "credentials": {
649
- "httpBearerAuth": {
650
- "id": "6JPGyoToOxOcHftx",
651
- "name": "n8n sync github token"
652
- }
653
- }
654
- },
655
- {
656
- "parameters": {
657
- "method": "PUT",
658
- "url": "=https://api.github.com/repos/oharu121/n8n-workflow/pulls/{{ $json.number }}/merge",
659
- "authentication": "genericCredentialType",
660
- "genericAuthType": "httpBearerAuth",
661
- "sendBody": true,
662
- "specifyBody": "json",
663
- "jsonBody": "={\n \"commit_title\": \"chore(n8n): workflow sync [auto]\",\n \"merge_method\": \"squash\"\n}",
664
- "options": {
665
- "response": {
666
- "response": {
667
- "neverError": true
668
- }
669
- }
670
- }
671
- },
672
- "type": "n8n-nodes-base.httpRequest",
673
- "typeVersion": 4.2,
674
- "position": [
675
- 2496,
676
- 64
677
- ],
678
- "id": "d4d37f81-762d-42e3-bede-d47a916f5b00",
679
- "name": "Merge PR (Auto)",
680
- "credentials": {
681
- "httpBearerAuth": {
682
- "id": "6JPGyoToOxOcHftx",
683
- "name": "n8n sync github token"
684
- }
685
- }
686
- },
687
- {
688
- "parameters": {
689
- "jsCode": "// Store the current workflow state for next run\nconst staticData = $getWorkflowStaticData('global');\n\n// Get currentMap from first item (all items have it)\nconst firstItem = $input.first();\nif (firstItem && firstItem.json && firstItem.json.currentMap) {\n staticData.workflows = firstItem.json.currentMap;\n}\n\nreturn [{ json: { message: 'State saved successfully', timestamp: new Date().toISOString() } }];"
690
- },
691
- "type": "n8n-nodes-base.code",
692
- "typeVersion": 2,
693
- "position": [
694
- 2720,
695
- 64
696
- ],
697
- "id": "ae6207cf-46d8-4361-aff0-ea31908fc1c7",
698
- "name": "Save State"
699
- },
700
- {
701
- "parameters": {
702
- "url": "=https://api.github.com/repos/oharu121/n8n-workflow/git/refs/heads/n8n-sync",
703
- "authentication": "genericCredentialType",
704
- "genericAuthType": "httpBearerAuth",
705
- "options": {
706
- "response": {
707
- "response": {
708
- "neverError": true
709
- }
710
- }
711
- }
712
- },
713
- "type": "n8n-nodes-base.httpRequest",
714
- "typeVersion": 4.2,
715
- "position": [
716
- -1312,
717
- 160
718
- ],
719
- "id": "ed53a1b6-2c12-412e-949d-617dcf230bef",
720
- "name": "Check Branch Exists",
721
- "credentials": {
722
- "httpHeaderAuth": {
723
- "id": "IWWp65Bj7tNkqAlg",
724
- "name": "Header Auth account"
725
- },
726
- "httpBearerAuth": {
727
- "id": "6JPGyoToOxOcHftx",
728
- "name": "n8n sync github token"
729
- }
730
- }
731
- },
732
- {
733
- "parameters": {
734
- "conditions": {
735
- "options": {
736
- "caseSensitive": true,
737
- "leftValue": "",
738
- "typeValidation": "strict",
739
- "version": 2
740
- },
741
- "conditions": [
742
- {
743
- "id": "branch-not-found",
744
- "leftValue": "={{ $json.message }}",
745
- "rightValue": "Not Found",
746
- "operator": {
747
- "type": "string",
748
- "operation": "notEquals"
749
- }
750
- }
751
- ],
752
- "combinator": "and"
753
- },
754
- "options": {}
755
- },
756
- "type": "n8n-nodes-base.if",
757
- "typeVersion": 2.2,
758
- "position": [
759
- -1088,
760
- 160
761
- ],
762
- "id": "e4580e40-f784-43fb-be23-5766c156ba6c",
763
- "name": "Branch Exists?"
764
- },
765
- {
766
- "parameters": {
767
- "url": "=https://api.github.com/repos/oharu121/n8n-workflow/git/refs/heads/main",
768
- "authentication": "genericCredentialType",
769
- "genericAuthType": "httpBearerAuth",
770
- "options": {}
771
- },
772
- "type": "n8n-nodes-base.httpRequest",
773
- "typeVersion": 4.2,
774
- "position": [
775
- -864,
776
- 256
777
- ],
778
- "id": "7aa53065-4271-479d-b073-ddaaf73cd6ad",
779
- "name": "Get Main SHA",
780
- "credentials": {
781
- "httpHeaderAuth": {
782
- "id": "IWWp65Bj7tNkqAlg",
783
- "name": "Header Auth account"
784
- },
785
- "httpBearerAuth": {
786
- "id": "6JPGyoToOxOcHftx",
787
- "name": "n8n sync github token"
788
- }
789
- }
790
- },
791
- {
792
- "parameters": {
793
- "method": "POST",
794
- "url": "=https://api.github.com/repos/oharu121/n8n-workflow/git/refs",
795
- "authentication": "genericCredentialType",
796
- "genericAuthType": "httpBearerAuth",
797
- "sendBody": true,
798
- "specifyBody": "json",
799
- "jsonBody": "={\n \"ref\": \"refs/heads/n8n-sync\",\n \"sha\": \"{{ $json.object.sha }}\"\n}",
800
- "options": {}
801
- },
802
- "type": "n8n-nodes-base.httpRequest",
803
- "typeVersion": 4.2,
804
- "position": [
805
- -640,
806
- 256
807
- ],
808
- "id": "640fb613-1684-410b-86d9-790ffec332af",
809
- "name": "Create n8n-sync Branch",
810
- "credentials": {
811
- "httpHeaderAuth": {
812
- "id": "IWWp65Bj7tNkqAlg",
813
- "name": "Header Auth account"
814
- },
815
- "httpBearerAuth": {
816
- "id": "6JPGyoToOxOcHftx",
817
- "name": "n8n sync github token"
818
- }
819
- }
820
- },
821
- {
822
- "parameters": {},
823
- "type": "n8n-nodes-base.noOp",
824
- "typeVersion": 1,
825
- "position": [
826
- 480,
827
- 256
828
- ],
829
- "id": "80a3d37f-da98-4828-bc64-aac6074aa490",
830
- "name": "No Changes"
831
- },
832
- {
833
- "parameters": {
834
- "jsCode": "// Get the existing PR from the check\nconst existingPRs = $('Check Existing PR').first().json;\nif (existingPRs && existingPRs.length > 0) {\n return [{ json: existingPRs[0] }];\n}\nreturn [];"
835
- },
836
- "type": "n8n-nodes-base.code",
837
- "typeVersion": 2,
838
- "position": [
839
- 2272,
840
- -32
841
- ],
842
- "id": "cc98547d-7920-4b86-ae23-dbf29e488adb",
843
- "name": "Get Existing PR"
844
- },
845
- {
846
- "parameters": {
847
- "rule": {
848
- "interval": [
849
- {}
850
- ]
851
- }
852
- },
853
- "type": "n8n-nodes-base.scheduleTrigger",
854
- "typeVersion": 1.2,
855
- "position": [
856
- -1536,
857
- 160
858
- ],
859
- "id": "6181b14b-80e7-48d6-85e8-60d1eed86d35",
860
- "name": "Schedule Trigger"
861
- },
862
- {
863
- "parameters": {},
864
- "type": "n8n-nodes-base.noOp",
865
- "typeVersion": 1,
866
- "position": [
867
- -640,
868
- 64
869
- ],
870
- "id": "62286096-97d8-4736-abd0-695fadb630f3",
871
- "name": "Branch is ready"
872
- },
873
- {
874
- "parameters": {
875
- "mode": "runOnceForEachItem",
876
- "jsCode": "const original = $('Split Into Items').item.json;\nconst sha = $json.sha;\n\nconst body = {\n message: `chore(n8n): sync workflow '${original.name}' [auto-sync]`,\n content: original.contentBase64,\n branch: 'n8n-sync'\n};\n\nif (sha) {\n body.sha = sha;\n}\n\nreturn { requestBody: body, filename: original.filename };\n"
877
- },
878
- "type": "n8n-nodes-base.code",
879
- "typeVersion": 2,
880
- "position": [
881
- 1152,
882
- 160
883
- ],
884
- "id": "be4eaaf3-5c16-4f8b-847d-322685081b5e",
885
- "name": "Build Request Body"
886
- },
887
- {
888
- "parameters": {},
889
- "type": "n8n-nodes-base.merge",
890
- "typeVersion": 3.2,
891
- "position": [
892
- -416,
893
- 160
894
- ],
895
- "id": "dc59c629-2ce8-4968-a108-b88f4e0bd003",
896
- "name": "Merge"
897
- }
898
- ],
899
- "connections": {
900
- "Get All Workflows": {
901
- "main": [
902
- [
903
- {
904
- "node": "Detect Changes",
905
- "type": "main",
906
- "index": 0
907
- }
908
- ]
909
- ]
910
- },
911
- "Detect Changes": {
912
- "main": [
913
- [
914
- {
915
- "node": "Has Changes?",
916
- "type": "main",
917
- "index": 0
918
- }
919
- ]
920
- ]
921
- },
922
- "Has Changes?": {
923
- "main": [
924
- [
925
- {
926
- "node": "Split Into Items",
927
- "type": "main",
928
- "index": 0
929
- }
930
- ],
931
- [
932
- {
933
- "node": "No Changes",
934
- "type": "main",
935
- "index": 0
936
- }
937
- ]
938
- ]
939
- },
940
- "Split Into Items": {
941
- "main": [
942
- [
943
- {
944
- "node": "Get File SHA",
945
- "type": "main",
946
- "index": 0
947
- }
948
- ]
949
- ]
950
- },
951
- "Get File SHA": {
952
- "main": [
953
- [
954
- {
955
- "node": "Is Delete?",
956
- "type": "main",
957
- "index": 0
958
- }
959
- ]
960
- ]
961
- },
962
- "Is Delete?": {
963
- "main": [
964
- [
965
- {
966
- "node": "Delete File",
967
- "type": "main",
968
- "index": 0
969
- }
970
- ],
971
- [
972
- {
973
- "node": "Build Request Body",
974
- "type": "main",
975
- "index": 0
976
- }
977
- ]
978
- ]
979
- },
980
- "Delete File": {
981
- "main": [
982
- [
983
- {
984
- "node": "Aggregate Results",
985
- "type": "main",
986
- "index": 0
987
- }
988
- ]
989
- ]
990
- },
991
- "Create/Update File": {
992
- "main": [
993
- [
994
- {
995
- "node": "Aggregate Results",
996
- "type": "main",
997
- "index": 0
998
- }
999
- ]
1000
- ]
1001
- },
1002
- "Aggregate Results": {
1003
- "main": [
1004
- [
1005
- {
1006
- "node": "Check Existing PR",
1007
- "type": "main",
1008
- "index": 0
1009
- }
1010
- ]
1011
- ]
1012
- },
1013
- "Check Existing PR": {
1014
- "main": [
1015
- [
1016
- {
1017
- "node": "PR Exists?",
1018
- "type": "main",
1019
- "index": 0
1020
- }
1021
- ]
1022
- ]
1023
- },
1024
- "PR Exists?": {
1025
- "main": [
1026
- [
1027
- {
1028
- "node": "Get Existing PR",
1029
- "type": "main",
1030
- "index": 0
1031
- }
1032
- ],
1033
- [
1034
- {
1035
- "node": "Create PR",
1036
- "type": "main",
1037
- "index": 0
1038
- }
1039
- ]
1040
- ]
1041
- },
1042
- "Create PR": {
1043
- "main": [
1044
- [
1045
- {
1046
- "node": "Merge PR (Auto)",
1047
- "type": "main",
1048
- "index": 0
1049
- }
1050
- ]
1051
- ]
1052
- },
1053
- "Merge PR (Auto)": {
1054
- "main": [
1055
- [
1056
- {
1057
- "node": "Save State",
1058
- "type": "main",
1059
- "index": 0
1060
- }
1061
- ]
1062
- ]
1063
- },
1064
- "Check Branch Exists": {
1065
- "main": [
1066
- [
1067
- {
1068
- "node": "Branch Exists?",
1069
- "type": "main",
1070
- "index": 0
1071
- }
1072
- ]
1073
- ]
1074
- },
1075
- "Branch Exists?": {
1076
- "main": [
1077
- [
1078
- {
1079
- "node": "Branch is ready",
1080
- "type": "main",
1081
- "index": 0
1082
- }
1083
- ],
1084
- [
1085
- {
1086
- "node": "Get Main SHA",
1087
- "type": "main",
1088
- "index": 0
1089
- }
1090
- ]
1091
- ]
1092
- },
1093
- "Get Main SHA": {
1094
- "main": [
1095
- [
1096
- {
1097
- "node": "Create n8n-sync Branch",
1098
- "type": "main",
1099
- "index": 0
1100
- }
1101
- ]
1102
- ]
1103
- },
1104
- "Get Existing PR": {
1105
- "main": [
1106
- [
1107
- {
1108
- "node": "Merge PR (Auto)",
1109
- "type": "main",
1110
- "index": 0
1111
- }
1112
- ]
1113
- ]
1114
- },
1115
- "Schedule Trigger": {
1116
- "main": [
1117
- [
1118
- {
1119
- "node": "Check Branch Exists",
1120
- "type": "main",
1121
- "index": 0
1122
- }
1123
- ]
1124
- ]
1125
- },
1126
- "Build Request Body": {
1127
- "main": [
1128
- [
1129
- {
1130
- "node": "Create/Update File",
1131
- "type": "main",
1132
- "index": 0
1133
- }
1134
- ]
1135
- ]
1136
- },
1137
- "Create n8n-sync Branch": {
1138
- "main": [
1139
- [
1140
- {
1141
- "node": "Merge",
1142
- "type": "main",
1143
- "index": 1
1144
- }
1145
- ]
1146
- ]
1147
- },
1148
- "Branch is ready": {
1149
- "main": [
1150
- [
1151
- {
1152
- "node": "Merge",
1153
- "type": "main",
1154
- "index": 0
1155
- }
1156
- ]
1157
- ]
1158
- },
1159
- "Merge": {
1160
- "main": [
1161
- [
1162
- {
1163
- "node": "Get All Workflows",
1164
- "type": "main",
1165
- "index": 0
1166
- }
1167
- ]
1168
- ]
1169
- }
1170
- },
1171
- "authors": "Yuchen Lin",
1172
- "name": "Version 04dba160",
1173
- "description": "first publish",
1174
- "autosaved": false
1175
- },
1176
- "tags": [],
1177
  "filename": "git-sync-workflow.json",
1178
  "needsSync": true,
1179
  "reason": "updated"
 
1
  {
 
 
2
  "id": "0WxkD9-eMPQr7WJy6LiDV",
3
  "name": "git-sync-workflow",
4
+ "updatedAt": "2026-01-19T15:18:45.786Z",
5
  "active": true,
 
6
  "nodes": [
7
  {
8
  "parameters": {
 
50
  "type": "n8n-nodes-base.httpRequest",
51
  "typeVersion": 4.2,
52
  "position": [
53
+ -208,
54
  144
55
  ],
56
  "id": "4e6dabc2-f6f2-4141-b0ae-6be37bc342da",
 
76
  "type": "n8n-nodes-base.httpRequest",
77
  "typeVersion": 4.2,
78
  "position": [
79
+ 240,
80
  144
81
  ],
82
  "id": "cd6044ea-f6eb-4533-9ac8-e2df8feae10d",
 
93
  "type": "n8n-nodes-base.noOp",
94
  "typeVersion": 1,
95
  "position": [
96
+ -208,
97
  336
98
  ],
99
  "id": "80a3d37f-da98-4828-bc64-aac6074aa490",
 
124
  "type": "n8n-nodes-base.code",
125
  "typeVersion": 2,
126
  "position": [
127
+ 16,
128
  144
129
  ],
130
  "id": "be4eaaf3-5c16-4f8b-847d-322685081b5e",
 
153
  "type": "n8n-nodes-base.httpRequest",
154
  "typeVersion": 4.3,
155
  "position": [
156
+ -880,
157
  240
158
  ],
159
  "id": "ecf243ba-d6a0-4c72-a8e4-44ba232b11fe",
 
167
  },
168
  {
169
  "parameters": {
170
+ "jsCode": "const workflows = $('Slim Workflows').all();\nconst commits = $('Get GitHub Commits').all();\n\nconst results = [];\nfor (let i = 0; i < workflows.length; i++) {\n const wf = workflows[i].json;\n const commit = commits[i].json;\n \n const n8nUpdatedAt = new Date(wf.updatedAt);\n const githubCommitDate = new Date(commit.commit.committer.date);\n \n const needsSync = n8nUpdatedAt > githubCommitDate;\n \n results.push({\n json: {\n ...wf,\n filename: wf.name + '.json',\n needsSync,\n reason: needsSync ? 'updated' : 'already synced'\n }\n });\n}\n\nreturn results;"
171
  },
172
  "type": "n8n-nodes-base.code",
173
  "typeVersion": 2,
174
  "position": [
175
+ -656,
176
  240
177
  ],
178
  "id": "21c15c6f-2a70-49b8-8e4c-0cd3ba404492",
 
205
  "type": "n8n-nodes-base.if",
206
  "typeVersion": 2.2,
207
  "position": [
208
+ -432,
209
  240
210
  ],
211
  "id": "8d02eba5-2aa2-44ac-b28f-622f7169de8c",
212
  "name": "Need Sync?"
213
+ },
214
+ {
215
+ "parameters": {
216
+ "jsCode": "const workflows = $input.all();\n\nreturn workflows.map(item => {\n const wf = item.json;\n \n // Keep only essential fields for sync\n return {\n json: {\n id: wf.id,\n name: wf.name,\n updatedAt: wf.updatedAt,\n active: wf.active,\n nodes: wf.nodes,\n connections: wf.connections,\n settings: wf.settings,\n staticData: wf.staticData || null,\n meta: wf.meta,\n pinData: wf.pinData || {}\n }\n };\n});\n"
217
+ },
218
+ "type": "n8n-nodes-base.code",
219
+ "typeVersion": 2,
220
+ "position": [
221
+ -1104,
222
+ 240
223
+ ],
224
+ "id": "7373959d-cf1c-4fe4-8fd9-14e9ea6e82c3",
225
+ "name": "Slim Workflows"
226
  }
227
  ],
228
  "connections": {
 
230
  "main": [
231
  [
232
  {
233
+ "node": "Slim Workflows",
234
  "type": "main",
235
  "index": 0
236
  }
 
314
  }
315
  ]
316
  ]
317
+ },
318
+ "Slim Workflows": {
319
+ "main": [
320
+ [
321
+ {
322
+ "node": "Get GitHub Commits",
323
+ "type": "main",
324
+ "index": 0
325
+ }
326
+ ]
327
+ ]
328
  }
329
  },
330
  "settings": {
 
336
  "templateCredsSetupCompleted": true
337
  },
338
  "pinData": {},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
339
  "filename": "git-sync-workflow.json",
340
  "needsSync": true,
341
  "reason": "updated"