Skip to content

Commit 1852034

Browse files
committed
Merge branches 'use-additional-info-from-clone-links' and 'native-webhooks' into HEAD
2 parents 3f2ca00 + 9fb3410 commit 1852034

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

42 files changed

+1384
-353
lines changed

README.adoc

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,4 +8,4 @@ This means that when you have a private repository, or a private fork of a publi
88
=== How-to run and test with Bitbucket Server locally
99

1010
* https://developer.atlassian.com/server/framework/atlassian-sdk/install-the-atlassian-sdk-on-a-linux-or-mac-system/[Install the Atlassian SDK on Linux or Mac] or https://developer.atlassian.com/server/framework/atlassian-sdk/install-the-atlassian-sdk-on-a-windows-system/[on Windows]
11-
* To run 5.2.0 server: atlas-run-standalone -u 6.3.0 --product bitbucket --version 5.2.0 --data-version 5.2.0
11+
* To run 5.2.0 server: `atlas-run-standalone -u 6.3.0 --product bitbucket --version 5.2.0 --data-version 5.2.0`

pom.xml

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
</parent>
3434

3535
<artifactId>cloudbees-bitbucket-branch-source</artifactId>
36-
<version>2.2.11-SNAPSHOT</version>
36+
<version>2.2.13-SNAPSHOT</version>
3737
<packaging>hpi</packaging>
3838

3939
<name>Bitbucket Branch Source Plugin</name>
@@ -52,8 +52,23 @@
5252
<jenkins.version>1.642.3</jenkins.version>
5353
<java.level>7</java.level>
5454
<scm-api.version>2.2.0</scm-api.version>
55-
<git.version>3.5.0</git.version>
55+
<git.version>3.6.0</git.version>
5656
</properties>
57+
58+
<developers>
59+
<developer>
60+
<id>amuniz</id>
61+
<name>Antonio Muniz</name>
62+
</developer>
63+
<developer>
64+
<id>rsandell</id>
65+
<name>Bobby Sandell</name>
66+
</developer>
67+
<developer>
68+
<id>vivek</id>
69+
<name>Vivek Pandey</name>
70+
</developer>
71+
</developers>
5772

5873
<scm>
5974
<connection>scm:git:git://github.com/jenkinsci/bitbucket-branch-source-plugin.git</connection>
@@ -95,7 +110,7 @@
95110
<dependency>
96111
<groupId>org.jenkins-ci.plugins</groupId>
97112
<artifactId>structs</artifactId>
98-
<version>1.9</version>
113+
<version>1.10</version>
99114
</dependency>
100115
<dependency>
101116
<groupId>org.jenkins-ci.plugins</groupId>

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMNavigator.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -227,9 +227,11 @@ public void setCredentialsId(@CheckForNull String credentialsId) {
227227
this.credentialsId = Util.fixEmpty(credentialsId);
228228
}
229229

