通过 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)可能需要您自行付费。
相关工作流推荐
工作简历与求职信自动化(含简历 HTML 模板)
使用 AI、GitHub Pages 和 Google Drive 个性化简历和求职信
Set
Code
Html
+16
31 节点Michael A Putra
文档提取
AI会议纪要与任务项追踪器:Notion、Slack和Gmail集成
AI会议纪要与任务项追踪器:集成Notion、Slack和Gmail
Code
Gmail
Slack
+7
25 节点Daniel Shashko
项目管理
AI活动与预算编排套件
使用 Claude AI 和 Google Sheets 实现活动策划和预算优化自动化
Code
Merge
Slack
+6
20 节点Oneclick AI Squad
项目管理
基于蓝图和Baserow的自动化任务生成与周末感知调度
基于蓝图和Baserow的自动化任务生成与周末感知调度
Set
Code
Baserow
+5
12 节点Frederik Duchi
项目管理
从 Streamlit 应用自动创建 Jira 工单
通过 Webhook 和 REST API 从 Streamlit 表单创建 Jira 工单
If
Set
Code
+3
16 节点Yassin Zehar
项目管理
转录 -> Notion -> 任务
使用AI和Google Drive将会议转录转换为Notion笔记和任务
If
Set
Code
+12
36 节点Matty Reed
项目管理