-
Notifications
You must be signed in to change notification settings - Fork 158
feat: Add Bitbucket Server webhook compatibility #3962
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: main
Are you sure you want to change the base?
Conversation
c2d7c05 to
1b59a7d
Compare
59aac7a to
f3db864
Compare
| if (Array.isArray(cloneLinks)) { | ||
| const sshLink = cloneLinks.find(link => link.name === 'ssh'); | ||
| const httpLink = cloneLinks.find(link => link.name === 'http'); | ||
| if (sshLink?.href) { | ||
| giturl = sshLink.href; | ||
| } else if (httpLink?.href) { | ||
|
|
||
| const match = httpLink.href.match(/https?:\/\/([^\/]+)\/scm\/([^\.]+)\.git/i); | ||
| if (match) { | ||
| const domain = match[1]; | ||
| const projectAndRepo = match[2]; | ||
| giturl = `git@${domain}:${projectAndRepo}.git`; | ||
| } else { | ||
| throw new Error(`Could not parse project/repo from http clone link: ${httpLink.href}`); | ||
| } | ||
| } | ||
| } | ||
| // TODO: Use when single snapshot data is fixed | ||
| if (!giturl) { | ||
| let repoHref = null; | ||
|
|
||
| if (bodyObj.repository.links?.html?.href) { | ||
| repoHref = bodyObj.repository.links.html.href; | ||
| } else if (bodyObj.repository.links?.self?.[0]?.href) { | ||
| repoHref = bodyObj.repository.links.self[0].href; | ||
| } else { | ||
| throw new Error('Could not determine repository URL from webhook payload.'); | ||
| } | ||
|
|
||
| const regexmatch = repoHref.match(/https?:\/\/([a-z0-9-_.]*)(:[0-9]*)?\//i); | ||
| if (!regexmatch) { | ||
| throw new Error(`Could not parse domain from repository href: ${repoHref}`); | ||
| } | ||
|
|
||
| const domain = regexmatch[1]; | ||
|
|
||
| if (!bodyObj.repository.full_name) { | ||
| throw new Error('Missing repository.full_name in webhook payload.'); | ||
| } | ||
|
|
||
| if (!regexmatch[2]) { | ||
| giturl = `git@${domain}:${bodyObj.repository.full_name}.git`; | ||
| } else { | ||
| const port = regexmatch[2]; | ||
| giturl = `ssh://git@${domain}${port}/${bodyObj.repository.full_name}.git`; | ||
| } | ||
| } |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We have tests for bitbucket cloud based payloads (though these are probably a little bit out of date in some of the data)
- https://github.com/uselagoon/lagoon/blob/main/tests/tests/bitbucket.yaml
- https://github.com/uselagoon/lagoon/tree/main/tests/tests/bitbucket
- https://github.com/uselagoon/lagoon/tree/main/tests/tasks/webhook-bitbucket < this is where the payloads would need to be saved
Are you able to create tests the same way but call them stash. This would mean copying those bitbucket tests, renaming them to stash and then modifying the references like ci-bitbucket to be ci-stash and then updating the payloads with matching payload data from stash. You will need to modify the payload data to account for the local git that would be created for the tests to use, you can read the existing payload files for bitbucket to see how this is done.
The tests are a little bit difficult to understand, but the main thing would be to ensure that you've provided some example webhook payloads that would be used to verify that the payloads from Stash/BB Server will correctly provision environments.
You'd be able to run the tests locally too, but resetting after a failed test run is a bit cumbersome, its usually easier to just tear it all down and start over like this
make k3d/clean && make k3d/test TESTS=[stash]
Having these tests would ensure that both the bitbucket cloud tests still pass, and that the stash webhooks would work too.
| break; | ||
|
|
||
| case 'bitbucket:repo:push': | ||
| case 'bitbucket:repo:refs_changed': |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These may need to be split off from being prefixed with bitbucket to being prefixed with stash. Since the two systems are different, this would make it clear they are different. You'd need to update all the events in logs2notifications to deal with this, and then move this https://github.com/tarikflz/lagoon/blob/feat/webhook-bitbucket-server/services/webhook-handler/src/extractWebhookData.ts#L61 into this if block https://github.com/tarikflz/lagoon/blob/feat/webhook-bitbucket-server/services/webhook-handler/src/extractWebhookData.ts#L85 and add webhooktype = 'stash'; into the clone links block https://github.com/tarikflz/lagoon/blob/feat/webhook-bitbucket-server/services/webhook-handler/src/extractWebhookData.ts#L68
This way its made clear that an event would be stash/bitbucket server, instead of bitbucket cloud when the messages are flying around.
|
May be replaced with #3979 |
General Checklist
Database Migrations
Description
This PR improves Lagoon's Bitbucket webhook handler to support Bitbucket Server and Data Center instances, which do not include the
repository.links.html.hreforrepository.full_namefields in webhook payloads.Instead, Bitbucket Server provides clone URLs under
repository.links.clone, including SSH and HTTP(S) links. This update:cloneif available and uses it directly.html.href + full_name) for Bitbucket Cloud compatibility.giturlgeneration is resilient and safe across both Bitbucket variants.Reference
Official documentation for Bitbucket Server webhook payload format:
📄 https://confluence.atlassian.com/bitbucketserver064/event-payload-974388877.html#Eventpayload-repositoryevents
Tested with:
Closing issues
This implements: #3961