AutomationFlowsData & Sheets › Sync Azure Devops Work Items to Github Issues with Google Sheets Tracking

Sync Azure Devops Work Items to Github Issues with Google Sheets Tracking

ByConceptRecall @conceptrecallcom on n8n.io

This workflow is designed for software teams, project managers, and developers who manage work across Azure DevOps and GitHub. It helps organizations that use Azure DevOps for work item tracking but rely on GitHub for issue management and collaboration.

Webhook trigger★★★★☆ complexity25 nodesHTTP RequestGoogle SheetsGitHub
Data & Sheets Trigger: Webhook Nodes: 25 Complexity: ★★★★☆ Added:

This workflow corresponds to n8n.io template #8643 — we link there as the canonical source.

This workflow follows the GitHub → HTTP Request recipe pattern — see all workflows that pair these two integrations.

The workflow JSON

Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →

Download .json
{
  "id": "xU7oltBCaOQVpXTL",
  "meta": {
    "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
      ],
      "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": {
          "name": "<your credential>"
        }
      },
      "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": {
          "name": "<your credential>"
        }
      },
      "typeVersion": 4.2
    },
    {
      "id": "f5a34fc0-1af4-4ed1-aaa7-2d9647ece841",
      "name": "Webhook2",
      "type": "n8n-nodes-base.webhook",
      "position": [
        -400,
        680
      ],
      "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": {
          "name": "<your credential>"
        }
      },
      "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": {
          "name": "<your credential>"
        }
      },
      "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": {
          "name": "<your credential>"
        }
      },
      "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": {
          "name": "<your credential>"
        }
      },
      "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": {
          "name": "<your credential>"
        }
      },
      "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": "\ud83d\udccc 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\u2019s mapping in Google Sheets and updates the corresponding GitHub \n   Issue by appending a clickable bullet point link to the Task.\n\n\u2705 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": "\ud83d\udd14 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": "\ud83e\uddf9 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": "\ud83d\udcc4 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": "\ud83d\udce1 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": "\ud83c\udfb2 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": "\u270f\ufe0f 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": "\ud83d\udcca 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": "\ud83d\udd14 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": "\ud83e\uddf9 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": "\ud83d\udd0d Looks up the parent Story\u2019s 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": "\ud83d\udce5 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": "\u2795 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,
  "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
          }
        ]
      ]
    }
  }
}

Credentials you'll need

Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.

Pro

For the full experience including quality scoring and batch install features for each workflow upgrade to Pro

About this workflow

This workflow is designed for software teams, project managers, and developers who manage work across Azure DevOps and GitHub. It helps organizations that use Azure DevOps for work item tracking but rely on GitHub for issue management and collaboration.

Source: https://n8n.io/workflows/8643/ — original creator credit. Request a take-down →

More Data & Sheets workflows → · Browse all categories →

Related workflows

Workflows that share integrations, category, or trigger type with this one. All free to copy and import.

Data & Sheets

BP_check. Uses googleSheets, @n-octo-n/n8n-nodes-json-database, httpRequest, itemLists. Webhook trigger; 99 nodes.

Google Sheets, @N Octo N/N8N Nodes Json Database, HTTP Request +2
Data & Sheets

Receive request via webhook with customer question Analyze sentiment and detect urgency using JavaScript Send urgent alerts to Slack for critical cases Search knowledge base and fetch conversation his

HTTP Request, Postgres, Email Send +1
Data & Sheets

Dialpad to Syncro. Uses httpRequest, googleSheets, noOp. Webhook trigger; 22 nodes.

HTTP Request, Google Sheets
Data & Sheets

This comprehensive n8n workflow automates the entire travel business call management process, from initial customer inquiries to trip bookings and marketing outreach. The system handles incoming calls

Postgres, Google Sheets Trigger, HTTP Request +1
Data & Sheets

Clockify to Syncro. Uses googleSheets, httpRequest, noOp. Webhook trigger; 13 nodes.

Google Sheets, HTTP Request