Skip to content

Commit 7f97d29

Browse files
authored
[JENKINS-71355] Fix retrieval of Bitbucket Server tags head with special characters (#714)
* [JENKINS-71386] Fix retrieval of Bitbucket Server tags head with special characters * [JENKINS-71386] Add tests for tags retrieval * [JENKINS-71386] remove un-necessary forward slash
1 parent 8b06426 commit 7f97d29

14 files changed

+694
-16
lines changed

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/server/client/BitbucketServerAPIClient.java

Lines changed: 6 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -138,9 +138,9 @@ public class BitbucketServerAPIClient implements BitbucketApi {
138138
private static final String API_REPOSITORY_PATH = API_BASE_PATH + "/projects/{owner}/repos/{repo}";
139139
private static final String API_DEFAULT_BRANCH_PATH = API_REPOSITORY_PATH + "/branches/default";
140140
private static final String API_BRANCHES_PATH = API_REPOSITORY_PATH + "/branches{?start,limit}";
141-
private static final String API_BRANCHES_FILTERED_PATH = API_REPOSITORY_PATH + "/branches/{?filterText}";
141+
private static final String API_BRANCHES_FILTERED_PATH = API_REPOSITORY_PATH + "/branches{?filterText}";
142142
private static final String API_TAGS_PATH = API_REPOSITORY_PATH + "/tags{?start,limit}";
143-
private static final String API_TAG_PATH = API_REPOSITORY_PATH + "/tags/{tagName}";
143+
private static final String API_TAGS_FILTERED_PATH = API_REPOSITORY_PATH + "/tags{?filterText}";
144144
private static final String API_PULL_REQUESTS_PATH = API_REPOSITORY_PATH + "/pull-requests{?start,limit,at,direction,state}";
145145
private static final String API_PULL_REQUEST_PATH = API_REPOSITORY_PATH + "/pull-requests/{id}";
146146
private static final String API_PULL_REQUEST_MERGE_PATH = API_REPOSITORY_PATH + "/pull-requests/{id}/merge";
@@ -617,12 +617,13 @@ private List<BitbucketServerBranch> getServerBranches(String apiPath) throws IOE
617617

618618
private BitbucketServerBranch getSingleTag(String tagName) throws IOException, InterruptedException {
619619
UriTemplate template = UriTemplate
620-
.fromTemplate(API_TAG_PATH)
620+
.fromTemplate(API_TAGS_FILTERED_PATH)
621621
.set("owner", getUserCentricOwner())
622622
.set("repo", repositoryName)
623-
.set("tagName", tagName);
623+
.set("filterText", tagName);
624624

625-
BitbucketServerBranch tag = getResource(template, BitbucketServerBranch.class);
625+
BitbucketServerBranch tag = getResource(template, BitbucketServerBranches.class,
626+
branch -> tagName.equals(branch.getName()));
626627
if(tag != null) {
627628
tag.setCommitClosure(new CommitClosure(tag.getRawNode()));
628629
}
@@ -897,16 +898,6 @@ private <V> List<V> getResources(UriTemplate template, Class<? extends PagedApiR
897898
return resources;
898899
}
899900

900-
private <V> V getResource(UriTemplate template, Class<? extends V> clazz) throws IOException, InterruptedException {
901-
String url = template.expand();
902-
String response = getRequest(url);
903-
try {
904-
return JsonParser.toJava(response, clazz);
905-
} catch (IOException e) {
906-
throw new IOException("I/O error when parsing response from URL: " + url, e);
907-
}
908-
}
909-
910901
private <V> V getResource(UriTemplate template, Class<? extends PagedApiResponse<V>> clazz, Predicate<V> filter) throws IOException, InterruptedException {
911902

912903
PagedApiResponse<V> page;

src/test/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketGitSCMRevisionTest.java

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@
3030
import java.util.Collection;
3131
import java.util.Set;
3232
import jenkins.scm.api.SCMHead;
33+
import jenkins.scm.api.mixin.TagSCMHead;
3334
import jenkins.scm.api.trait.SCMHeadAuthority;
3435
import jenkins.scm.api.trait.SCMSourceTrait;
3536
import org.hamcrest.Matchers;
@@ -58,7 +59,9 @@ public static Collection<Object[]> data() {
5859
{ "PR on cloud", new OriginPullRequestDiscoveryTrait(2), BitbucketCloudEndpoint.SERVER_URL }, //
5960
{ "PR on server", new OriginPullRequestDiscoveryTrait(2), "localhost" }, //
6061
{ "forked on cloud", new ForkPullRequestDiscoveryTrait(2, Mockito.mock(SCMHeadAuthority.class)), BitbucketCloudEndpoint.SERVER_URL }, //
61-
{ "forked on server", new ForkPullRequestDiscoveryTrait(2, Mockito.mock(SCMHeadAuthority.class)), "localhost" } //
62+
{ "forked on server", new ForkPullRequestDiscoveryTrait(2, Mockito.mock(SCMHeadAuthority.class)), "localhost" }, //
63+
{ "Tags on cloud", new TagDiscoveryTrait(), BitbucketCloudEndpoint.SERVER_URL }, //
64+
{ "Tags on server", new TagDiscoveryTrait(), "localhost" } //
6265
});
6366
}
6467

@@ -99,6 +102,9 @@ public void verify_revision_informations_are_valued() throws Exception {
99102
PullRequestSCMRevision<BitbucketGitSCMRevision> revision = (PullRequestSCMRevision<BitbucketGitSCMRevision>) source.retrieve(head, listener);
100103
assertRevision(revision.getPull());
101104
assertRevision((BitbucketGitSCMRevision) revision.getTarget());
105+
} else if(head instanceof TagSCMHead) {
106+
BitbucketTagSCMRevision revision = (BitbucketTagSCMRevision) source.retrieve(head, listener);
107+
assertRevision(revision);
102108
}
103109
}
104110
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"hash": "046d9a3c1532acf4cf08fe93235c00e4d673c1d2",
3+
"repository": {
4+
"links": {
5+
"self": {
6+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos"
7+
},
8+
"html": {
9+
"href": "https://bitbucket.org/amuniz/test-repos"
10+
},
11+
"avatar": {
12+
"href": "https://bytebucket.org/ravatar/%7B3deb8c29-778a-450c-8f69-3e50a18079df%7D?ts=default"
13+
}
14+
},
15+
"type": "repository",
16+
"name": "test-repos",
17+
"full_name": "amuniz/test-repos",
18+
"uuid": "{3deb8c29-778a-450c-8f69-3e50a18079df}"
19+
},
20+
"links": {
21+
"self": {
22+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/046d9a3c1532acf4cf08fe93235c00e4d673c1d2"
23+
},
24+
"comments": {
25+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/046d9a3c1532acf4cf08fe93235c00e4d673c1d2/comments"
26+
},
27+
"patch": {
28+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/patch/046d9a3c1532acf4cf08fe93235c00e4d673c1d2"
29+
},
30+
"html": {
31+
"href": "https://bitbucket.org/amuniz/test-repos/commits/046d9a3c1532acf4cf08fe93235c00e4d673c1d2"
32+
},
33+
"diff": {
34+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/diff/046d9a3c1532acf4cf08fe93235c00e4d673c1d2"
35+
},
36+
"approve": {
37+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/046d9a3c1532acf4cf08fe93235c00e4d673c1d2/approve"
38+
},
39+
"statuses": {
40+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/046d9a3c1532acf4cf08fe93235c00e4d673c1d2/statuses"
41+
}
42+
},
43+
"author": {
44+
"raw": "Nikolas Falco <[email protected]>"
45+
},
46+
"summary": {
47+
"raw": "Add one message more",
48+
"markup": "markdown",
49+
"html": "<p>Add one message more</p>",
50+
"type": "rendered"
51+
},
52+
"participants": [],
53+
"parents": [{
54+
"hash": "bf4f4ce8a3a8d5c7dbfe7d609973a81a6c6664cf",
55+
"type": "commit",
56+
"links": {
57+
"self": {
58+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/bf4f4ce8a3a8d5c7dbfe7d609973a81a6c6664cf"
59+
},
60+
"html": {
61+
"href": "https://bitbucket.org/amuniz/test-repos/commits/bf4f4ce8a3a8d5c7dbfe7d609973a81a6c6664cf"
62+
}
63+
}
64+
}],
65+
"date": "2018-09-21T14:49:23+00:00",
66+
"message": "Add one message more",
67+
"type": "commit"
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
{
2+
"hash": "bf0e8b7962c024026ad01ae09d3a11732e26c0d4",
3+
"repository": {
4+
"links": {
5+
"self": {
6+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos"
7+
},
8+
"html": {
9+
"href": "https://bitbucket.org/amuniz/test-repos"
10+
},
11+
"avatar": {
12+
"href": "https://bytebucket.org/ravatar/%7B3deb8c29-778a-450c-8f69-3e50a18079df%7D?ts=default"
13+
}
14+
},
15+
"type": "repository",
16+
"name": "test-repos",
17+
"full_name": "amuniz/test-repos",
18+
"uuid": "{3deb8c29-778a-450c-8f69-3e50a18079df}"
19+
},
20+
"links": {
21+
"self": {
22+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/bf0e8b7962c024026ad01ae09d3a11732e26c0d4"
23+
},
24+
"comments": {
25+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/bf0e8b7962c024026ad01ae09d3a11732e26c0d4/comments"
26+
},
27+
"patch": {
28+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/patch/bf0e8b7962c024026ad01ae09d3a11732e26c0d4"
29+
},
30+
"html": {
31+
"href": "https://bitbucket.org/amuniz/test-repos/commits/bf0e8b7962c024026ad01ae09d3a11732e26c0d4"
32+
},
33+
"diff": {
34+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/diff/bf0e8b7962c024026ad01ae09d3a11732e26c0d4"
35+
},
36+
"approve": {
37+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/bf0e8b7962c024026ad01ae09d3a11732e26c0d4/approve"
38+
},
39+
"statuses": {
40+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/bf0e8b7962c024026ad01ae09d3a11732e26c0d4/statuses"
41+
}
42+
},
43+
"author": {
44+
"raw": "Builder <[email protected]>"
45+
},
46+
"summary": {
47+
"raw": "[CI] Release version 1.0.0",
48+
"markup": "markdown",
49+
"html": "<p>[CI] Release version 1.0.0</p>",
50+
"type": "rendered"
51+
},
52+
"participants": [],
53+
"parents": [{
54+
"hash": "4bec6858eade48522da1d2f295a9d1b2360982ba",
55+
"type": "commit",
56+
"links": {
57+
"self": {
58+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/4bec6858eade48522da1d2f295a9d1b2360982ba"
59+
},
60+
"html": {
61+
"href": "https://bitbucket.org/amuniz/test-repos/commits/4bec6858eade48522da1d2f295a9d1b2360982ba"
62+
}
63+
}
64+
}],
65+
"date": "2018-09-21T14:53:12+00:00",
66+
"message": "[CI] Release version 1.0.0",
67+
"type": "commit"
68+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,121 @@
1+
{
2+
"name": "special-\"$;><&#_=@!|.,/test",
3+
"type": "tag",
4+
"message": "Test special chars\n",
5+
"date": "2023-06-01T23:33:41+00:00",
6+
"tagger": {
7+
"type": "author",
8+
"raw": "John Doe <[email protected]>",
9+
"user": {
10+
"display_name": "amuniz",
11+
"links": {
12+
"self": {
13+
"href": "https://api.bitbucket.org/2.0/users/amuniz"
14+
},
15+
"avatar": {
16+
"href": "https://bytebucket.org/ravatar/%7B3deb8c29-778a-450c-8f69-3e50a18079df%7D?ts=default"
17+
},
18+
"html": {
19+
"href": "https://bitbucket.org/amuniz/"
20+
}
21+
},
22+
"type": "user",
23+
"uuid": "{303f084f-c85d-45c0-9fcb-655e3d887c39}",
24+
"account_id": "557058:7fc0bd24-4a5a-490d-bd73-68536aa02730",
25+
"nickname": "amuniz"
26+
}
27+
},
28+
"target": {
29+
"type": "commit",
30+
"hash": "bf0e8b7962c024026ad01ae09d3a11732e26c0d4",
31+
"date": "2023-06-01T23:32:44+00:00",
32+
"author": {
33+
"type": "author",
34+
"raw": "Builder <[email protected]>",
35+
"user": {
36+
"display_name": "amuniz",
37+
"links": {
38+
"self": {
39+
"href": "https://api.bitbucket.org/2.0/users/amuniz"
40+
},
41+
"avatar": {
42+
"href": "https://bytebucket.org/ravatar/%7B3deb8c29-778a-450c-8f69-3e50a18079df%7D?ts=default"
43+
},
44+
"html": {
45+
"href": "https://bitbucket.org/amuniz/"
46+
}
47+
},
48+
"type": "user",
49+
"uuid": "{303f084f-c85d-45c0-9fcb-655e3d887c39}",
50+
"account_id": "557058:7fc0bd24-4a5a-490d-bd73-68536aa02730",
51+
"nickname": "amuniz"
52+
}
53+
},
54+
"message": "[CI] Release version 1.0.0",
55+
"links": {
56+
"self": {
57+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/bf0e8b7962c024026ad01ae09d3a11732e26c0d4"
58+
},
59+
"html": {
60+
"href": "https://bitbucket.org/amuniz/test-repos/commits/bf0e8b7962c024026ad01ae09d3a11732e26c0d4"
61+
},
62+
"diff": {
63+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/diff/bf0e8b7962c024026ad01ae09d3a11732e26c0d4"
64+
},
65+
"approve": {
66+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/bf0e8b7962c024026ad01ae09d3a11732e26c0d4/approve"
67+
},
68+
"comments": {
69+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/bf0e8b7962c024026ad01ae09d3a11732e26c0d4/comments"
70+
},
71+
"statuses": {
72+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/bf0e8b7962c024026ad01ae09d3a11732e26c0d4/statuses"
73+
},
74+
"patch": {
75+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/patch/bf0e8b7962c024026ad01ae09d3a11732e26c0d4"
76+
}
77+
},
78+
"parents": [
79+
{
80+
"type": "commit",
81+
"hash": "4bec6858eade48522da1d2f295a9d1b2360982ba",
82+
"links": {
83+
"self": {
84+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commit/4bec6858eade48522da1d2f295a9d1b2360982ba"
85+
},
86+
"html": {
87+
"href": "https://bitbucket.org/amuniz/test-repos/commits/4bec6858eade48522da1d2f295a9d1b2360982ba"
88+
}
89+
}
90+
}
91+
],
92+
"repository": {
93+
"type": "repository",
94+
"full_name": "amuniz/test-repos",
95+
"links": {
96+
"self": {
97+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos"
98+
},
99+
"html": {
100+
"href": "https://bitbucket.org/amuniz/test-repos"
101+
},
102+
"avatar": {
103+
"href": "https://bytebucket.org/ravatar/%7B3deb8c29-778a-450c-8f69-3e50a18079df%7D?ts=default"
104+
}
105+
},
106+
"name": "test-repos",
107+
"uuid": "{4f0f5dbc-56c4-4ee1-bff9-34bd6149f6a6}"
108+
}
109+
},
110+
"links": {
111+
"self": {
112+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/refs/tags/special-%22$;%3E%3C&%23_=@!%7C.,/test"
113+
},
114+
"commits": {
115+
"href": "https://api.bitbucket.org/2.0/repositories/amuniz/test-repos/commits/special-%22$;%3E%3C&%23_=@!%7C.,/test"
116+
},
117+
"html": {
118+
"href": "https://bitbucket.org/amuniz/test-repos/commits/tag/special-%22$;%3E%3C&%23_=@!%7C.,/test"
119+
}
120+
}
121+
}

0 commit comments

Comments
 (0)