uselagoon / lagoon

Lagoon, the developer-focused application delivery platform
https://docs.lagoon.sh/
Apache License 2.0
567 stars 148 forks source link

Feature request: Add Azure repos webhook handler #3470

Open christopher-hopper opened 1 year ago

christopher-hopper commented 1 year ago

Add support for Azure DevOps repos in the Lagoon webhook-handler similar to currently supported GitHub, GitLab, Bitbucket and Gitea handlers.

Lagoon code

webook-handler extractWebhookData https://github.com/uselagoon/lagoon/blob/1026e453f717459a1730bb8b1f58709a555d6df3/services/webhook-handler/src/extractWebhookData.ts#L20

webhooks2tasks https://github.com/uselagoon/lagoon/blob/1026e453f717459a1730bb8b1f58709a555d6df3/services/webhooks2tasks/src/webhooks/projects.ts#L125

Documentation

References for getting started with webhooks on Lagoon and Azure DevOps repos.

tobybellwood commented 1 year ago

Thanks @christopher-hopper - do you have access to a set of request headers - given that is how we try to frontload the identification of the source repo?

christopher-hopper commented 1 year ago

Thanks @christopher-hopper - do you have access to a set of request headers - given that is how we try to frontload the identification of the source repo?

I can see about capturing them for you. They show example headers in the Azure DO docs but that may not be up-to-date and isn't in a format you'd need. I think I saw some screen captures which don't really help.

tobybellwood commented 1 year ago

From what I can see in the images and other packages, there looks to be nothing in there we can sniff 😢 - but it would be good to check.

christopher-hopper commented 1 year ago

You can add your own custom headers when you set-up a Service Hooks webhook in Azure DevOps.

Azure service hooks: Screen 1 - webhook trigger

Screen Shot Azure service hook trigger 2023-06-26

Azure service hooks: Screen 2 - webhook action

See the custom headers section in red:

Screen Shot Azure service hook action 2023-06-26

Azure service hooks: Test request data

Method: POST URI: https://hooks.example.com/hooks/catch/uid/token/ HTTP Version: 1.1 Headers:

x-custom-header: ********
Content-Type: application/json; charset=utf-8

Content:

