jenkinsci / jenkinsci/gitlab-branch-source-plugin
Branch not removed from discovery when Merge Request is created via webhook (Merge Request Hook)
- Dominant language
- Java
- Stars
- 134
- Forks
- 113
- PR merge metrics
- No merged PRs in 30d
Description
When a Merge Request is created from a feature branch toward a target branch, the source feature branch is **not automatically removed** from the Jenkins multibranch pipeline job, even though the Branch Discovery strategy is set to **"Only branches that are not also filed as MRs"**.
The branch is only removed when a **manual scan** is triggered afterward.
## Environment
- **Plugin version**: 704.vc7f1202d7e14
- **Jenkins version**: 2.414.3
- **Branch Discovery strategy**: Only branches that are not also filed as MRs
- **Discover merge requests from origin**: enabled
## Steps to reproduce
1. Configure a Multibranch Pipeline with:
- Branch Discovery → "Only branches that are not also filed as MRs"
- Discover merge requests from origin → enabled
- GitLab webhooks enabled (Push events + Merge request events)
2. Push a feature branch (e.g. `feature_test_ahmed_123`) → Jenkins discovers it and creates a branch job.
3. Create a Merge Request from `feature_test_ahmed_123` → `develop` in GitLab.
4. Observe Jenkins: the branch job `feature_test_ahmed_123` **remains visible** despite the MR being open.
## Expected behavior
When a Merge Request is opened for a branch, Jenkins should automatically remove the branch job (since the strategy is "Only branches not also filed as MRs").
## Actual behavior
The branch job persists after MR creation. It is only removed when a manual scan is triggered.
## Root cause analysis
When GitLab sends a `Merge Request Hook` upon MR creation, Jenkins processes it via `MultiBranchProject$SCMEventListenerImpl.processHeadUpdate()`. This path **creates/updates the MR job** but does **not trigger a re-evaluation of existing branch jobs**. As a result, the `ExcludeOriginMRBranchesSCMHeadFilter` is never applied to the existing branch job at that point.
Evidence from the indexing log when a manual scan is triggered:
```
Checking branch feature_test_ahmed_123
'Jenkinsfile' found
Met criteria ← branch incorrectly kept before manual scan
Checking merge request !491
'Jenkinsfile' found
Met criteria
...
Will remove feature_test_ahmed_123 ← correctly removed during full scan
```
Confirmed via GitLab API that the MR is open and `source_project_id == target_project_id` (not a fork), so the filter conditions are met — the branch just never gets re-evaluated on MR creation.
Also confirmed: after the manual scan removes the branch job, pushing new commits to `feature_test_ahmed_123` does **not** recreate the branch job — the Push Hook path correctly applies the filter. The issue is isolated to the moment of MR creation.
## Suggested fix
When a `Merge Request Hook` of action `open` is received, trigger a re-evaluation (mini-scan or removal event) for the corresponding source branch, so the filter can apply immediately without waiting for a full scheduled scan.
## Workaround
Configure a periodic scan (e.g. every 5 minutes) under "Scan Multibranch Pipeline Triggers → Periodically if not otherwise run". This limits the window during which the phantom branch job is visible.
Contributor guide
Research direction
Start at MultiBranchProject$SCMEventListenerImpl.processHeadUpdate() and trace the Merge Request Hook path alongside ExcludeOriginMRBranchesSCMHeadFilter. Reproduce the open-MR webhook case, then verify that the source branch job is removed immediately without a manual scan while later push-hook behavior remains unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- java
- Domain
- ci-cd, devops
- Issue type
- Bug
- Difficulty
- 4/5
- Estimated time
- 3-5 days
- Activity status
- Quiet
- Clarity
- Clearly specified
- Newbie friendliness
- 64/100