{
  "id": "B9XHO1B8oUR04nOu",
  "meta": {
    "templateCredsSetupCompleted": true
  },
  "name": "My workflow 19",
  "tags": [],
  "nodes": [
    {
      "id": "8465e817-4dec-4d5e-b607-6e46db16b6e7",
      "name": "Commit Message Breakdown",
      "type": "n8n-nodes-base.code",
      "position": [
        800,
        1160
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "const commitMessage = $json.body.commits[0].message;\nconst fullRef = $json.body.ref;\nconst pushBranch = fullRef.startsWith('refs/heads/') ? fullRef.slice('refs/heads/'.length) : fullRef;\n\n// Updated regex to make the [...] part optional\nconst regex = /^([A-Z]+-\\d+)\\s(.*?)(?:\\s\\[(.*)\\])?$/;\nconst match = commitMessage.match(regex);\n\nif (!match) {\n  throw new Error(\"Commit message format is incorrect. Missing task key or message.\");\n}\n\nconst jiraKey = match[1];\nconst commitDescription = match[2].trim();\nconst flagString = match[3];\n\nconst flags = flagString ? flagString.split(',').map(s => s.trim()) : [];\n\nconst baseBranch = flags.find(f => !['auto-pr', 'taskcompleted'].includes(f));\nconst autoPR = flags.includes('auto-pr');\nconst taskCompleted = flags.includes('taskcompleted');\n\n// Validation rules\nif (autoPR && !baseBranch) {\n  throw new Error(\"Commit message error: Please enter a base branch to create the PR in.\");\n}\n\nreturn {\n  json: {\n    jiraKey,\n    commitDescription,\n    commands: flags,\n    baseBranch,\n    autoPR,\n    taskCompleted,\n    pushBranch\n  }\n};\n"
      },
      "typeVersion": 2
    },
    {
      "id": "6046dbdd-8494-4e58-966d-83b8fdae1759",
      "name": "Check for PR commands",
      "type": "n8n-nodes-base.if",
      "position": [
        1220,
        1160
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "0837a6e7-03a7-4a80-b263-4e75a4cc3efb",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.autoPR.toString() }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "1d931b22-aaae-4afe-8f20-4478944eef1a",
      "name": "Request to create PR",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2160,
        1000
      ],
      "parameters": {
        "url": "=https://api.github.com/repos/{YOUR_GITHUB_OWNER_NAME}/{YOUR_GITHUB_REPO_NAME}/pulls",
        "method": "POST",
        "options": {},
        "jsonBody": "={\n  \"title\": \"{{$('Commit Message Breakdown').item.json.jiraKey}} {{$('Commit Message Breakdown').item.json.commitDescription}}\",\n  \"head\": \"{{$('Commit Message Breakdown').item.json.pushBranch}}\",\n  \"base\": \"{{$('Commit Message Breakdown').item.json.baseBranch}}\",\n  \"body\": \"Auto Generated PR for Jira Task {{$('Commit Message Breakdown').item.json.jiraKey}}\"\n}\n",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "githubApi"
      },
      "typeVersion": 4.2
    },
    {
      "id": "8d200a8c-de05-4bce-9150-88a34749b09a",
      "name": "Github Trigger",
      "type": "n8n-nodes-base.githubTrigger",
      "position": [
        320,
        1160
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "{YOUR_GITHUB_NAME}"
        },
        "events": [
          "push"
        ],
        "options": {},
        "repository": {
          "__rl": true,
          "mode": "list",
          "value": "github-jira-automation",
          "cachedResultUrl": "https://github.com/{YOUR_GITHUB_OWNER_NAME}/{YOUR_GITHUB_REPO_NAME}",
          "cachedResultName": "github-jira-automation"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "9e61e558-fbf3-4cef-96f4-a6732ffd8373",
      "name": "Invalid commit message",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        2140,
        1760
      ],
      "parameters": {
        "errorMessage": "Workflow stopped due to invalid commit message or no commands provided"
      },
      "typeVersion": 1
    },
    {
      "id": "f3a3d76c-6713-407a-92a2-117a6cef4674",
      "name": "JIRA Task does not exist",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        3080,
        1100
      ],
      "parameters": {
        "errorMessage": "Workflow stopped due to invalid task or no taskcompleted command"
      },
      "typeVersion": 1
    },
    {
      "id": "45ffc321-9cf6-4d63-a303-5cbd9fcc9f5a",
      "name": "Check for task completed command",
      "type": "n8n-nodes-base.if",
      "position": [
        1540,
        1400
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3945b951-fc98-45b2-8194-9b712cc15705",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.taskCompleted.toString() }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "805644e9-e934-4e8e-8d2d-0a0340ae1313",
      "name": "Get task details for PR",
      "type": "n8n-nodes-base.jira",
      "position": [
        1720,
        780
      ],
      "parameters": {
        "issueKey": "={{ $('Check for PR commands').item.json.jiraKey }}",
        "operation": "get",
        "additionalFields": {}
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "3588f1d5-d44c-429f-84d4-2d59b9df9d19",
      "name": "Get Task Details without PR.",
      "type": "n8n-nodes-base.jira",
      "position": [
        2160,
        1260
      ],
      "parameters": {
        "issueKey": "={{ $json.jiraKey }}",
        "operation": "get",
        "additionalFields": {}
      },
      "typeVersion": 1
    },
    {
      "id": "37f80bcc-bdcd-440f-86a5-d71e7c6084fa",
      "name": "Check if task exist",
      "type": "n8n-nodes-base.if",
      "position": [
        2960,
        800
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "3bda73c5-47f6-4605-b9db-17e74ccc2bcb",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{$('Get task details for PR').item.json.id}}",
              "rightValue": ""
            },
            {
              "id": "77d6fa4e-a7c2-4f66-810a-5566a1d78501",
              "operator": {
                "name": "filter.operator.equals",
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Commit Message Breakdown').item.json.taskCompleted.toString() }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "5fa57725-9731-415a-b6c9-3468ba3cc294",
      "name": "Update task status after PR",
      "type": "n8n-nodes-base.jira",
      "position": [
        3380,
        780
      ],
      "parameters": {
        "issueKey": "={{ $('Get task details for PR').item.json.key}}",
        "operation": "update",
        "updateFields": {
          "statusId": {
            "__rl": true,
            "mode": "list",
            "value": "61",
            "cachedResultName": "Development Done"
          }
        }
      },
      "typeVersion": 1
    },
    {
      "id": "4d6f5d00-df3c-477b-b6e1-561502851cc8",
      "name": "Check whether a PR already exists",
      "type": "n8n-nodes-base.if",
      "position": [
        2500,
        620
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b63c7d9a-7f1d-497b-838b-f617bcab9457",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.id.toString() }}",
              "rightValue": ""
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "e8c58c09-0d35-4928-867d-441f894bcd0d",
      "name": "Update the task status without PR",
      "type": "n8n-nodes-base.jira",
      "position": [
        3080,
        1420
      ],
      "parameters": {
        "issueKey": "={{ $json.key }}",
        "operation": "update",
        "updateFields": {
          "statusId": {
            "__rl": true,
            "mode": "list",
            "value": "61",
            "cachedResultName": "Development Done"
          }
        }
      },
      "typeVersion": 1
    },
    {
      "id": "d8c0c38a-fdd3-49c1-b566-bb35ecaa9f92",
      "name": "Check if PR exists",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        2060,
        620
      ],
      "parameters": {
        "url": "=https://api.github.com/repos/{YOUR_GITHUB_OWNER_NAME}/{YOUR_REPO_NAME}/pulls?head={YOUR_GITHUB_OWNER_NAME}:{{ $('Commit Message Breakdown').item.json.pushBranch }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "githubApi"
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "67f8edcb-4647-4ee1-8fff-e25a0482528b",
      "name": "Check if task exists",
      "type": "n8n-nodes-base.if",
      "position": [
        2500,
        1140
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "26d8ff5a-c830-4443-8acb-16fd095aead5",
              "operator": {
                "type": "string",
                "operation": "exists",
                "singleValue": true
              },
              "leftValue": "={{ $json.id }}",
              "rightValue": ""
            },
            {
              "id": "315fd79c-263b-448d-ae26-bd2b448e5212",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $('Commit Message Breakdown').item.json.taskCompleted.toString() }}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2
    },
    {
      "id": "f9064e43-40d4-4d1d-aefa-ed15879831f2",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        900
      ],
      "parameters": {
        "color": 5,
        "width": 540,
        "height": 240,
        "content": "### Step 1: The Listening Post \ud83d\udc42 (For the GitHub Trigger)\n\nThis node is our ear to the ground in GitHub.\n\nIt patiently waits for a developer to use `git push`. \n\nThe moment new code arrives, this node catches it and says, \"We've got one! Time to get to work.\" It passes the commit details, including your special message, to the next step.\n\nFor any queries, please reach out to getstarted@intuz.com"
      },
      "typeVersion": 1
    },
    {
      "id": "fe66429f-1fc9-4e06-9072-849c4c848a5e",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        540,
        1300
      ],
      "parameters": {
        "width": 580,
        "height": 280,
        "content": "### Step 2: The Decoder Ring \ud83e\udde0\n\nThis is where the magic happens! Think of this node as a translator.\n\nIt carefully reads the commit message you wrote (e.g., \"FF-1196...[auto-pr]...\") and intelligently pulls out the three key pieces of information we need:\n\n1.  **Who:** The Jira ticket number.\n\n2.  **What:** The special commands (`[auto-pr]`, `[taskcompleted]`).\n\n3.  **Where:** The target branch for the PR."
      },
      "typeVersion": 1
    },
    {
      "id": "d2b4e8e4-1b05-4ee2-b14d-8084fed4f82c",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        980,
        820
      ],
      "parameters": {
        "width": 500,
        "height": 300,
        "content": "### Step 3: To PR, or Not to PR? \ud83e\udd14\n\nThis is a checkpoint that gives you control.\n\nIt asks a simple question: \"Did the developer include the `[auto-pr]` command?\"\n\n- If **YES**, we proceed down the \"True\" path to create the Pull Request automatically. No more manual form-filling in GitHub!\n\n- If **NO**, we skip it. This lets you push multiple work-in-progress commits without flooding your team with PRs."
      },
      "typeVersion": 1
    },
    {
      "id": "b165e11c-5cfe-426f-997d-3a4df5cb0fe4",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1280,
        1600
      ],
      "parameters": {
        "width": 560,
        "height": 300,
        "content": "### Step 4: Closing the Loop in Jira \u2705\n\nThis final checkpoint keeps your project manager happy.\n\nIt asks: \"Did the developer include the `[taskcompleted]` command?\"\n\n- If **YES**, the workflow automatically finds the right Jira ticket and updates its status for you. Your task board is now perfectly in sync with your code.\n\n- If **NO**, it does nothing, because you're probably still working on it!"
      },
      "typeVersion": 1
    },
    {
      "id": "50536438-518e-431c-93a2-9d416b14d5a4",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        80,
        460
      ],
      "parameters": {
        "color": 3,
        "width": 620,
        "height": 320,
        "content": "## \ud83d\udd27 Quick Setup Required!\n\nWelcome! To make this workflow yours, you just need to do two things:\n\n1.  **Connect Your Accounts:** Click on the GitHub and Jira nodes and select your credentials.\n\n2.  **Set Your Jira Status:** In the final Jira node, tell it which status to use for completed tasks (e.g., 'Done', 'In Review').\n\n\nThat's it! You're ready to automate."
      },
      "typeVersion": 1
    },
    {
      "id": "7e0eeb44-d1c8-430c-9fab-519662e898cd",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2380,
        1520
      ],
      "parameters": {
        "color": 5,
        "width": 576,
        "height": 300,
        "content": "# Need more help ?\n\n**We develop tailored workflow to save youe valuable time. Should you have any questions or wish to explore more custom automation solutions, we would be happy to connect.**\n\n### Email: hello.b@intuz.com\n### Website: https://www.intuz.com/"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "dd6e80c1-5de1-44b3-b946-54550b64e807",
  "connections": {
    "Github Trigger": {
      "main": [
        [
          {
            "node": "Commit Message Breakdown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if PR exists": {
      "main": [
        [
          {
            "node": "Check whether a PR already exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if task exist": {
      "main": [
        [
          {
            "node": "Update task status after PR",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "JIRA Task does not exist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if task exists": {
      "main": [
        [
          {
            "node": "Update the task status without PR",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "JIRA Task does not exist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Request to create PR": {
      "main": [
        [
          {
            "node": "Check if task exist",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for PR commands": {
      "main": [
        [
          {
            "node": "Get task details for PR",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Check for task completed command",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get task details for PR": {
      "main": [
        [
          {
            "node": "Check if PR exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Commit Message Breakdown": {
      "main": [
        [
          {
            "node": "Check for PR commands",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Get Task Details without PR.": {
      "main": [
        [
          {
            "node": "Check if task exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check for task completed command": {
      "main": [
        [
          {
            "node": "Get Task Details without PR.",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Invalid commit message",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check whether a PR already exists": {
      "main": [
        [
          {
            "node": "Check if task exist",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Request to create PR",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}