{
    "subscriptionId": "00000000-0000-0000-0000-000000000000",
    "notificationId": 5,
    "id": "2ab4e3d3-b7a6-425e-92b1-5a9982c1269e",
    "eventType": "git.pullrequest.created",
    "publisherId": "tfs",
    "message": {
        "text": "Jamal Hartnett created a new pull request",
        "html": "Jamal Hartnett created a new pull request",
        "markdown": "Jamal Hartnett created a new pull request"
    },
    "detailedMessage": {
        "text": "Jamal Hartnett created a new pull request\r\n\r\n- Merge status: Succeeded\r\n- Merge commit: eef717(https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72)\r\n",
        "html": "Jamal Hartnett created a new pull request\r\n<ul>\r\n<li>Merge status: Succeeded</li>\r\n<li>Merge commit: <a href=\"https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72\">eef717</a></li>\r\n</ul>",
        "markdown": "Jamal Hartnett created a new pull request\r\n\r\n+ Merge status: Succeeded\r\n+ Merge commit: [eef717](https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72)\r\n"
    },
    "resource": {
        "repository": {
            "id": "4bc14d40-c903-45e2-872e-0462c7748079",
            "name": "Fabrikam",
            "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079",
            "project": {
                "id": "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
                "name": "Fabrikam",
                "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
                "state": "wellFormed",
                "visibility": "unchanged",
                "lastUpdateTime": "0001-01-01T00:00:00"
            },
            "defaultBranch": "refs/heads/master",
            "remoteUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam"
        },
        "pullRequestId": 1,
        "status": "active",
        "createdBy": {
            "displayName": "Jamal Hartnett",
            "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/54d125f7-69f7-4191-904f-c5b96b6261c8",
            "id": "54d125f7-69f7-4191-904f-c5b96b6261c8",
            "uniqueName": "fabrikamfiber4@hotmail.com",
            "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8"
        },
        "creationDate": "2014-06-17T16:55:46.589889Z",
        "title": "my first pull request",
        "description": " - test2\r\n",
        "sourceRefName": "refs/heads/mytopic",
        "targetRefName": "refs/heads/master",
        "mergeStatus": "succeeded",
        "mergeId": "a10bb228-6ba6-4362-abd7-49ea21333dbd",
        "lastMergeSourceCommit": {
            "commitId": "53d54ac915144006c2c9e90d2c7d3880920db49c",
            "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/53d54ac915144006c2c9e90d2c7d3880920db49c"
        },
        "lastMergeTargetCommit": {
            "commitId": "a511f535b1ea495ee0c903badb68fbc83772c882",
            "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/a511f535b1ea495ee0c903badb68fbc83772c882"
        },
        "lastMergeCommit": {
            "commitId": "eef717f69257a6333f221566c1c987dc94cc0d72",
            "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72"
        },
        "reviewers": [
            {
                "reviewerUrl": null,
                "vote": 0,
                "displayName": "[Mobile]\\Mobile Team",
                "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/2ea2d095-48f9-4cd6-9966-62f6f574096c",
                "id": "2ea2d095-48f9-4cd6-9966-62f6f574096c",
                "uniqueName": "vstfs:///Classification/TeamProject/f0811a3b-8c8a-4e43-a3bf-9a049b4835bd\\Mobile Team",
                "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=2ea2d095-48f9-4cd6-9966-62f6f574096c",
                "isContainer": true
            }
        ],
        "commits": [
            {
                "commitId": "53d54ac915144006c2c9e90d2c7d3880920db49c",
                "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/53d54ac915144006c2c9e90d2c7d3880920db49c"
            }
        ],
        "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1",
        "_links": {
            "web": {
                "href": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1#view=discussion"
            },
            "statuses": {
                "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/statuses"
            }
        }
    },
    "resourceVersion": "1.0",
    "resourceContainers": {
        "collection": {
            "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2"
        },
        "account": {
            "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e"
        },
        "project": {
            "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f"
        }
    },
    "createdDate": "2023-06-26T04:58:45.7020705Z"
}
christopher-hopper commented 1 year ago

Here's some more test data for the triggers:

Trigger: Pull request updated

Method: POST URI: https://hooks.example.com/hooks/catch/uid/token/ HTTP Version: 1.1 Headers:

x-custom-header: ********
Content-Type: application/json; charset=utf-8

Content:

