Skip to content

Commit 9c7781b

Browse files
committed
Add gitlab Merge Request compatibility.
1 parent c16fcd9 commit 9c7781b

5 files changed

Lines changed: 174 additions & 6 deletions

File tree

docs.txt

Lines changed: 154 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,154 @@
1+
# GitLab Merge Request Support for PT_PULL_REQUEST
2+
3+
## Overview
4+
The git-parameter-plugin now supports GitLab Merge Requests in addition to GitHub Pull Requests
5+
and Bitbucket Pull Requests.
6+
7+
## Changes Made
8+
The following files were modified to add GitLab support:
9+
10+
1. **Consts.java:16** - Updated regex pattern
11+
- Old: `refs/pull.*/(\\d+)/[from|head]`
12+
- New: `refs/(pull.*|merge-requests)/(\\d+)/(from|head)`
13+
14+
2. **GitParameterDefinition.java:460** - Updated capture group
15+
- Changed from: `matcher.group(1)`
16+
- Changed to: `matcher.group(2)`
17+
18+
3. **BasicTests.java & BasicSafeTests.java** - Added test cases for GitLab
19+
20+
## Supported Platforms
21+
The plugin now detects pull/merge requests from:
22+
- ✅ GitHub Pull Requests: `refs/pull/45/head`
23+
- ✅ Bitbucket Pull Requests: `refs/pull-requests/186/from`
24+
- ✅ GitLab Merge Requests: `refs/merge-requests/42/head`
25+
26+
## How to Use with GitLab
27+
28+
### Basic Pipeline Example
29+
```groovy
30+
pipeline {
31+
agent any
32+
parameters {
33+
gitParameter type: 'PT_PULL_REQUEST',
34+
name: 'MERGE_REQUEST',
35+
defaultValue: '',
36+
description: 'Choose a merge request to checkout',
37+
selectedValue: 'TOP',
38+
sortMode: 'DESCENDING_SMART'
39+
}
40+
stages {
41+
stage('Checkout') {
42+
steps {
43+
checkout scmGit(
44+
branches: [[name: "refs/remotes/origin/merge-requests/${params.MERGE_REQUEST}/head"]],
45+
userRemoteConfigs: [[
46+
refspec: '+refs/merge-requests/*:refs/remotes/origin/merge-requests/*',
47+
url: 'https://gitlab.com/your-group/your-project.git'
48+
]]
49+
)
50+
}
51+
}
52+
}
53+
}
54+
```
55+
56+
### Key Differences Between GitHub and GitLab
57+
58+
**GitHub Pull Requests:**
59+
```groovy
60+
checkout scmGit(
61+
branches: [[name: "pr/${params.A_PULL_REQUEST}/head"]],
62+
userRemoteConfigs: [[
63+
refspec: '+refs/pull/*:refs/remotes/origin/pr/*',
64+
url: 'https://github.com/jenkinsci/git-plugin.git'
65+
]]
66+
)
67+
```
68+
69+
**GitLab Merge Requests:**
70+
```groovy
71+
checkout scmGit(
72+
branches: [[name: "refs/remotes/origin/merge-requests/${params.MERGE_REQUEST}/head"]],
73+
userRemoteConfigs: [[
74+
refspec: '+refs/merge-requests/*:refs/remotes/origin/merge-requests/*',
75+
url: 'https://gitlab.com/your-group/your-project.git'
76+
]]
77+
)
78+
```
79+
80+
Differences:
81+
- **Branch name**: `merge-requests/{ID}/head` instead of `pr/{ID}/head`
82+
- **Refspec**: `+refs/merge-requests/*` instead of `+refs/pull/*`
83+
- **Full ref path**: Use `refs/remotes/origin/merge-requests/${params.MERGE_REQUEST}/head`
84+
85+
## Custom Local Branch Names
86+
87+
If you want to checkout with a custom local branch name:
88+
89+
**Option 1: Checkout and create local branch**
90+
```groovy
91+
steps {
92+
checkout scmGit(
93+
branches: [[name: "refs/remotes/origin/merge-requests/${params.MERGE_REQUEST}/head"]],
94+
userRemoteConfigs: [[
95+
refspec: '+refs/merge-requests/*:refs/remotes/origin/merge-requests/*',
96+
url: 'https://gitlab.com/your-group/your-project.git'
97+
]]
98+
)
99+
sh "git checkout -b MR-${params.MERGE_REQUEST}"
100+
}
101+
```
102+
103+
**Option 2: Use localBranch extension (RECOMMENDED)**
104+
```groovy
105+
checkout scmGit(
106+
branches: [[name: "refs/remotes/origin/merge-requests/${params.MERGE_REQUEST}/head"]],
107+
extensions: [localBranch("MR-${params.MERGE_REQUEST}")],
108+
userRemoteConfigs: [[
109+
refspec: '+refs/merge-requests/*:refs/remotes/origin/merge-requests/*',
110+
url: 'https://gitlab.com/your-group/your-project.git'
111+
]]
112+
)
113+
```
114+
115+
**Option 3: Manual git commands**
116+
```groovy
117+
steps {
118+
sh """
119+
git fetch origin +refs/merge-requests/${params.MERGE_REQUEST}/head:refs/remotes/origin/merge-requests/${params.MERGE_REQUEST}/head
120+
git checkout -b MR-${params.MERGE_REQUEST} refs/remotes/origin/merge-requests/${params.MERGE_REQUEST}/head
121+
"""
122+
}
123+
```
124+
125+
## How It Works
126+
127+
1. **Refspec** (`+refs/merge-requests/*:refs/remotes/origin/merge-requests/*`)
128+
- Tells Git to fetch ALL merge request refs from the remote repository
129+
- Maps them to local remote-tracking branches
130+
131+
2. **Branches** (`branches: [[name: "refs/remotes/origin/merge-requests/${params.MERGE_REQUEST}/head"]]`)
132+
- Tells Git which specific ref to checkout after fetching
133+
- Must reference a ref that was fetched by the refspec
134+
- The MR number in the path determines which merge request is checked out
135+
136+
3. **localBranch extension** (optional)
137+
- Creates a local branch with a custom name
138+
- Without this, you're in detached HEAD state
139+
140+
## Testing
141+
142+
Run tests to verify the changes:
143+
144+
```bash
145+
# Using Docker
146+
docker run --rm -v "$(pwd):/workspace" -w /workspace maven:3.9-eclipse-temurin-17 mvn test
147+
148+
# Or run specific tests
149+
docker run --rm -v "$(pwd):/workspace" -w /workspace maven:3.9-eclipse-temurin-17 mvn test -Dtest=BasicTests,BasicSafeTests
150+
151+
# Using local Maven
152+
mvn test
153+
mvn test -Dtest=BasicTests,BasicSafeTests
154+
```

