8
n8n 中文网amn8n.com

通过 Microsoft Azure DevOps 在仓库中创建 GitHub Issue

高级

这是一个Project Management领域的自动化工作流,包含 25 个节点。主要使用 Code, Github, Webhook, HttpRequest, GoogleSheets 等节点。 将 Azure DevOps 工作项同步至 GitHub Issues,并通过 Google Sheets 跟踪

前置要求
  • GitHub Personal Access Token
  • HTTP Webhook 端点(n8n 会自动生成)
  • 可能需要目标 API 的认证凭证
  • Google Sheets API 凭证
工作流预览
可视化展示节点连接关系,支持缩放和平移
导出工作流
复制以下 JSON 配置到 n8n 导入,即可使用此工作流
{
  "id": "xU7oltBCaOQVpXTL",
  "meta": {
    "instanceId": "0dce4a8577fc7818af4d5063da85aecc2e78c224380b158fcc7b79f366de29cf",
    "templateCredsSetupCompleted": true
  },
  "name": "Create Github Issue on Repository through Microsoft Azure Devops",
  "tags": [
    {
      "id": "bzVlYzwMkoShfaSM",
      "name": "Usman - Azure",
      "createdAt": "2025-09-01T10:16:32.706Z",
      "updatedAt": "2025-09-01T10:16:32.706Z"
    }
  ],
  "nodes": [
    {
      "id": "bc44de1f-5aae-4610-9656-7b0f1abacc17",
      "name": "Webhook1",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -400,
        400
      ],
      "webhookId": "3006842c-5f13-4147-8d78-9ee73ac78e34",
      "parameters": {
        "path": "3006842c-5f13-4147-8d78-9ee73ac78e34",
        "options": {
          "responseData": "Azure Devops Event Triggered"
        },
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "57abbafb-499f-4d15-96a9-761ec01c029b",
      "name": "HTTP Request1",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        500,
        80
      ],
      "parameters": {
        "url": "={{ $json.repository_url }}/collaborators",
        "options": {
          "response": {
            "response": {
              "responseFormat": "json"
            }
          }
        },
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "githubOAuth2Api"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "wRGEOSgVBxXPUcv9",
          "name": "GitHub - Mohammad Usman"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "c8e8776c-e157-4695-ab7c-2e9092a8cde3",
      "name": "Code2",
      "type": "n8n-nodes-base.code",
      "position": [
        800,
        80
      ],
      "parameters": {
        "jsCode": "// Extract only login field\nconst logins = $input.all().map((c) => c.json.login);\n\n// Pick random one\nconst randomAssignee = logins[Math.floor(Math.random() * logins.length)];\n\nreturn {\n  json: {\n    assignee: randomAssignee\n  }\n}\n"
      },
      "typeVersion": 2
    },
    {
      "id": "95ddfe84-ad11-47a1-bdca-905dce64e7e9",
      "name": "HTTP Request2",
      "type": "n8n-nodes-base.httpRequest",
      "position": [
        1080,
        80
      ],
      "parameters": {
        "url": "={{ $('Create Github Issue').first().json.url }}",
        "method": "PATCH",
        "options": {},
        "jsonBody": "={\n  \"assignees\": [\"{{ $json.assignee }}\"]\n}\n",
        "sendBody": true,
        "specifyBody": "json",
        "authentication": "predefinedCredentialType",
        "nodeCredentialType": "githubOAuth2Api"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "wRGEOSgVBxXPUcv9",
          "name": "GitHub - Mohammad Usman"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f5a34fc0-1af4-4ed1-aaa7-2d9647ece841",
      "name": "Webhook2",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -400,
        680
      ],
      "webhookId": "cfecf4f6-b82d-4dd0-af5b-bd231130b272",
      "parameters": {
        "path": "cfecf4f6-b82d-4dd0-af5b-bd231130b272",
        "options": {},
        "httpMethod": "POST"
      },
      "typeVersion": 2
    },
    {
      "id": "c23ad66e-3e21-46af-9587-10d7c81cf44b",
      "name": "Google Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        1360,
        80
      ],
      "parameters": {
        "columns": {
          "value": {
            "Url": "={{ $json.url }}",
            "AzureID": "={{ $('Filter Story Data').first().json.id }}",
            "IssueID": "={{ $('Create Github Issue').first().json.number }}"
          },
          "schema": [
            {
              "id": "AzureID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "AzureID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "IssueID",
              "type": "string",
              "display": true,
              "required": false,
              "displayName": "IssueID",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            },
            {
              "id": "Url",
              "type": "string",
              "display": true,
              "removed": false,
              "required": false,
              "displayName": "Url",
              "defaultMatch": false,
              "canBeUsedToMatch": true
            }
          ],
          "mappingMode": "defineBelow",
          "matchingColumns": [],
          "attemptToConvertTypes": false,
          "convertFieldsToString": false
        },
        "options": {},
        "operation": "append",
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Cr7IRGiS1mB691euOBvDLC_Y56lTDWc4mhAll9-TEII/edit#gid=0",
          "cachedResultName": "IssuesMap"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Cr7IRGiS1mB691euOBvDLC_Y56lTDWc4mhAll9-TEII",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Cr7IRGiS1mB691euOBvDLC_Y56lTDWc4mhAll9-TEII/edit?usp=drivesdk",
          "cachedResultName": "Github Issues"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "zBY5kSBHNzMp7NUo",
          "name": "Google Sheets Read - Usman"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "910297bd-cf54-42af-b297-3bb397721710",
      "name": "Google Sheets1",
      "type": "n8n-nodes-base.googleSheets",
      "position": [
        280,
        1000
      ],
      "parameters": {
        "options": {},
        "filtersUI": {
          "values": [
            {
              "lookupValue": "={{ $json.parent }}",
              "lookupColumn": "AzureID"
            }
          ]
        },
        "sheetName": {
          "__rl": true,
          "mode": "list",
          "value": "gid=0",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Cr7IRGiS1mB691euOBvDLC_Y56lTDWc4mhAll9-TEII/edit#gid=0",
          "cachedResultName": "IssuesMap"
        },
        "documentId": {
          "__rl": true,
          "mode": "list",
          "value": "1Cr7IRGiS1mB691euOBvDLC_Y56lTDWc4mhAll9-TEII",
          "cachedResultUrl": "https://docs.google.com/spreadsheets/d/1Cr7IRGiS1mB691euOBvDLC_Y56lTDWc4mhAll9-TEII/edit?usp=drivesdk",
          "cachedResultName": "Github Issues"
        }
      },
      "credentials": {
        "googleSheetsOAuth2Api": {
          "id": "zBY5kSBHNzMp7NUo",
          "name": "Google Sheets Read - Usman"
        }
      },
      "typeVersion": 4.5
    },
    {
      "id": "0b938c91-25a2-4f32-8cf6-5ea6f5fbb862",
      "name": "Create Github Issue",
      "type": "n8n-nodes-base.github",
      "position": [
        180,
        80
      ],
      "parameters": {
        "body": "={{ $json.description }}",
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "usman151710"
        },
        "title": "={{ $json.title }}",
        "labels": [],
        "assignees": [],
        "repository": {
          "__rl": true,
          "mode": "list",
          "value": "github-n8n",
          "cachedResultUrl": "https://github.com/usman151710/github-n8n",
          "cachedResultName": "github-n8n"
        },
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "wRGEOSgVBxXPUcv9",
          "name": "GitHub - Mohammad Usman"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "42b27eee-cbbb-4d4c-aee1-31a2951855c6",
      "name": "Filter Story Data",
      "type": "n8n-nodes-base.code",
      "position": [
        -140,
        80
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Input: Webhook payload from Azure DevOps\n// Output: A cleaned object with only useful fields\n\nconst item = $json.body; // full webhook response\n\n// Build a simplified object\nconst workItem = {\n  id: item.resource.id,\n  url: item.resource.url,\n  title: item.resource.fields[\"System.Title\"],\n  workItemType: item.resource.fields[\"System.WorkItemType\"],\n  createdBy: item.resource.fields[\"System.CreatedBy\"].displayName,\n  createdDate: item.resource.fields[\"System.CreatedDate\"],\n  description: item.resource.fields[\"System.Description\"] || \"\",\n  state: item.resource.fields[\"System.State\"],\n  areaPath: item.resource.fields[\"System.AreaPath\"],\n  iterationPath: item.resource.fields[\"System.IterationPath\"],\n};\n\n// Return the object for next node (GitHub Issue)\nreturn { json: workItem };\n"
      },
      "typeVersion": 2
    },
    {
      "id": "ae95f447-f964-4f01-b97e-7616032da091",
      "name": "Filter Task Data",
      "type": "n8n-nodes-base.code",
      "position": [
        -120,
        1000
      ],
      "parameters": {
        "mode": "runOnceForEachItem",
        "jsCode": "// Input: Webhook payload from Azure DevOps\n// Output: A cleaned object with only useful fields\n\nconst item = $json.body; // full webhook response\n\n// Build a simplified object\nconst workItem = {\n  id: item.resource.id,\n  url: item.resource.url,\n  title: item.resource.fields[\"System.Title\"],\n  workItemType: item.resource.fields[\"System.WorkItemType\"],\n  createdBy: item.resource.fields[\"System.CreatedBy\"].displayName,\n  createdDate: item.resource.fields[\"System.CreatedDate\"],\n  description: item.resource.fields[\"System.Description\"] || \"\",\n  state: item.resource.fields[\"System.State\"],\n  parent: item.resource.fields[\"System.Parent\"],\n  ticketUrl: item.resource._links.html.href,\n};\n\n// Return the object for next node (GitHub Issue)\nreturn { json: workItem };\n"
      },
      "typeVersion": 2
    },
    {
      "id": "207fc436-0d69-4d63-a44b-4a3619244d31",
      "name": "GitHub1",
      "type": "n8n-nodes-base.github",
      "position": [
        1000,
        1000
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "usman151710"
        },
        "operation": "edit",
        "editFields": {
          "body": "={{ $json.body }}\n\n<li>\n  <a href=\"{{ $('Filter Task Data').first().json.ticketUrl }}\"\n     target=\"_blank\" rel=\"noopener noreferrer\">\n    [{{ $('Google Sheets1').first().json.AzureID }}] - {{ $('Filter Task Data').first().json.title }}\n  </a>\n</li>"
        },
        "repository": {
          "__rl": true,
          "mode": "list",
          "value": "github-n8n",
          "cachedResultUrl": "https://github.com/usman151710/github-n8n",
          "cachedResultName": "github-n8n"
        },
        "issueNumber": "={{ $('Google Sheets1').first().json.IssueID }}",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "wRGEOSgVBxXPUcv9",
          "name": "GitHub - Mohammad Usman"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "2be4943e-b315-464d-bed7-350daaaba3d4",
      "name": "GitHub2",
      "type": "n8n-nodes-base.github",
      "position": [
        660,
        1000
      ],
      "parameters": {
        "owner": {
          "__rl": true,
          "mode": "name",
          "value": "usman151710"
        },
        "operation": "get",
        "repository": {
          "__rl": true,
          "mode": "list",
          "value": "github-n8n",
          "cachedResultUrl": "https://github.com/usman151710/github-n8n",
          "cachedResultName": "github-n8n"
        },
        "issueNumber": "={{ $json.IssueID }}",
        "authentication": "oAuth2"
      },
      "credentials": {
        "githubOAuth2Api": {
          "id": "wRGEOSgVBxXPUcv9",
          "name": "GitHub - Mohammad Usman"
        }
      },
      "typeVersion": 1
    },
    {
      "id": "8e29be67-84eb-4a1f-b5fd-b73e6828026d",
      "name": "Sticky Note",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -1100,
        380
      ],
      "parameters": {
        "width": 480,
        "height": 500,
        "content": "📌 Workflow Purpose\n\nThis workflow automates the connection between Microsoft Azure DevOps, GitHub, \nand Google Sheets to streamline project tracking.\n\n1. When a new Story is created in Azure DevOps, a matching GitHub Issue is automatically generated.\n2. A random collaborator from the repository is assigned to the new issue to balance workload.\n3. The workflow logs a mapping of Azure DevOps Story ID, GitHub Issue number, \n   and GitHub Issue URL into a Google Sheet for easy cross-referencing.\n4. When a Task is created under a Story in Azure DevOps, the workflow locates the \n   parent Story’s mapping in Google Sheets and updates the corresponding GitHub \n   Issue by appending a clickable bullet point link to the Task.\n\n✅ This ensures that all Stories and related Tasks from Azure DevOps are mirrored in GitHub, \nassigned to collaborators, and fully traceable through a central Google Sheets record."
      },
      "typeVersion": 1
    },
    {
      "id": "7bbaf109-4dae-4c20-94f3-af945a14e5f3",
      "name": "Sticky Note1",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -520,
        220
      ],
      "parameters": {
        "height": 140,
        "content": "🔔 Trigger for Azure DevOps Story events.\nReceives POST requests whenever a new Story \nwork item is created/updated in Azure DevOps."
      },
      "typeVersion": 1
    },
    {
      "id": "6f109ecb-6062-4813-9ddd-b10ce7cb0a6d",
      "name": "Sticky Note2",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -220,
        -120
      ],
      "parameters": {
        "content": "🧹 Cleans and structures Story data from Azure DevOps.\nExtracts fields like: ID, Title, Description, CreatedBy, State, etc.\nPasses simplified object for GitHub Issue creation."
      },
      "typeVersion": 1
    },
    {
      "id": "6ec95daa-9ae6-4255-a906-d95a14522ae8",
      "name": "Sticky Note3",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        100,
        -80
      ],
      "parameters": {
        "height": 120,
        "content": "📄 Creates a new GitHub Issue in the repository \n(based on Story Title and Description from Azure DevOps)."
      },
      "typeVersion": 1
    },
    {
      "id": "be859faf-90bb-446d-8279-9cffb1f1302e",
      "name": "Sticky Note4",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        440,
        -60
      ],
      "parameters": {
        "width": 220,
        "height": 100,
        "content": "📡 Calls GitHub API to fetch repository collaborators.\nUsed to determine possible assignees for the new issue."
      },
      "typeVersion": 1
    },
    {
      "id": "f6c1077a-3fa3-4754-9c2b-d18b5db67850",
      "name": "Sticky Note5",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        720,
        -60
      ],
      "parameters": {
        "height": 100,
        "content": "🎲 Selects a random collaborator from the list \nof repository members and prepares the assignee value."
      },
      "typeVersion": 1
    },
    {
      "id": "6b031bcb-878d-4441-8d48-fe4411e1bdb2",
      "name": "Sticky Note6",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1000,
        -60
      ],
      "parameters": {
        "height": 100,
        "content": "✏️ Updates the GitHub Issue using PATCH request.\nAssigns the randomly selected collaborator.\n"
      },
      "typeVersion": 1
    },
    {
      "id": "245e637c-f6fb-4021-83a4-b94640d128f3",
      "name": "Sticky Note7",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        1300,
        -80
      ],
      "parameters": {
        "height": 120,
        "content": "📊 Appends mapping between Azure DevOps Story ID, \nGitHub Issue number, and Issue URL into the Google Sheet.\nActs as a central cross-reference."
      },
      "typeVersion": 1
    },
    {
      "id": "6d034b36-eec5-4d3e-94c2-23623d120abe",
      "name": "Sticky Note8",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -480,
        840
      ],
      "parameters": {
        "content": "🔔 Trigger for Azure DevOps Task events.\nReceives POST requests whenever a new Task \nis created/updated in Azure DevOps."
      },
      "typeVersion": 1
    },
    {
      "id": "f8246a02-e5e3-4c99-a98e-d0513dc4f24f",
      "name": "Sticky Note9",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        -180,
        1160
      ],
      "parameters": {
        "height": 120,
        "content": "🧹 Cleans and structures Task data from Azure DevOps.\nExtracts Task ID, Title, Description, Parent Story ID, \nand Task URL for mapping back to GitHub Issue."
      },
      "typeVersion": 1
    },
    {
      "id": "e6935cec-974e-4a21-8c91-da4b3d7a9916",
      "name": "Sticky Note10",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        200,
        1160
      ],
      "parameters": {
        "height": 120,
        "content": "🔍 Looks up the parent Story’s mapping in Google Sheets \n(using AzureID as the key) to find the corresponding \nGitHub Issue ID."
      },
      "typeVersion": 1
    },
    {
      "id": "5e5ad2f6-cf46-4224-8759-f54cf27c0d3f",
      "name": "Sticky Note11",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        580,
        1160
      ],
      "parameters": {
        "width": 220,
        "height": 100,
        "content": "📥 Retrieves details of the GitHub Issue associated \nwith the parent Story from the mapping found in Sheets."
      },
      "typeVersion": 1
    },
    {
      "id": "e4488f49-21d4-4f22-a539-a12f08832398",
      "name": "Sticky Note12",
      "type": "n8n-nodes-base.stickyNote",
      "position": [
        960,
        1160
      ],
      "parameters": {
        "content": "➕ Updates the GitHub Issue body.\nAppends a clickable Task link (with Azure DevOps Task ID and Title) \nas a bullet point under the parent GitHub Issue."
      },
      "typeVersion": 1
    }
  ],
  "active": true,
  "pinData": {},
  "settings": {
    "executionOrder": "v1"
  },
  "versionId": "9202c4ad-ba66-41d9-b1ce-3d8c3bcaa915",
  "connections": {
    "Code2": {
      "main": [
        [
          {
            "node": "HTTP Request2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "GitHub2": {
      "main": [
        [
          {
            "node": "GitHub1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook1": {
      "main": [
        [
          {
            "node": "Filter Story Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Webhook2": {
      "main": [
        [
          {
            "node": "Filter Task Data",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request1": {
      "main": [
        [
          {
            "node": "Code2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Request2": {
      "main": [
        [
          {
            "node": "Google Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Google Sheets1": {
      "main": [
        [
          {
            "node": "GitHub2",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Task Data": {
      "main": [
        [
          {
            "node": "Google Sheets1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Filter Story Data": {
      "main": [
        [
          {
            "node": "Create Github Issue",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Create Github Issue": {
      "main": [
        [
          {
            "node": "HTTP Request1",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
常见问题

如何使用这个工作流?

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

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

高级 - 项目管理

需要付费吗?

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

工作流信息
难度等级
高级
节点数量25
分类1
节点类型6
难度说明

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

外部链接
在 n8n.io 查看

分享此工作流