{
    "subscriptionId": "00000000-0000-0000-0000-000000000000",
    "notificationId": 6,
    "id": "af07be1b-f3ad-44c8-a7f1-c4835f2df06b",
    "eventType": "git.pullrequest.updated",
    "publisherId": "tfs",
    "message": {
        "text": "Jamal Hartnett marked the pull request as completed",
        "html": "Jamal Hartnett marked the pull request as completed",
        "markdown": "Jamal Hartnett marked the pull request as completed"
    },
    "detailedMessage": {
        "text": "Jamal Hartnett marked the pull request as completed\r\n\r\n- Merge status: Succeeded\r\n- Merge commit: eef717(https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72)\r\n",
        "html": "Jamal Hartnett marked the pull request as completed\r\n<ul>\r\n<li>Merge status: Succeeded</li>\r\n<li>Merge commit: <a href=\"https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72\">eef717</a></li>\r\n</ul>",
        "markdown": "Jamal Hartnett marked the pull request as completed\r\n\r\n+ Merge status: Succeeded\r\n+ Merge commit: [eef717](https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72)\r\n"
    },
    "resource": {
        "repository": {
            "id": "4bc14d40-c903-45e2-872e-0462c7748079",
            "name": "Fabrikam",
            "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079",
            "project": {
                "id": "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
                "name": "Fabrikam",
                "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
                "state": "wellFormed",
                "visibility": "unchanged",
                "lastUpdateTime": "0001-01-01T00:00:00"
            },
            "defaultBranch": "refs/heads/master",
            "remoteUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam"
        },
        "pullRequestId": 1,
        "status": "completed",
        "createdBy": {
            "displayName": "Jamal Hartnett",
            "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/54d125f7-69f7-4191-904f-c5b96b6261c8",
            "id": "54d125f7-69f7-4191-904f-c5b96b6261c8",
            "uniqueName": "fabrikamfiber4@hotmail.com",
            "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=54d125f7-69f7-4191-904f-c5b96b6261c8"
        },
        "creationDate": "2014-06-17T16:55:46.589889Z",
        "closedDate": "2014-06-30T18:59:12.3660573Z",
        "title": "my first pull request",
        "description": " - test2\r\n",
        "sourceRefName": "refs/heads/mytopic",
        "targetRefName": "refs/heads/master",
        "mergeStatus": "succeeded",
        "mergeId": "a10bb228-6ba6-4362-abd7-49ea21333dbd",
        "lastMergeSourceCommit": {
            "commitId": "53d54ac915144006c2c9e90d2c7d3880920db49c",
            "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/53d54ac915144006c2c9e90d2c7d3880920db49c"
        },
        "lastMergeTargetCommit": {
            "commitId": "a511f535b1ea495ee0c903badb68fbc83772c882",
            "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/a511f535b1ea495ee0c903badb68fbc83772c882"
        },
        "lastMergeCommit": {
            "commitId": "eef717f69257a6333f221566c1c987dc94cc0d72",
            "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/eef717f69257a6333f221566c1c987dc94cc0d72"
        },
        "reviewers": [
            {
                "reviewerUrl": null,
                "vote": 0,
                "displayName": "[Mobile]\\Mobile Team",
                "url": "https://fabrikam.vssps.visualstudio.com/_apis/Identities/2ea2d095-48f9-4cd6-9966-62f6f574096c",
                "id": "2ea2d095-48f9-4cd6-9966-62f6f574096c",
                "uniqueName": "vstfs:///Classification/TeamProject/f0811a3b-8c8a-4e43-a3bf-9a049b4835bd\\Mobile Team",
                "imageUrl": "https://fabrikam.visualstudio.com/DefaultCollection/_api/_common/identityImage?id=2ea2d095-48f9-4cd6-9966-62f6f574096c",
                "isContainer": true
            }
        ],
        "commits": [
            {
                "commitId": "53d54ac915144006c2c9e90d2c7d3880920db49c",
                "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/commits/53d54ac915144006c2c9e90d2c7d3880920db49c"
            }
        ],
        "url": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1",
        "_links": {
            "web": {
                "href": "https://fabrikam.visualstudio.com/DefaultCollection/_git/Fabrikam/pullrequest/1#view=discussion"
            },
            "statuses": {
                "href": "https://fabrikam.visualstudio.com/DefaultCollection/_apis/git/repositories/4bc14d40-c903-45e2-872e-0462c7748079/pullRequests/1/statuses"
            }
        }
    },
    "resourceVersion": "1.0",
    "resourceContainers": {
        "collection": {
            "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2"
        },
        "account": {
            "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e"
        },
        "project": {
            "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f"
        }
    },
    "createdDate": "2023-06-26T05:08:33.4839435Z"
}

Trigger: Code pushed

Method: POST URI: https://hooks.example.com/hooks/catch/uid/token/ HTTP Version: 1.1 Headers:

x-custom-header: ********
Content-Type: application/json; charset=utf-8

Content:

