Automa­tisches Erstellen von GitHub-PRs und Aktualisieren von Jira basierend auf Git-Commit-Befehlen (Mehrere Repositories)

Experte

Dies ist ein Automatisierungsworkflow mit 39 Nodes. Hauptsächlich werden If, Code, Jira, Merge, Slack und andere Nodes verwendet. Erstellen einer GitHub PR und Aktualisierung von Jira automatisch gemäß Git-Commit-Befehlen (Mehrere Repos)

Voraussetzungen
  • Slack Bot Token oder Webhook URL
  • Notion API Key
  • HTTP Webhook-Endpunkt (wird von n8n automatisch generiert)
  • Möglicherweise sind Ziel-API-Anmeldedaten erforderlich

Kategorie

-
Workflow-Vorschau
Visualisierung der Node-Verbindungen, mit Zoom und Pan
Workflow exportieren
Kopieren Sie die folgende JSON-Konfiguration und importieren Sie sie in n8n
{
  "id": "XrACI58wgVlnNv1M",
  "meta": {
    "instanceId": "1a54c41d9050a8f1fa6f74ca858828ad9fb97b9fafa3e9760e576171c531a787"
  },
  "name": "Auto-Create GitHub PRs & Jira Updates from Git Commit Commands (Multi-Repo)",
  "tags": [],
  "nodes": [
    {
      "id": "2dff9822-74ef-47b9-8eda-db563f4718d9",
      "name": "Commit-Nachricht aufschlüsseln",
      "type": "n8n-nodes-base.code",
      "position": [
        -2220,
        1360
      ],
      "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": "40c7ec38-ce05-4cf0-b685-764fb1e3e8f8",
      "name": "Auf PR-Befehle prüfen",
      "type": "n8n-nodes-base.if",
      "position": [
        -1500,
        1360
      ],
      "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": "dde2e24e-2ade-4422-90e5-4d340551797f",
      "name": "Anfrage zur PR-Erstellung",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        920,
        680
      ],
      "parameters": {
        "url": "=https://api.github.com/repos/{{ $('Webhook').item.json.body.repository.owner.name }}/{{ $('Webhook').item.json.body.repository.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": "b5066bae-dfa3-45ab-9858-37bb5461de7e",
      "name": "Ungültige Commit-Nachricht",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        -860,
        2500
      ],
      "parameters": {
        "errorMessage": "Workflow stopped due to invalid commit message or no commands provided"
      },
      "typeVersion": 1
    },
    {
      "id": "ce18dcbc-9708-44a1-8b21-2230bfc6478f",
      "name": "JIRA Aufgabe existiert nicht",
      "type": "n8n-nodes-base.stopAndError",
      "position": [
        1400,
        1280
      ],
      "parameters": {
        "errorMessage": "Workflow stopped due to invalid task or no taskcompleted command"
      },
      "typeVersion": 1
    },
    {
      "id": "d2779f44-67c3-419e-8957-4963360f6071",
      "name": "Auf Aufgabenabschlussbefehl prüfen",
      "type": "n8n-nodes-base.if",
      "position": [
        -1140,
        1840
      ],
      "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": "c21c433f-1b97-485d-8936-79f9b884cd28",
      "name": "Aufgabendetails für PR abrufen",
      "type": "n8n-nodes-base.jira",
      "position": [
        -1140,
        700
      ],
      "parameters": {
        "issueKey": "={{ $('Check for PR commands').item.json.jiraKey }}",
        "operation": "get",
        "additionalFields": {}
      },
      "typeVersion": 1,
      "alwaysOutputData": false
    },
    {
      "id": "87aa1a73-12bb-4cf7-bf83-b2a552c41b71",
      "name": "Aufgabendetails ohne PR abrufen",
      "type": "n8n-nodes-base.jira",
      "position": [
        -420,
        2020
      ],
      "parameters": {
        "issueKey": "={{ $json.jiraKey }}",
        "operation": "get",
        "additionalFields": {}
      },
      "typeVersion": 1
    },
    {
      "id": "43311650-47f2-4166-b916-2f956605504a",
      "name": "Prüfen, ob Aufgabe existiert",
      "type": "n8n-nodes-base.if",
      "position": [
        1540,
        540
      ],
      "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": "07939a6f-184b-4552-9b9b-2e64a7547a40",
      "name": "Aufgabenstatus nach PR aktualisieren",
      "type": "n8n-nodes-base.jira",
      "position": [
        2120,
        880
      ],
      "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": "f3dd4a57-565a-461b-bf87-2a4f33da045f",
      "name": "Prüfen, ob PR bereits existiert",
      "type": "n8n-nodes-base.if",
      "position": [
        660,
        420
      ],
      "parameters": {
        "options": {},
        "conditions": {
          "options": {
            "version": 2,
            "leftValue": "",
            "caseSensitive": true,
            "typeValidation": "strict"
          },
          "combinator": "and",
          "conditions": [
            {
              "id": "b63c7d9a-7f1d-497b-838b-f617bcab9457",
              "operator": {
                "type": "string",
                "operation": "equals"
              },
              "leftValue": "={{ $json.prExists.toString()}}",
              "rightValue": "true"
            }
          ]
        }
      },
      "typeVersion": 2.2,
      "alwaysOutputData": false
    },
    {
      "id": "8a138396-1513-4542-bd88-9d24d99caf51",
      "name": "Aufgabenstatus ohne PR aktualisieren",
      "type": "n8n-nodes-base.jira",
      "position": [
        1220,
        2140
      ],
      "parameters": {
        "issueKey": "={{ $json.key }}",
        "operation": "update",
        "updateFields": {
          "statusId": {
            "__rl": true,
            "mode": "list",
            "value": "61",
            "cachedResultName": "Development Done"
          }
        }
      },
      "typeVersion": 1
    },
    {
      "id": "98cf28cc-9ac3-4109-bfc6-1e8c1e2a48ee",
      "name": "Prüfen, ob PR existiert",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        -400,
        420
      ],
      "parameters": {
        "url": "=https://api.github.com/repos/{{ $('Webhook').item.json.body.repository.owner.name }}/{{ $('Webhook').item.json.body.repository.name }}/pulls?head={{ $('Webhook').item.json.body.repository.owner.name }}:{{ $('Commit Message Breakdown').item.json.pushBranch }}",
        "options": {},
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "githubApi"
      },
      "typeVersion": 4.2,
      "alwaysOutputData": true
    },
    {
      "id": "7a6ead0b-7975-4695-94b8-208620dd3402",
      "name": "Prüfen, ob Aufgabe existiert",
      "type": "n8n-nodes-base.if",
      "position": [
        100,
        2140
      ],
      "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": "0295041e-7f62-42af-bdc7-9e0d8a920053",
      "name": "Code",
      "type": "n8n-nodes-base.code",
      "position": [
        140,
        300
      ],
      "parameters": {
        "jsCode": "const inputItems = $input.all();\n\nif (\n  inputItems.length === 0 || \n  !inputItems[0].json || \n  Object.keys(inputItems[0].json).length === 0\n) {\n  // PR doesn't exist, return original data + prExists = false\n  return [\n    {\n      json: {\n        ...($input.first()?.json || {}),\n        prExists: false\n      }\n    }\n  ];\n} else {\n  // PR exists, return existing PR data + prExists = true\n  return inputItems.map(item => ({\n    json: {\n      ...item.json,\n      prExists: true\n    }\n  }));\n}\n"
      },
      "typeVersion": 2
    },
    {
      "id": "c38d3be6-25bc-4373-8b9c-50644ebfb387",
      "name": "Merge",
      "type": "n8n-nodes-base.merge",
      "position": [
        260,
        720
      ],
      "parameters": {
        "mode": "chooseBranch"
      },
      "typeVersion": 3.2
    },
    {
      "id": "866cd55e-0b51-4451-b5a2-bd6420d6f686",
      "name": "Webhook",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -2940,
        1380
      ],
      "webhookId": "{YOUR_GITHUB_WEBHOOK_ID}",
      "parameters": {
        "path": "github-push",
        "options": {
          "rawBody": true
        },
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "2c37d886-5822-4c87-a2bb-e68c84a07e3f",
      "name": "Nachricht in slack mit PR senden",
      "type": "n8n-nodes-base.slack",
      "position": [
        2780,
        700
      ],
      "webhookId": "{YOUR_SLACK_WEBHOOK_ID}",
      "parameters": {
        "text": "=PR has been created for the repository '{{ $('Webhook').item.json.body.repository.name }}' and task status of the task {{ $('Get task details for PR').item.json.key }} has been changed to development done\n\n",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0994RB3VAR",
          "cachedResultName": "{YOUR_SLACK_CHANNEL_NAME}"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.3
    },
    {
      "id": "0df5af64-7250-4cfb-b050-91440a90efcf",
      "name": "Nachricht in slack ohne PR senden",
      "type": "n8n-nodes-base.slack",
      "position": [
        2020,
        1800
      ],
      "webhookId": "{YOUR_SLACK_WEBHOOK_ID}",
      "parameters": {
        "text": "=Task status of the task {{ $('Get Task Details without PR.').item.json.key }} has been changed to development done",
        "select": "channel",
        "channelId": {
          "__rl": true,
          "mode": "list",
          "value": "C0994RB3VAR",
          "cachedResultName": "{YOUR_SLACK_CHANNEL_NAME}"
        },
        "otherOptions": {},
        "authentication": "oAuth2"
      },
      "typeVersion": 2.3
    },
    {
      "id": "c4615c8a-9d1e-4ab1-acce-cbbfc3857f54",
      "name": "Block in notion mit PR anhängen",
      "type": "n8n-nodes-base.notion",
      "position": [
        2780,
        1140
      ],
      "parameters": {
        "blockId": {
          "__rl": true,
          "mode": "url",
          "value": "https://www.notion.so/{YOUR_NOTION_PAGE_ID}"
        },
        "blockUi": {
          "blockValues": [
            {
              "textContent": "=PR has been created from the repository {{ $('Webhook').item.json.body.repository.name }} and task status for the task{{ $('Get task details for PR').item.json.fields.parent.key }}  has been updated to Development Done\n"
            }
          ]
        },
        "resource": "block"
      },
      "typeVersion": 2.2
    },
    {
      "id": "2f8f6c68-2a63-4a20-8771-9b616b1e37b9",
      "name": "Block in notion ohne PR anhängen",
      "type": "n8n-nodes-base.notion",
      "position": [
        2040,
        2360
      ],
      "parameters": {
        "blockId": {
          "__rl": true,
          "mode": "url",
          "value": "https://www.notion.so/{YOUR_NOTION_PAGE_ID}"
        },
        "blockUi": {
          "blockValues": [
            {
              "textContent": "=Task status for the task {{ $('Get Task Details without PR.').item.json.key }} has been updated to Development Done"
            }
          ]
        },
        "resource": "block"
      },
      "typeVersion": 2.2
    },
    {
      "id": "0acdb107-372c-46ae-8be1-1dfca5c03f08",
      "name": "Haftnotiz1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2800,
        400
      ],
      "parameters": {
        "color": 4,
        "width": 680,
        "height": 280,
        "content": "## 🔧 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. Also, add the slack and notion credentials to ensure smooth message delivery\n\n2.  **Add Webhooks to the required repositories:** Add the production webhook link to the concerned repositories\n \n\n\nThat's it! You're ready to automate."
      },
      "typeVersion": 1
    },
    {
      "id": "00004e99-bfa8-41ba-bff6-0e9b0a882c4c",
      "name": "Haftnotiz",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3160,
        1040
      ],
      "parameters": {
        "color": 6,
        "width": 540,
        "height": 320,
        "content": "### Step 1: Webhook Activated! 🪝\n\nThis is the entry point of the workflow.\n\nIt acts as a **listener for GitHub push events**, tapping into your repositories to catch every new commit.\n\nHere’s what it does:\n\n- 📦 Listens for `push` requests on specific branches.\n- 🚦 Triggers the workflow only when new commits hit the repo.\n- 🎯 Ensures everything starts from the moment you push code.\n\nIt’s the spark that kicks off the automation engine. 🔧⚡\n"
      },
      "typeVersion": 1
    },
    {
      "id": "ee39ccc2-c7d8-4783-bc79-b7710dda0cb8",
      "name": "Haftnotiz2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2460,
        1520
      ],
      "parameters": {
        "width": 560,
        "height": 280,
        "content": "### Step 2: The Decoder Ring 🧠\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": "5abbabd7-f911-4905-a810-fb473cceb6f8",
      "name": "Haftnotiz3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1820,
        1040
      ],
      "parameters": {
        "color": 6,
        "width": 480,
        "height": 300,
        "content": "### Step 3: To PR, or Not to PR? 🤔\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": "f5b6e4b5-130f-4ebc-8e76-d968642404c1",
      "name": "Haftnotiz4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1300,
        380
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 260,
        "content": "### Step 4: Task Intel Incoming! 🕵️‍♂️\n\nThis node is your mission control for task details.\n\nIt takes the **Jira ticket number** extracted in Step 2 and dives into your project management system to fetch all the juicy details—like the task title, status, assignee, and more.\n\nIn short: it’s the bridge between your code and your backlog. 🧩\n"
      },
      "typeVersion": 1
    },
    {
      "id": "8994f439-0876-4a7f-97b6-00a7df59ecfe",
      "name": "Haftnotiz5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -540,
        100
      ],
      "parameters": {
        "color": 3,
        "width": 420,
        "height": 280,
        "content": "### Step 5: PR Radar Activated! 📡\n\nThis node is on patrol to prevent duplicates.\n\nIt scans the repository to check if a **Pull Request already exists** from the current branch. Why? Because creating multiple PRs for the same work = chaos. 🧨\n\n- If a PR already exists, we skip creating a new one.\n- If no PR is found, we move ahead to create it.\n\nSimple, smart, and keeps your GitHub tidy. 🧼\n"
      },
      "typeVersion": 1
    },
    {
      "id": "2795b793-1389-4459-814e-29fed2455ef7",
      "name": "Haftnotiz6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -60,
        -40
      ],
      "parameters": {
        "color": 6,
        "width": 580,
        "height": 300,
        "content": "### Step 6: PR Data Extractor 🧠📄\n\nThis node digs into GitHub to check if a **Pull Request already exists** for the current branch.\n\nHere’s what it does:\n\n- ✅ **If a PR exists**: It extracts and formats key details like PR title, description, status, URL, and number—ready to be used in the next steps.\n- ❌ **If no PR is found**: It returns `false`, signaling that a new PR may need to be created.\n\nThis step ensures we always work with clean, structured data—and avoid duplication. 📦🧹\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b087e06b-7ac1-4c31-9312-3fcd4828a2a6",
      "name": "Haftnotiz7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        60,
        880
      ],
      "parameters": {
        "color": 3,
        "width": 520,
        "height": 360,
        "content": "### Step 7: PR Data Merge Hub 🔗🧩\n\nThis node acts as a smart **merge point** for Pull Request data.\n\nIt brings together inputs from:\n\n- 🧠 **Extracted PR details** (if a PR already exists).\n- ✅ **PR existence check** (whether or not a PR is found).\n\nWhat’s the result?\n\n- A single, unified dataset that combines both logic and content.\n- Downstream nodes can now operate on **consistent and complete PR info**, regardless of the path taken.\n\nThink of it as your data convergence checkpoint—clean, connected, and ready to go. 🔄🧷\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f91c2b1d-80a5-4563-9c00-37f8216985bb",
      "name": "Haftnotiz8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        740,
        860
      ],
      "parameters": {
        "color": 4,
        "width": 480,
        "height": 300,
        "content": "### Step 8: Launch the PR! 🚀\n\nThis is the final move—the grand finale.\n\nIf everything checks out, this node **creates the Pull Request** automatically using the details we gathered earlier (task info, branch name, etc.).\n\nNo manual clicking. No copy-pasting. Just:\n\n- ✅ A clean PR title.\n- 📝 A brief and clean description\n\nIt’s automation magic at its finest. ✨"
      },
      "typeVersion": 1
    },
    {
      "id": "bdd25203-fe9c-434e-a4bd-967c3e3632a6",
      "name": "Haftnotiz9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1940,
        460
      ],
      "parameters": {
        "color": 5,
        "width": 620,
        "height": 320,
        "content": "### Step 7: Status Update Sent! 📬\n\nTime to close the loop with Jira.\n\nThis node takes care of updating the **task status to “Development Done”** once the PR is successfully created.\n\nWhy does this matter?\n\n- ✅ Keeps your Jira board up to date automatically.\n- 📊 Gives your team instant visibility into progress.\n- 🔄 Ensures a smooth handoff to the next stage (like QA or Code Review).\n\nNo need to switch tabs—your workflow just updated itself. 🔁\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4a379c5e-bc5d-4ce5-818b-68aca73c45ce",
      "name": "Haftnotiz10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1560,
        1160
      ],
      "parameters": {
        "color": 3,
        "width": 580,
        "height": 300,
        "content": "### Heads-Up Node: Something’s Missing! ⚠️\n\nThis node acts as a checkpoint when things don’t go as planned.\n\nIt checks two key conditions:\n\n1. ❌ The **Jira task** couldn’t be found based on the commit message.\n2. 🛑 The PR **does not include** the `[taskcompleted]` keyword.\n\nIf either is true, we **skip the task status update** to avoid pushing incomplete or incorrect changes to Jira.\n\nIt’s a safety net to keep your workflow clean and error-free. 🧯\n"
      },
      "typeVersion": 1
    },
    {
      "id": "4040caf2-2b6d-4194-afc5-e1fa376b6c7a",
      "name": "Haftnotiz11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2980,
        820
      ],
      "parameters": {
        "color": 4,
        "width": 640,
        "height": 300,
        "content": "### Step 8: Spread the Word! 📣\n\nTime to notify the crew.\n\nThese nodes send out alerts that a **Pull Request has been created** and the **Jira task status has been updated**—all in real-time.\n\nWhere does the message go?\n\n- 💬 **Slack** – Keeps your team in the loop instantly.\n- 🗂️ **Notion** – Logs the activity for async tracking and documentation.\n\nClear, consistent, and automatic communication. Your workflow just became a team player. 🤝\n"
      },
      "typeVersion": 1
    },
    {
      "id": "12c79a7b-edb9-4233-9fd4-33ff9efdf462",
      "name": "Haftnotiz12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1040,
        2680
      ],
      "parameters": {
        "color": 3,
        "width": 540,
        "height": 320,
        "content": "### Halt! Invalid Commit Detected 🚫\n\nThis node is the gatekeeper for clean automation.\n\nIt checks if the commit message is **missing the required format or commands** (like `[auto-pr]`, `[taskcompleted]`, etc.).\n\nIf the message is invalid or empty:\n\n- 🛑 The workflow is **stopped immediately**.\n- 🔒 No PR is created.\n- ⚠️ No task is updated.\n\nThis ensures only intentional, well-formed commits trigger automation—keeping your pipeline smart and safe. 🧠✅\n"
      },
      "typeVersion": 1
    },
    {
      "id": "b007ed13-aaef-4f7d-bea4-7ae2aa77a213",
      "name": "Haftnotiz13",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1200,
        1440
      ],
      "parameters": {
        "width": 480,
        "height": 340,
        "content": "### Step 4: Task Completion Check ✅❓\n\nThis node plays detective for the `[taskcompleted]` command.\n\nIt scans the commit message to see if you’ve marked the task as complete—by including the `[taskcompleted]` keyword.\n\nWhy is this important?\n\n- ✅ If present, we’ll proceed to update the Jira task status in later steps.\n- ❌ If missing, we assume the task isn’t done yet and **skip the status update**.\n\nIt’s a smart way to give **you control over when the task is marked complete**—all from the comfort of your commit message. 🧘‍♂️\n"
      },
      "typeVersion": 1
    },
    {
      "id": "38fa4c21-97e6-4cbb-bd56-01b22ab9dcaf",
      "name": "Haftnotiz14",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -80,
        1760
      ],
      "parameters": {
        "color": 6,
        "width": 500,
        "height": 320,
        "content": "### Step 5: Task Hunt Begins! 🔍\n\nThis node verifies whether the **Jira task actually exists**.\n\nUsing the ticket number extracted earlier, it queries Jira to confirm that the task is valid and accessible.\n\nHere’s what it does:\n\n- ✅ If the task exists, we move forward confidently.\n- ❌ If not, we stop here to avoid pushing changes to a non-existent or incorrect task.\n\nThink of it as a sanity check—because broken links to Jira help no one. 🧠🛑\n"
      },
      "typeVersion": 1
    },
    {
      "id": "f9dc7b51-164b-493a-88f3-123e80fb4d1d",
      "name": "Haftnotiz15",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        940,
        1800
      ],
      "parameters": {
        "color": 5,
        "width": 580,
        "height": 300,
        "content": "### Step 6: Silent Status Update 🤫✅\n\nThis node updates the **Jira task status to “Development Done”**, but skips the PR creation process.\n\nWhy would this happen?\n\n- The commit message includes `[taskcompleted]`, but **does not** include `[auto-pr]`.\n- You want to mark the task as finished **without creating a Pull Request**—for example, in cases of non-code or internal changes.\n\nIt’s a clean way to **signal task completion in Jira** while keeping your GitHub untouched. 🎯\n"
      },
      "typeVersion": 1
    },
    {
      "id": "39389ae3-505b-4c2d-8747-8d95bf22613b",
      "name": "Haftnotiz16",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        2200,
        2000
      ],
      "parameters": {
        "color": 4,
        "width": 560,
        "height": 260,
        "content": "### Step 7: Task Update Broadcast! 📢\n\nThis node handles communication after the Jira task status has been updated.\n\nIt sends out friendly alerts to keep everyone in the loop:\n\n- 💬 **Slack** – So your team knows the task has moved to “Development Done”.\n- 🗂️ **Notion** – For async tracking, visibility, and documentation.\n\nNo more “Did you finish this?” messages—your workflow answers for you. ✅🧘‍♀️\n"
      },
      "typeVersion": 1
    },
    {
      "id": "7fc5e9aa-2bfe-4bb8-b7e9-1c6c587769b3",
      "name": "Haftnotiz17",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3780,
        180
      ],
      "parameters": {
        "color": 6,
        "width": 900,
        "height": 700,
        "content": "\n\n### ✍️ Commit Message Command Guide\n\nYour `git commit` message is the remote control for this automation. Use the format below to trigger specific actions.\n\n**Base Format:**\n`TICKET-ID Your descriptive message [command1,command2,base-branch]`\n\n---\n\n| Commit Message Example | Commands Used | Automation Triggered |\n| :--- | :--- | :--- |\n\n| **`DEV-123 Fix login bug [auto-pr, taskcompleted, develop]`** | `[auto-pr]`<br>`[taskcompleted]`<br>`develop` | **🚀 Full Automation:**<br>1. Creates a Pull Request to the `develop` branch.<br>2. Updates Jira task `DEV-123` to \"Done\".<br>3. Sends notifications about both actions. |\n\n| **`DEV-456 WIP on new UI [auto-pr, main]`** | `[auto-pr]`<br>`main` | **⚙️ PR Creation Only:**<br>1. Creates a Pull Request to the `main` branch.<br>2. Jira task status is **not changed**. |\n\n| **`DEV-789 Final docs added [taskcompleted]`** | `[taskcompleted]` | **✅ Jira Update Only:**<br>1. **No Pull Request** is created.<br>2. Updates Jira task `DEV-789` to \"Done\".<br>3. Sends notifications about the task update. |\n\n| **`DEV-111 Minor typo fix`** | *None* | **🚫 No Automation:**<br>The commit is pushed, but the workflow does nothing. This is for standard commits that don't need automation. |\n\n| **`DEV-222 This will fail [auto-pr]`** | `[auto-pr]` | **⚠️ Error - Workflow Stops:**<br>The workflow's validation will catch that `[auto-pr]` was used without a target branch and will stop, preventing an error. |"
      },
      "typeVersion": 1
    }
  ],
  "active": false,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "fa5c1a3b-1869-42e8-a94f-1ac9e5d52b5b",
  "connections": {
    "0295041e-7f62-42af-bdc7-9e0d8a920053": {
      "main": [
        [
          {
            "node": "f3dd4a57-565a-461b-bf87-2a4f33da045f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c38d3be6-25bc-4373-8b9c-50644ebfb387": {
      "main": [
        [
          {
            "node": "dde2e24e-2ade-4422-90e5-4d340551797f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "866cd55e-0b51-4451-b5a2-bd6420d6f686": {
      "main": [
        [
          {
            "node": "2dff9822-74ef-47b9-8eda-db563f4718d9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "98cf28cc-9ac3-4109-bfc6-1e8c1e2a48ee": {
      "main": [
        [
          {
            "node": "0295041e-7f62-42af-bdc7-9e0d8a920053",
            "type": "main",
            "index": 0
          },
          {
            "node": "c38d3be6-25bc-4373-8b9c-50644ebfb387",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "7a6ead0b-7975-4695-94b8-208620dd3402": {
      "main": [
        [
          {
            "node": "8a138396-1513-4542-bd88-9d24d99caf51",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "ce18dcbc-9708-44a1-8b21-2230bfc6478f",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "dde2e24e-2ade-4422-90e5-4d340551797f": {
      "main": [
        [
          {
            "node": "7a6ead0b-7975-4695-94b8-208620dd3402",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "40c7ec38-ce05-4cf0-b685-764fb1e3e8f8": {
      "main": [
        [
          {
            "node": "c21c433f-1b97-485d-8936-79f9b884cd28",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "d2779f44-67c3-419e-8957-4963360f6071",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "c21c433f-1b97-485d-8936-79f9b884cd28": {
      "main": [
        [
          {
            "node": "98cf28cc-9ac3-4109-bfc6-1e8c1e2a48ee",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "2dff9822-74ef-47b9-8eda-db563f4718d9": {
      "main": [
        [
          {
            "node": "40c7ec38-ce05-4cf0-b685-764fb1e3e8f8",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "07939a6f-184b-4552-9b9b-2e64a7547a40": {
      "main": [
        [
          {
            "node": "2c37d886-5822-4c87-a2bb-e68c84a07e3f",
            "type": "main",
            "index": 0
          },
          {
            "node": "c4615c8a-9d1e-4ab1-acce-cbbfc3857f54",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "87aa1a73-12bb-4cf7-bf83-b2a552c41b71": {
      "main": [
        [
          {
            "node": "7a6ead0b-7975-4695-94b8-208620dd3402",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "d2779f44-67c3-419e-8957-4963360f6071": {
      "main": [
        [
          {
            "node": "87aa1a73-12bb-4cf7-bf83-b2a552c41b71",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "b5066bae-dfa3-45ab-9858-37bb5461de7e",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "f3dd4a57-565a-461b-bf87-2a4f33da045f": {
      "main": [
        [
          {
            "node": "7a6ead0b-7975-4695-94b8-208620dd3402",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "c38d3be6-25bc-4373-8b9c-50644ebfb387",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "8a138396-1513-4542-bd88-9d24d99caf51": {
      "main": [
        [
          {
            "node": "0df5af64-7250-4cfb-b050-91440a90efcf",
            "type": "main",
            "index": 0
          },
          {
            "node": "2f8f6c68-2a63-4a20-8771-9b616b1e37b9",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Häufig gestellte Fragen

Wie verwende ich diesen Workflow?

Kopieren Sie den obigen JSON-Code, erstellen Sie einen neuen Workflow in Ihrer n8n-Instanz und wählen Sie "Aus JSON importieren". Fügen Sie die Konfiguration ein und passen Sie die Anmeldedaten nach Bedarf an.

Für welche Szenarien ist dieser Workflow geeignet?

Experte

Ist es kostenpflichtig?

Dieser Workflow ist völlig kostenlos. Beachten Sie jedoch, dass Drittanbieterdienste (wie OpenAI API), die im Workflow verwendet werden, möglicherweise kostenpflichtig sind.

Workflow-Informationen
Schwierigkeitsgrad
Experte
Anzahl der Nodes39
Kategorie-
Node-Typen10
Schwierigkeitsbeschreibung

Für fortgeschrittene Benutzer, komplexe Workflows mit 16+ Nodes

Autor
Intuz

Intuz

@intuz

Workflow automation can help automate your routine activities and help saves $$$, as well as hours of time. As a boutique tech consulting company, Intuz help businesses with custom AI/ML, AI Workflow Automations, and software development. Automate your business workflow for: Sales Marketing Accounting Finance Operations E-Commerce Customer Support Admin & Backoffice Logistics & Supply Chain

Externe Links
Auf n8n.io ansehen

Diesen Workflow teilen

Kategorien

Kategorien: 34