230+
@SuppressWarnings("unchecked")
230231
@DataBoundSetter
231-
public void setTraits(@NonNull List<SCMTrait<? extends SCMTrait<?>>> traits) {
232-
this.traits = new ArrayList<>(/*defensive*/Util.fixNull(traits));
232+
public void setTraits(@NonNull List<SCMTrait> traits) {
233+
// the reduced generics in the method signature are a workaround for JENKINS-26535
234+
this.traits = new ArrayList<>((List)/*defensive*/Util.fixNull(traits));
233235
}
234236

235237
public String getServerUrl() {
@@ -594,10 +596,11 @@ public String getIconClassName() {
594596
return "icon-bitbucket-scmnavigator";
595597
}
596598

599+
@SuppressWarnings("unchecked")
597600
@Override
598601
public SCMNavigator newInstance(String name) {
599602
BitbucketSCMNavigator instance = new BitbucketSCMNavigator(StringUtils.defaultString(name));
600-
instance.setTraits(getTraitsDefaults());
603+
instance.setTraits((List) getTraitsDefaults());
601604
return instance;
602605
}
603606

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSource.java

Lines changed: 71 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,7 @@
8686
import java.util.logging.Level;
8787
import java.util.logging.Logger;
8888
import jenkins.plugins.git.AbstractGitSCMSource.SCMRevisionImpl;
89+
import jenkins.plugins.git.GitTagSCMRevision;
8990
import jenkins.plugins.git.traits.GitBrowserSCMSourceTrait;
9091
import jenkins.scm.api.SCMHead;
9192
import jenkins.scm.api.SCMHeadCategory;
@@ -106,6 +107,7 @@
106107
import jenkins.scm.api.trait.SCMSourceTrait;
107108
import jenkins.scm.api.trait.SCMSourceTraitDescriptor;
108109
import jenkins.scm.impl.ChangeRequestSCMHeadCategory;
110+
import jenkins.scm.impl.TagSCMHeadCategory;
109111
import jenkins.scm.impl.UncategorizedSCMHeadCategory;
110112
import jenkins.scm.impl.form.NamedArrayList;
111113
import jenkins.scm.impl.trait.Discovery;
@@ -506,11 +508,15 @@ public BitbucketRepositoryType getRepositoryType() throws IOException, Interrupt
506508
}
507509

508510
public BitbucketApi buildBitbucketClient() {
509-
return BitbucketApiFactory.newInstance(getServerUrl(), credentials(), repoOwner, repository);
511+
return buildBitbucketClient(repoOwner, repository);
510512
}
511513

512514
public BitbucketApi buildBitbucketClient(PullRequestSCMHead head) {
513-
return BitbucketApiFactory.newInstance(getServerUrl(), credentials(), head.getRepoOwner(), head.getRepository());
515+
return buildBitbucketClient(head.getRepoOwner(), head.getRepository());
516+
}
517+
518+
public BitbucketApi buildBitbucketClient(String repoOwner, String repository) {
519+
return BitbucketApiFactory.newInstance(getServerUrl(), credentials(), repoOwner, repository);
514520
}
515521

516522
@Override
@@ -566,7 +572,16 @@ protected Iterable<BitbucketBranch> create() {
566572
});
567573
}
568574
if (request.isFetchTags()) {
569-
// TODO request.setTags(...);
575+
request.setTags(new LazyIterable<BitbucketBranch>() {
576+
@Override
577+
protected Iterable<BitbucketBranch> create() {
578+
try {
579+
return (Iterable<BitbucketBranch>) buildBitbucketClient().getTags();
580+
} catch (IOException | InterruptedException e) {
581+
throw new BitbucketSCMSource.WrappedException(e);
582+
}
583+
}
584+
});
570585
}
571586