src/main/java/net/uaznia/lukanus/hudson/plugins/gitparameter/Consts.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@ public class Consts {
1313
public static final String PARAMETER_TYPE_TAG_BRANCH = "PT_BRANCH_TAG";
1414
public static final String PARAMETER_TYPE_PULL_REQUEST = "PT_PULL_REQUEST";
1515

16-
public static final Pattern PULL_REQUEST_REFS_PATTERN = Pattern.compile("refs/pull.*/(\\d+)/[from|head]");
16+
public static final Pattern PULL_REQUEST_REFS_PATTERN = Pattern.compile("refs/(pull.*|merge-requests)/(\\d+)/(from|head)");
1717

1818
public static final String TEMPORARY_DIRECTORY_PREFIX = "git_parameter_";
1919
public static final String EMPTY_JOB_NAME = "EMPTY_JOB_NAME";

src/main/java/net/uaznia/lukanus/hudson/plugins/gitparameter/GitParameterDefinition.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -457,7 +457,7 @@ private Set<String> getPullRequest(GitClient gitClient, String gitUrl) throws Ex
457457
for (String remoteReference : remoteReferences.keySet()) {
458458
Matcher matcher = PULL_REQUEST_REFS_PATTERN.matcher(remoteReference);
459459
if (matcher.find()) {
460-
pullRequestSet.add(matcher.group(1));
460+
pullRequestSet.add(matcher.group(2));
461461
}
462462
}
463463
return pullRequestSet;

src/test/java/net/uaznia/lukanus/hudson/plugins/gitparameter/BasicSafeTests.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -51,14 +51,21 @@ void testCreateValue_StaplerRequest2() {
5151
void matchesWithBitbucketPullRequestRefs() {
5252
Matcher matcher = Consts.PULL_REQUEST_REFS_PATTERN.matcher("refs/pull-requests/186/from");
5353
assertTrue(matcher.find());
54-
assertEquals("186", matcher.group(1));
54+
assertEquals("186", matcher.group(2));
5555
}
5656

5757
@Test
5858
void matchesWithGithubPullRequestRefs() {
5959
Matcher matcher = Consts.PULL_REQUEST_REFS_PATTERN.matcher("refs/pull/45/head");
6060
assertTrue(matcher.find());
61-
assertEquals("45", matcher.group(1));
61+
assertEquals("45", matcher.group(2));
62+
}
63+
64+
@Test
65+
void matchesWithGitLabMergeRequestRefs() {
66+
Matcher matcher = Consts.PULL_REQUEST_REFS_PATTERN.matcher("refs/merge-requests/42/head");
67+
assertTrue(matcher.find());
68+
assertEquals("42", matcher.group(2));
6269
}
6370

6471
@Test

src/test/java/net/uaznia/lukanus/hudson/plugins/gitparameter/BasicTests.java

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,14 +61,21 @@ void testCreateValue_StaplerRequest2() {
6161
void matchesWithBitbucketPullRequestRefs() {
6262
Matcher matcher = Consts.PULL_REQUEST_REFS_PATTERN.matcher("refs/pull-requests/186/from");
6363
assertTrue(matcher.find());
64-
assertEquals("186", matcher.group(1));
64+
assertEquals("186", matcher.group(2));
6565
}
6666

6767
@Test
6868
void matchesWithGithubPullRequestRefs() {
6969
Matcher matcher = Consts.PULL_REQUEST_REFS_PATTERN.matcher("refs/pull/45/head");
7070
assertTrue(matcher.find());
71-
assertEquals("45", matcher.group(1));
71+
assertEquals("45", matcher.group(2));
72+
}
73+
74+
@Test
75+
void matchesWithGitLabMergeRequestRefs() {
76+
Matcher matcher = Consts.PULL_REQUEST_REFS_PATTERN.matcher("refs/merge-requests/42/head");
77+
assertTrue(matcher.find());
78+
assertEquals("42", matcher.group(2));
7279
}
7380

7481
@Test

0 commit comments

Comments
 (0)