{
    "subscriptionId": "00000000-0000-0000-0000-000000000000",
    "notificationId": 7,
    "id": "03c164c2-8912-4d5e-8009-3707d5f83734",
    "eventType": "git.push",
    "publisherId": "tfs",
    "message": {
        "text": "Jamal Hartnett pushed updates to Fabrikam-Fiber-Git:master.",
        "html": "Jamal Hartnett pushed updates to Fabrikam-Fiber-Git:master.",
        "markdown": "Jamal Hartnett pushed updates to `Fabrikam-Fiber-Git`:`master`."
    },
    "detailedMessage": {
        "text": "Jamal Hartnett pushed a commit to Fabrikam-Fiber-Git:master.\n - Fixed bug in web.config file 33b55f7c",
        "html": "Jamal Hartnett pushed a commit to <a href=\"https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/\">Fabrikam-Fiber-Git</a>:<a href=\"https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/#version=GBmaster\">master</a>.\n<ul>\n<li>Fixed bug in web.config file <a href=\"https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/commit/33b55f7cb7e7e245323987634f960cf4a6e6bc74\">33b55f7c</a>\n</ul>",
        "markdown": "Jamal Hartnett pushed a commit to [Fabrikam-Fiber-Git](https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/):[master](https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/#version=GBmaster).\n* Fixed bug in web.config file [33b55f7c](https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/commit/33b55f7cb7e7e245323987634f960cf4a6e6bc74)"
    },
    "resource": {
        "commits": [
            {
                "commitId": "33b55f7cb7e7e245323987634f960cf4a6e6bc74",
                "author": {
                    "name": "Jamal Hartnett",
                    "email": "fabrikamfiber4@hotmail.com",
                    "date": "2015-02-25T19:01:00Z"
                },
                "committer": {
                    "name": "Jamal Hartnett",
                    "email": "fabrikamfiber4@hotmail.com",
                    "date": "2015-02-25T19:01:00Z"
                },
                "comment": "Fixed bug in web.config file",
                "url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git/commit/33b55f7cb7e7e245323987634f960cf4a6e6bc74"
            }
        ],
        "refUpdates": [
            {
                "name": "refs/heads/master",
                "oldObjectId": "aad331d8d3b131fa9ae03cf5e53965b51942618a",
                "newObjectId": "33b55f7cb7e7e245323987634f960cf4a6e6bc74"
            }
        ],
        "repository": {
            "id": "278d5cd2-584d-4b63-824a-2ba458937249",
            "name": "Fabrikam-Fiber-Git",
            "url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249",
            "project": {
                "id": "6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
                "name": "Fabrikam-Fiber-Git",
                "url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/projects/6ce954b1-ce1f-45d1-b94d-e6bf2464ba2c",
                "state": "wellFormed",
                "visibility": "unchanged",
                "lastUpdateTime": "0001-01-01T00:00:00"
            },
            "defaultBranch": "refs/heads/master",
            "remoteUrl": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_git/Fabrikam-Fiber-Git"
        },
        "pushedBy": {
            "displayName": "Jamal Hartnett",
            "id": "00067FFED5C7AF52@Live.com",
            "uniqueName": "fabrikamfiber4@hotmail.com"
        },
        "pushId": 14,
        "date": "2014-05-02T19:17:13.3309587Z",
        "url": "https://fabrikam-fiber-inc.visualstudio.com/DefaultCollection/_apis/git/repositories/278d5cd2-584d-4b63-824a-2ba458937249/pushes/14"
    },
    "resourceVersion": "1.0",
    "resourceContainers": {
        "collection": {
            "id": "c12d0eb8-e382-443b-9f9c-c52cba5014c2"
        },
        "account": {
            "id": "f844ec47-a9db-4511-8281-8b63f4eaf94e"
        },
        "project": {
            "id": "be9b3917-87e6-42a4-a549-2bc06a7a878f"
        }
    },
    "createdDate": "2023-06-26T05:12:10.7769443Z"
}
shreddedbacon commented 1 year ago

That is handy, we could document that users of azure devops would need to define a specific lagoon header like

X-Lagoon-Azure-Devops: true
tobybellwood commented 1 year ago

From those, it doesn't look like the SSH version of the URL is referenced anywhere in the payloads - and as that is what Lagoon uses as the canonical reference for the project (https://github.com/uselagoon/lagoon/blob/main/services/webhooks2tasks/src/webhooks/projects.ts#L42), this is not going to be an easy addition.