8
n8n 中文网amn8n.com

根据 Git 提交命令自动创建 GitHub PR 和更新 Jira(多仓库)

高级

这是一个自动化工作流,包含 39 个节点。主要使用 If, Code, Jira, Merge, Slack 等节点。 根据 Git 提交命令自动创建 GitHub PR 并更新 Jira(多仓库)

前置要求
  • Slack Bot Token 或 Webhook URL
  • Notion API Key
  • HTTP Webhook 端点(n8n 会自动生成)
  • 可能需要目标 API 的认证凭证

分类

-
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "XrACI58wgVlnNv1M",
  "meta": {
    "instanceId": "1a54c41d9050a8f1fa6f74ca858828ad9fb97b9fafa3e9760e576171c531a787"
  },
  "name": "根据 Git 提交命令自动创建 GitHub PR 和更新 Jira(多仓库)",
  "tags": [],
  "nodes": [
    {
      "id": "2dff9822-74ef-47b9-8eda-db563f4718d9",
      "name": "提交消息分解",
      "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": "检查 PR 命令",
      "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": "请求创建 PR",
      "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": "无效的提交消息",
      "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 任务不存在",
      "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": "检查任务完成命令",
      "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": "获取 PR 的任务详情",
      "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": "获取无 PR 的任务详情。",
      "type": "n8n-nodes-base.jira",
      "position": [
        -420,
        2020
      ],
      "parameters": {
        "issueKey": "={{ $json.jiraKey }}",
        "operation": "get",
        "additionalFields": {}
      },
      "typeVersion": 1
    },
    {
      "id": "43311650-47f2-4166-b916-2f956605504a",
      "name": "检查任务是否存在",
      "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": "PR 后更新任务状态",
      "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 是否已存在",
      "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": "无 PR 更新任务状态",
      "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 是否存在",
      "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": "检查任务是否存在",
      "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": "代码",
      "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": "合并",
      "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": "在 Slack 中发送带 PR 的消息",
      "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": "在 Slack 中发送无 PR 的消息",
      "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": "在 Notion 中附加带 PR 的块",
      "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": "在 Notion 中附加无 PR 的块",
      "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": "便签1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2800,
        400
      ],
      "parameters": {
        "color": 4,
        "width": 680,
        "height": 280,
        "content": "## 🔧 需要快速设置!"
      },
      "typeVersion": 1
    },
    {
      "id": "00004e99-bfa8-41ba-bff6-0e9b0a882c4c",
      "name": "便签",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -3160,
        1040
      ],
      "parameters": {
        "color": 6,
        "width": 540,
        "height": 320,
        "content": "### 步骤 1:Webhook 已激活!🪝"
      },
      "typeVersion": 1
    },
    {
      "id": "ee39ccc2-c7d8-4783-bc79-b7710dda0cb8",
      "name": "便签2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -2460,
        1520
      ],
      "parameters": {
        "width": 560,
        "height": 280,
        "content": "### 步骤 2:解码环 🧠"
      },
      "typeVersion": 1
    },
    {
      "id": "5abbabd7-f911-4905-a810-fb473cceb6f8",
      "name": "便签3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1820,
        1040
      ],
      "parameters": {
        "color": 6,
        "width": 480,
        "height": 300,
        "content": "### 步骤 3:创建 PR,还是不创建?🤔"
      },
      "typeVersion": 1
    },
    {
      "id": "f5b6e4b5-130f-4ebc-8e76-d968642404c1",
      "name": "便签4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1300,
        380
      ],
      "parameters": {
        "color": 4,
        "width": 400,
        "height": 260,
        "content": "### 步骤 4:任务情报传入!🕵️‍♂️"
      },
      "typeVersion": 1
    },
    {
      "id": "8994f439-0876-4a7f-97b6-00a7df59ecfe",
      "name": "便签5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -540,
        100
      ],
      "parameters": {
        "color": 3,
        "width": 420,
        "height": 280,
        "content": "### 步骤 5:PR 雷达已激活!📡"
      },
      "typeVersion": 1
    },
    {
      "id": "2795b793-1389-4459-814e-29fed2455ef7",
      "name": "便签6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -60,
        -40
      ],
      "parameters": {
        "color": 6,
        "width": 580,
        "height": 300,
        "content": "### 步骤 6:PR 数据提取器 🧠📄"
      },
      "typeVersion": 1
    },
    {
      "id": "b087e06b-7ac1-4c31-9312-3fcd4828a2a6",
      "name": "便签7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        60,
        880
      ],
      "parameters": {
        "color": 3,
        "width": 520,
        "height": 360,
        "content": "### 步骤 7:PR 数据合并中心 🔗🧩"
      },
      "typeVersion": 1
    },
    {
      "id": "f91c2b1d-80a5-4563-9c00-37f8216985bb",
      "name": "便签8",
      "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": "便签9",
      "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": "便签 10",
      "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": "便签 11",
      "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": "便签12",
      "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": "便签13",
      "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": "便签14",
      "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": "便签15",
      "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": "便签16",
      "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": "便签17",
      "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": {
    "Code": {
      "main": [
        [
          {
            "node": "Check whether a PR already exists",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Merge": {
      "main": [
        [
          {
            "node": "Request to create PR",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook": {
      "main": [
        [
          {
            "node": "Commit Message Breakdown",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Check if PR exists": {
      "main": [
        [
          {
            "node": "Code",
            "type": "main",
            "index": 0
          },
          {
            "node": "Merge",
            "type": "main",
            "index": 1
          }
        ]
      ]
    },
    "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
          }
        ]
      ]
    },
    "Update task status after PR": {
      "main": [
        [
          {
            "node": "Send message in slack with PR",
            "type": "main",
            "index": 0
          },
          {
            "node": "Append a block in notion with PR",
            "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": "Merge",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Update the task status without PR": {
      "main": [
        [
          {
            "node": "Send message in slack without PR",
            "type": "main",
            "index": 0
          },
          {
            "node": "Append a block in notion without PR",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

复制上方的 JSON 配置代码,在您的 n8n 实例中创建新工作流并选择「从 JSON 导入」,粘贴配置后根据需要修改凭证设置即可。

这个工作流适合什么场景?

高级

需要付费吗?

本工作流完全免费,您可以直接导入使用。但请注意,工作流中使用的第三方服务(如 OpenAI API)可能需要您自行付费。

工作流信息
难度等级
高级
节点数量39
分类-
节点类型10
难度说明

适合高级用户,包含 16+ 个节点的复杂工作流

作者
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

外部链接
在 n8n.io 查看

分享此工作流