572587
// now server the request
@@ -579,7 +594,8 @@ protected Iterable<BitbucketBranch> create() {
579594
retrievePullRequests(request);
580595
}
581596
if (request.isFetchTags() && !request.isComplete()) {
582-
// TODO
597+
//Search tags
598+
retrieveTags(request);
583599
}
584600
} catch (WrappedException e) {
585601
e.unwrap();
@@ -778,6 +794,38 @@ public String create() {
778794
request.listener().getLogger().format("%n %d branches were processed%n", count);
779795
}
780796

797+
798+
private void retrieveTags(final BitbucketSCMSourceRequest request)
799+
throws IOException, InterruptedException {
800+
String fullName = repoOwner + "/" + repository;
801+
request.listener().getLogger().println("Looking up " + fullName + " for tags");
802+
803+
final BitbucketApi bitbucket = buildBitbucketClient();
804+
Map<String, List<BitbucketHref>> links = bitbucket.getRepository().getLinks();
805+
if (links != null && links.containsKey("clone")) {
806+
cloneLinks = links.get("clone");
807+
}
808+
int count = 0;
809+
for (final BitbucketBranch tag : request.getTags()) {
810+
request.listener().getLogger().println("Checking tag " + tag.getName() + " from " + fullName);
811+
count++;
812+
if (request.process(new BitbucketTagSCMHead(tag.getName(), tag.getDateMillis(), repositoryType),
813+
new SCMSourceRequest.IntermediateLambda<String>() {
814+
@Nullable
815+
@Override
816+
public String create() {
817+
return tag.getRawNode();
818+
}
819+
}, new BitbucketProbeFactory(bitbucket, request), new BitbucketRevisionFactory(),
820+
new CriteriaWitness(request)
821+
)) {
822+
request.listener().getLogger().format("%n %d tags were processed (query completed)%n", count);
823+
return;
824+
}
825+
}
826+
request.listener().getLogger().format("%n %d tags were processed%n", count);
827+
}
828+
781829
@Override
782830
protected SCMRevision retrieve(SCMHead head, TaskListener listener) throws IOException, InterruptedException {
783831
final BitbucketApi bitbucket = buildBitbucketClient();
@@ -823,6 +871,19 @@ protected SCMRevision retrieve(SCMHead head, TaskListener listener) throws IOExc
823871
new SCMRevisionImpl(h, sourceRevision)
824872
);
825873
}
874+
} else if(head instanceof BitbucketTagSCMHead) {
875+
BitbucketTagSCMHead tagHead = (BitbucketTagSCMHead) head;
876+
List<? extends BitbucketBranch> tags = bitbucket.getTags();
877+
String revision = findRawNode(head.getName(), tags, listener);
878+
if (revision == null) {
879+
LOGGER.log(Level.WARNING, "No tag found in {0}/{1} with name [{2}]", new Object[] { repoOwner, repository, head.getName() });
880+
return null;
881+
}
882+
if (getRepositoryType() == BitbucketRepositoryType.MERCURIAL) {
883+
return new MercurialRevision(head, revision);
884+
} else {
885+
return new GitTagSCMRevision(tagHead, revision);
886+
}
826887
} else {
827888
String revision = findRawNode(head.getName(), branches, listener);
828889
if (revision == null) {
@@ -889,8 +950,10 @@ public SCM build(SCMHead head, SCMRevision revision) {
889950
type = ((PullRequestSCMHead) head).getRepositoryType();
890951
} else if (head instanceof BranchSCMHead) {
891952
type = ((BranchSCMHead) head).getRepositoryType();
953+
} else if (head instanceof BitbucketTagSCMHead) {
954+
type = ((BitbucketTagSCMHead) head).getRepositoryType();
892955
} else {
893-
throw new IllegalArgumentException("Either PullRequestSCMHead or BranchSCMHead required as parameter");
956+
throw new IllegalArgumentException("Either PullRequestSCMHead, BitbucketTagSCMHead or BranchSCMHead required as parameter");
894957
}
895958
if (type == null) {
896959
if (revision instanceof MercurialRevision) {
@@ -1260,8 +1323,9 @@ public ListBoxModel doFillCheckoutCredentialsIdItems(@AncestorInPath SCMSourceOw
12601323
protected SCMHeadCategory[] createCategories() {
12611324
return new SCMHeadCategory[]{
12621325
new UncategorizedSCMHeadCategory(Messages._BitbucketSCMSource_UncategorizedSCMHeadCategory_DisplayName()),
1263-
new ChangeRequestSCMHeadCategory(Messages._BitbucketSCMSource_ChangeRequestSCMHeadCategory_DisplayName())
1264-
// TODO add support for tags and maybe feature branch identification
1326+
new ChangeRequestSCMHeadCategory(Messages._BitbucketSCMSource_ChangeRequestSCMHeadCategory_DisplayName()),
1327+
new TagSCMHeadCategory(Messages._BitbucketSCMSource_TagSCMHeadCategory_DisplayName())
1328+
// TODO add support for feature branch identification
12651329
};
12661330
}
12671331

src/main/java/com/cloudbees/jenkins/plugins/bitbucket/BitbucketSCMSourceRequest.java

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -114,7 +114,11 @@ public class BitbucketSCMSourceRequest extends SCMSourceRequest {
114114
*/
115115
@CheckForNull
116116
private Iterable<BitbucketBranch> branches;
117-
// TODO private Iterable<BitbucketTag> tags;
117+
/**
118+
* The tag details or {@code null} if not {@link #isFetchTags()}.
119+
*/
120+
@CheckForNull
121+
private Iterable<BitbucketBranch> tags;
118122

119123
/**
120124
* Constructor.
@@ -363,7 +367,25 @@ public final Iterable<BitbucketBranch> getBranches() {
363367
return Util.fixNull(branches);
364368
}
365369

366-
// TODO Iterable<BitbucketTag> getTags() and setTags(...)
370+
/**
371+
* Provides the requests with the tag details.
372+
*
373+
* @param tags the tag details.
374+
*/
375+
public final void setTags(@CheckForNull Iterable<BitbucketBranch> tags) {
376+
this.tags = tags;
377+
}
378+
379+
/**
380+
* Returns the branch details or an empty list if either the request did not specify to {@link #isFetchTags()}
381+
* or if the tag details have not been provided by {@link #setTags(Iterable)} yet.
382+
*
383+
* @return the tag details (may be empty)
384+
*/
385+
@NonNull
386+
public final Iterable<BitbucketBranch> getTags() {
387+
return Util.fixNull(tags);
388+
}
367389

368390
/**
369391
* {@inheritDoc}
Lines changed: 91 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,91 @@
1+
/*
2+
* The MIT License
3+
*
4+
* Copyright (c) 2018, CloudBees, Inc.
5+
*
6+
* Permission is hereby granted, free of charge, to any person obtaining a copy
7+
* of this software and associated documentation files (the "Software"), to deal
8+
* in the Software without restriction, including without limitation the rights
9+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
10+
* copies of the Software, and to permit persons to whom the Software is
11+
* furnished to do so, subject to the following conditions:
12+
*
13+
* The above copyright notice and this permission notice shall be included in
14+
* all copies or substantial portions of the Software.
15+
*
16+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
17+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
18+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
19+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
20+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
21+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
22+
* THE SOFTWARE.
23+
*/
24+
package com.cloudbees.jenkins.plugins.bitbucket;
25+
26+
import com.cloudbees.jenkins.plugins.bitbucket.api.BitbucketRepositoryType;
27+
import edu.umd.cs.findbugs.annotations.CheckForNull;
28+
import edu.umd.cs.findbugs.annotations.NonNull;
29+
import jenkins.plugins.git.GitTagSCMHead;
30+
import jenkins.scm.api.SCMHead;
31+
import jenkins.scm.api.mixin.TagSCMHead;
32+
import org.kohsuke.accmod.Restricted;
33+
import org.kohsuke.accmod.restrictions.DoNotUse;
34+
35+
/**
36+
* {@link SCMHead} for a BitBucket tags.
37+
*
38+
* @since 2.2.11
39+
*/
40+
public class BitbucketTagSCMHead extends GitTagSCMHead implements TagSCMHead {
41+
42+
private static final long serialVersionUID = 1L;
43+
44+
/**
45+
* Cache of the repository type.
46+
*
47+
* @since 2.2.11
48+
*/
49+
// The repository type should be immutable for any SCMSource.
50+
@CheckForNull
51+
private final BitbucketRepositoryType repositoryType;
52+
53+
/**
54+
* Constructor.
55+
*
56+
* @param tagName the tag name
57+
* @param timestamp the timestamp of tag
58+
*/
59+
public BitbucketTagSCMHead(@NonNull String tagName, long timestamp) {
60+
this(tagName, timestamp, BitbucketRepositoryType.GIT);
61+
}
62+
63+
/**
64+
* Constructor.
65+
*
66+
* @param tagName the tag name
67+
* @param timestamp the timestamp of tag
68+
* @param repositoryType the repository type.
69+
*/
70+
public BitbucketTagSCMHead(String tagName, long timestamp, BitbucketRepositoryType repositoryType) {
71+
super(tagName, timestamp);
72+
this.repositoryType = repositoryType;
73+
}
74+
75+
/**
76+
* Gets the repository type.
77+
* @return the repository type or {@code null}
78+
*/
79+
@CheckForNull
80+
public BitbucketRepositoryType getRepositoryType() {
81+
return repositoryType;
82+
}
83+
84+
/**
85+
* {@inheritDoc}
86+
*/
87+
@Override
88+
public String getPronoun() {
89+
return Messages.BitBucketTagSCMHead_Pronoun();
90+
}
91+
}

0 commit comments

Comments
 (0)