Repository navigation
feat(bitbucket-server): Add gated webhook repair task - #128330
Conversation
c7a08ea to
4be3c4f
Compare
| else: | ||
| outcome = WebhookRepairOutcome.UPDATED | ||
|
|
||
| if needs_create: |
There was a problem hiding this comment.
This task only runs because a delivery reached us, so when webhook_id is missing or the stored hook 404s, some hook we don't track is already delivering (e.g. an orphan from a lost create race whose cleanup failed, or a hook an admin added by hand). Creating here adds a second one: every push is processed twice, the old hook keeps sending unsigned payloads so the missing signature result never drains, and once enforcement is on the customer sees that hook failing in Bitbucket's admin.
The same happens on retry: if create_hook times out or gets a 5xx after Bitbucket already created the hook, the next attempt creates another.
Could we list the repo's hooks (GET .../webhooks) before creating, and adopt the one whose URL matches build_webhook_data(...)["url"] (set the secret on it and store its id), creating only when nothing matches? That also makes the retry idempotent. GitLab's ensure_project_webhook has the same shape, but it runs as a batch reconcile, so a duplicate there is only possible; here the delivery trigger makes it likely.
There was a problem hiding this comment.
There's something in the plan about this… let me see
Funny:
“Why create a hook instead of discovering and adopting an existing one?”
Follow GitLab’s simpler update-or-create behavior; unknown hooks are not listed or adopted, and duplicate deliveries are an accepted trade-off.
Which the comment already points out 😓
There was a problem hiding this comment.
But there was a reason for not adopting an existing hook:
A delivery does not include its webhook ID, so listing cannot prove which hook sent it. Adoption would mean selecting a hook based on name and URL, overwriting its secret, and storing its ID even though it may have been manually created or otherwise not managed by us. Multiple matches also require a potentially destructive deduplication policy.
There was a problem hiding this comment.
I guess in the end I rather take the chance of double delivery (that will stop working and error out when we turn on the verification) and later delete those as needed than just take whatever is listed pointing at us
There was a problem hiding this comment.
OK here's the decision: I'll do neither. We only have a very small number of customers in this integration, so if the stored hook ID is absent or 404s we're gonna stop with a specific error code and not reconcile it.
I'll then ask support for help reaching out to customers to manually fix stuff.
There was a problem hiding this comment.
Cursor Bugbot has reviewed your changes and found 1 potential issue.
❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.
Reviewed by Cursor Bugbot for commit a74f0de. Configure here.
939d506 to
d8d51a0
Compare
Sentry Snapshot Testing
|
d8d51a0 to
4daa42b
Compare

Adds a cell-side Bitbucket Data Center webhook reconciliation task behind the default-off
bitbucket_server.webhook.secret-repair.enabledoption. The task validates repository identity, persists a stable local secret before remote mutation, updates the stored hook or creates a replacement only when its ID is absent or confirmed missing, classifies retryable and terminal API failures, and uses conditional config writes plus best-effort cleanup to handle concurrent repairs safely.This is 3 of 4 PRs aimed at self-healing webhook config for BB data center.
For more details please see SCM-134.
Why do I want this?
Well, this is the meaty part of the change. The task that actually takes a webhook that is missing config and reconciles it.
Note
Dear reviewer, there are files with the full plans in the ticket. I'm not saying "read them first" but maybe ask your clanker to do it. A lot of the reasoning and several questions and answers can be found there, and then you can ask the clanker.