├── .gitignore ├── README.md ├── vcs-utils ├── pom.xml └── src │ └── main │ ├── java │ └── com │ │ └── arcbees │ │ └── vcs │ │ ├── VcsType.java │ │ ├── model │ │ ├── Branch.java │ │ ├── Commit.java │ │ ├── Comment.java │ │ ├── PullRequests.java │ │ ├── PullRequestTarget.java │ │ ├── CommitStatus.java │ │ └── PullRequest.java │ │ ├── VcsApiFactory.java │ │ ├── github │ │ ├── GitHubVcsType.java │ │ ├── model │ │ │ ├── GitHubCreateComment.java │ │ │ ├── GitHubComment.java │ │ │ ├── GitHubBranch.java │ │ │ ├── GitHubCommit.java │ │ │ ├── GitHubPullRequests.java │ │ │ ├── GitHubPullRequestTarget.java │ │ │ ├── GitHubCommitStatus.java │ │ │ └── GitHubPullRequest.java │ │ ├── GitHubApiFactory.java │ │ ├── util │ │ │ └── GitHubPullRequestsTypeAdapter.java │ │ ├── GitHubApiPaths.java │ │ └── GitHubApi.java │ │ ├── util │ │ ├── HttpClientWrapper.java │ │ ├── UnexpectedHttpStatusException.java │ │ ├── CommitStatusTypeAdapter.java │ │ ├── PolymorphicTypeAdapter.java │ │ ├── GsonDateTypeAdapter.java │ │ ├── JsonCustomDataStorage.java │ │ └── HttpClientWrapperImpl.java │ │ ├── bitbucket │ │ ├── BitbucketVcsType.java │ │ ├── model │ │ │ ├── BitbucketBranch.java │ │ │ ├── BitbucketCommit.java │ │ │ ├── BitbucketComment.java │ │ │ ├── BitbucketPullRequests.java │ │ │ ├── BitbucketPullRequestTarget.java │ │ │ ├── BitbucketCommitStatus.java │ │ │ └── BitbucketPullRequest.java │ │ ├── BitbucketApiFactory.java │ │ ├── BitbucketApiPaths.java │ │ └── BitbucketApi.java │ │ ├── stash │ │ ├── StashVcsType.java │ │ ├── model │ │ │ ├── StashBranch.java │ │ │ ├── StashCommit.java │ │ │ ├── StashPullRequests.java │ │ │ ├── StashComment.java │ │ │ ├── StashPullRequestTarget.java │ │ │ ├── StashCommitStatus.java │ │ │ └── StashPullRequest.java │ │ ├── StashApiFactory.java │ │ ├── StashApiPaths.java │ │ └── StashApi.java │ │ ├── VcsTypes.java │ │ ├── VcsApiFactories.java │ │ ├── VcsApi.java │ │ ├── VcsPropertiesHelper.java │ │ ├── VcsConstants.java │ │ ├── VcsPropertiesProcessor.java │ │ └── AbstractVcsApi.java │ └── resources │ ├── META-INF │ └── build-server-plugin-vcs-utils.xml │ └── buildServerResources │ └── vcsSettings.jsp ├── staging ├── src │ ├── main │ │ ├── resources │ │ │ ├── META-INF │ │ │ │ └── build-server-plugin-staging.xml │ │ │ └── buildServerResources │ │ │ │ └── staging_deploy.jsp │ │ └── java │ │ │ └── com │ │ │ └── arcbees │ │ │ └── staging │ │ │ ├── UrlUtils.java │ │ │ ├── TomcatManagerFactory.java │ │ │ ├── TomcatManagerFactoryImpl.java │ │ │ ├── Constants.java │ │ │ ├── StagingPropertiesHelper.java │ │ │ ├── TomcatStagingDeploy.java │ │ │ ├── TomcatStagingPropertiesProcessor.java │ │ │ ├── TomcatStagingFeature.java │ │ │ └── StagingBuildListener.java │ └── test │ │ └── java │ │ └── com │ │ └── arcbees │ │ └── vcs │ │ └── util │ │ └── GsonDateTypeAdapterTest.java ├── teamcity-plugin.xml ├── plugin-assembly.xml └── pom.xml ├── pullrequests ├── teamcity-plugin.xml ├── src │ ├── main │ │ ├── java │ │ │ └── com │ │ │ │ └── arcbees │ │ │ │ ├── pullrequest │ │ │ │ ├── BuildStatus.java │ │ │ │ ├── Constants.java │ │ │ │ ├── PullRequestPropertiesHelper.java │ │ │ │ ├── PullRequestBuild.java │ │ │ │ ├── PullRequestChainParser.java │ │ │ │ ├── PullRequestsFeature.java │ │ │ │ └── PullRequestsBuildListener.java │ │ │ │ └── feature │ │ │ │ ├── BuildCommitFeature.java │ │ │ │ ├── BuildCommitBuildListener.java │ │ │ │ └── BuildCommitStatusHandler.java │ │ └── resources │ │ │ ├── META-INF │ │ │ └── build-server-plugin-pullrequests.xml │ │ │ └── buildServerResources │ │ │ ├── feature.jsp │ │ │ └── pullrequests.jsp │ └── test │ │ └── java │ │ └── com │ │ └── arcbees │ │ ├── pullrequest │ │ └── PullRequestChainParserTest.java │ │ └── vcs │ │ └── bitbucket │ │ └── PullRequestStatusHandlerTest.java ├── plugin-assembly.xml └── pom.xml └── pom.xml /.gitignore: -------------------------------------------------------------------------------- 1 | *.iml 2 | .idea* 3 | **/target/* 4 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | teamcity-plugins 2 | ================ 3 | 4 | ##Thanks to 5 | [![Arcbees.com](http://i.imgur.com/HDf1qfq.png)](http://arcbees.com) 6 | 7 | [![Atlassian](http://i.imgur.com/BKkj8Rg.png)](https://www.atlassian.com/) 8 | 9 | [![IntelliJ](https://lh6.googleusercontent.com/--QIIJfKrjSk/UJJ6X-UohII/AAAAAAAAAVM/cOW7EjnH778/s800/banner_IDEA.png)](http://www.jetbrains.com/idea/index.html) 10 | -------------------------------------------------------------------------------- /vcs-utils/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | com.arcbees.teamcity 9 | plugins 10 | 1.0-SNAPSHOT 11 | 12 | 13 | vcs-utils 14 | 1.0-SNAPSHOT 15 | 16 | -------------------------------------------------------------------------------- /staging/src/main/resources/META-INF/build-server-plugin-staging.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | -------------------------------------------------------------------------------- /pullrequests/teamcity-plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | PullRequestTrigger 6 | Pull Request Trigger 7 | @Version@ 8 | 9 | 10 | maxime.meriouma@arcbees.com 11 | 12 | ArcBees 13 | http://www.arcbees.com 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /staging/teamcity-plugin.xml: -------------------------------------------------------------------------------- 1 | 2 | 4 | 5 | Tomcat7Staging 6 | Tomcat 7 Deploy to Staging 7 | @Version@ 8 | 9 | 10 | maxime.meriouma@arcbees.com 11 | 12 | ArcBees 13 | http://www.arcbees.com 14 | 15 | 16 | 17 | 18 | 19 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/VcsType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs; 18 | 19 | public interface VcsType { 20 | String getName(); 21 | } 22 | -------------------------------------------------------------------------------- /pullrequests/src/main/java/com/arcbees/pullrequest/BuildStatus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.pullrequest; 18 | 19 | public enum BuildStatus { 20 | STARTING, 21 | INTERRUPTED, 22 | FINISHED 23 | } 24 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/model/Branch.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.model; 18 | 19 | public interface Branch { 20 | String getName(); 21 | 22 | void setName(String name); 23 | } 24 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/model/Commit.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.model; 18 | 19 | public interface Commit { 20 | String getHash(); 21 | 22 | void setHash(String hash); 23 | } 24 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/model/Comment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.model; 18 | 19 | public interface Comment { 20 | Long getCommentId(); 21 | 22 | void setCommentId(Long commentId); 23 | } 24 | -------------------------------------------------------------------------------- /pullrequests/src/main/resources/META-INF/build-server-plugin-pullrequests.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/VcsApiFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs; 18 | 19 | public interface VcsApiFactory { 20 | VcsApi create(VcsPropertiesHelper vcsPropertiesHelper); 21 | 22 | boolean handles(VcsType vcsType); 23 | } 24 | -------------------------------------------------------------------------------- /staging/plugin-assembly.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | plugin-assembly 6 | false 7 | 8 | zip 9 | 10 | 11 | 12 | target/teamcity-plugin.xml 13 | / 14 | 15 | 16 | 17 | 18 | true 19 | server 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /pullrequests/plugin-assembly.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | plugin-assembly 6 | false 7 | 8 | zip 9 | 10 | 11 | 12 | target/teamcity-plugin.xml 13 | / 14 | 15 | 16 | 17 | 18 | true 19 | server 20 | 21 | 22 | 23 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.model; 18 | 19 | import java.util.List; 20 | 21 | public interface PullRequests { 22 | List getPullRequests(); 23 | 24 | void setPullRequests(List pullRequests); 25 | } 26 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequestTarget.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.model; 18 | 19 | public interface PullRequestTarget { 20 | Commit getCommit(); 21 | 22 | void setCommit(C commit); 23 | 24 | Branch getBranch(); 25 | 26 | void setBranch(B branch); 27 | } 28 | -------------------------------------------------------------------------------- /vcs-utils/src/main/resources/META-INF/build-server-plugin-vcs-utils.xml: -------------------------------------------------------------------------------- 1 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | 17 | 18 | 19 | 20 | 21 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/GitHubVcsType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github; 18 | 19 | import com.arcbees.vcs.VcsType; 20 | 21 | public class GitHubVcsType implements VcsType { 22 | private static final String GITHUB = "github"; 23 | 24 | @Override 25 | public String getName() { 26 | return GITHUB; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/util/HttpClientWrapper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.util; 18 | 19 | import java.io.IOException; 20 | 21 | import org.apache.http.HttpResponse; 22 | import org.apache.http.client.methods.HttpUriRequest; 23 | 24 | public interface HttpClientWrapper { 25 | HttpResponse execute(HttpUriRequest request) throws IOException; 26 | } 27 | -------------------------------------------------------------------------------- /staging/src/main/java/com/arcbees/staging/UrlUtils.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.staging; 18 | 19 | import java.net.URL; 20 | 21 | public class UrlUtils { 22 | public static String extractBaseUrl(URL url) { 23 | String port = url.getPort() > 0 ? ":" + url.getPort() : ""; 24 | 25 | return url.getProtocol() + "://" + url.getHost() + port; 26 | } 27 | } 28 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketVcsType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket; 18 | 19 | import com.arcbees.vcs.VcsType; 20 | 21 | public class BitbucketVcsType implements VcsType { 22 | private static final String BITBUCKET = "bitbucket"; 23 | 24 | @Override 25 | public String getName() { 26 | return BITBUCKET; 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/model/CommitStatus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.model; 18 | 19 | public enum CommitStatus { 20 | ERROR, 21 | FAILURE, 22 | PENDING, 23 | SUCCESS; 24 | 25 | private final String statusCode; 26 | 27 | CommitStatus() { 28 | this.statusCode = name().toLowerCase(); 29 | } 30 | 31 | public String getStatusCode() { 32 | return statusCode; 33 | } 34 | } 35 | -------------------------------------------------------------------------------- /staging/src/main/java/com/arcbees/staging/TomcatManagerFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.staging; 18 | 19 | import java.net.MalformedURLException; 20 | import java.net.URISyntaxException; 21 | 22 | import org.apache.tomcat.maven.common.deployer.TomcatManager; 23 | 24 | public interface TomcatManagerFactory { 25 | TomcatManager create(StagingPropertiesHelper stagingPropertiesHelper) 26 | throws URISyntaxException, MalformedURLException; 27 | } 28 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/model/GitHubCreateComment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github.model; 18 | 19 | public class GitHubCreateComment { 20 | private String body; 21 | 22 | public GitHubCreateComment(String body) { 23 | this.body = body; 24 | } 25 | 26 | public String getBody() { 27 | return body; 28 | } 29 | 30 | public void setBody(String body) { 31 | this.body = body; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketBranch.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket.model; 18 | 19 | import com.arcbees.vcs.model.Branch; 20 | 21 | public class BitbucketBranch implements Branch { 22 | private String name; 23 | 24 | @Override 25 | public String getName() { 26 | return name; 27 | } 28 | 29 | @Override 30 | public void setName(String name) { 31 | this.name = name; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketCommit.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket.model; 18 | 19 | import com.arcbees.vcs.model.Commit; 20 | 21 | public class BitbucketCommit implements Commit { 22 | private String hash; 23 | 24 | @Override 25 | public String getHash() { 26 | return hash; 27 | } 28 | 29 | @Override 30 | public void setHash(String hash) { 31 | this.hash = hash; 32 | } 33 | } 34 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/StashVcsType.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * This file is part of Stash TeamCity plugin. 5 | * 6 | * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU 7 | * General Public License as published by the Free Software Foundation, either version 3 of the License, 8 | * or (at your option) any later version. 9 | * 10 | * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, 15 | * see http://www.gnu.org/licenses/. 16 | */ 17 | 18 | package com.arcbees.vcs.stash; 19 | 20 | import com.arcbees.vcs.VcsType; 21 | 22 | public class StashVcsType implements VcsType { 23 | private static final String STASH = "stash"; 24 | 25 | @Override 26 | public String getName() { 27 | return STASH; 28 | } 29 | } 30 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/util/UnexpectedHttpStatusException.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.util; 18 | 19 | import java.io.IOException; 20 | 21 | public class UnexpectedHttpStatusException extends IOException { 22 | private final int statusCode; 23 | 24 | public UnexpectedHttpStatusException(int statusCode, String message) { 25 | super(message); 26 | this.statusCode = statusCode; 27 | } 28 | 29 | public int getStatusCode() { 30 | return statusCode; 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/model/GitHubComment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github.model; 18 | 19 | import com.arcbees.vcs.model.Comment; 20 | import com.google.gson.annotations.SerializedName; 21 | 22 | public class GitHubComment implements Comment { 23 | @SerializedName("id") 24 | private Long commentId; 25 | 26 | @Override 27 | public Long getCommentId() { 28 | return commentId; 29 | } 30 | 31 | @Override 32 | public void setCommentId(Long commentId) { 33 | this.commentId = commentId; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketComment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket.model; 18 | 19 | import com.arcbees.vcs.model.Comment; 20 | import com.google.gson.annotations.SerializedName; 21 | 22 | public class BitbucketComment implements Comment { 23 | @SerializedName("comment_id") 24 | private Long commentId; 25 | 26 | @Override 27 | public Long getCommentId() { 28 | return commentId; 29 | } 30 | 31 | @Override 32 | public void setCommentId(Long commentId) { 33 | this.commentId = commentId; 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/model/GitHubBranch.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github.model; 18 | 19 | import com.arcbees.vcs.model.Branch; 20 | 21 | public class GitHubBranch implements Branch { 22 | private String name; 23 | 24 | public GitHubBranch() { 25 | } 26 | 27 | public GitHubBranch(String name) { 28 | this.name = name; 29 | } 30 | 31 | @Override 32 | public String getName() { 33 | return name; 34 | } 35 | 36 | @Override 37 | public void setName(String name) { 38 | this.name = name; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/model/GitHubCommit.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github.model; 18 | 19 | import com.arcbees.vcs.model.Commit; 20 | 21 | public class GitHubCommit implements Commit { 22 | private String hash; 23 | 24 | public GitHubCommit() { 25 | } 26 | 27 | public GitHubCommit(String hash) { 28 | this.hash = hash; 29 | } 30 | 31 | @Override 32 | public String getHash() { 33 | return hash; 34 | } 35 | 36 | @Override 37 | public void setHash(String hash) { 38 | this.hash = hash; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /pullrequests/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | com.arcbees.teamcity 9 | plugins 10 | 1.0-SNAPSHOT 11 | 12 | 13 | pullrequests 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 18 | com.arcbees.teamcity 19 | vcs-utils 20 | ${project.version} 21 | 22 | 23 | 24 | 25 | 26 | 27 | com.google.code.maven-replacer-plugin 28 | replacer 29 | 30 | 31 | maven-assembly-plugin 32 | 33 | 34 | 35 | 36 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/VcsTypes.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs; 18 | 19 | import java.util.List; 20 | 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.stereotype.Component; 23 | 24 | @Component 25 | public class VcsTypes { 26 | @Autowired 27 | private List vcsTypes; 28 | 29 | public VcsType getVcsType(String vcsType) { 30 | for (VcsType type : vcsTypes) { 31 | if (type.getName().equals(vcsType)) { 32 | return type; 33 | } 34 | } 35 | 36 | return null; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pullrequests/src/main/resources/buildServerResources/feature.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="/include.jsp" %> 2 | <%@ include file="/include-internal.jsp" %> 3 | 4 | 5 | 6 | 32 | 33 | <%@ include file="vcsSettings.jsp" %> 34 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/util/CommitStatusTypeAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.util; 18 | 19 | import java.lang.reflect.Type; 20 | 21 | import com.arcbees.vcs.model.CommitStatus; 22 | import com.google.gson.JsonElement; 23 | import com.google.gson.JsonPrimitive; 24 | import com.google.gson.JsonSerializationContext; 25 | import com.google.gson.JsonSerializer; 26 | 27 | public class CommitStatusTypeAdapter implements JsonSerializer { 28 | @Override 29 | public JsonElement serialize(CommitStatus src, Type typeOfSrc, JsonSerializationContext context) { 30 | return new JsonPrimitive(src.getStatusCode()); 31 | } 32 | } 33 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/model/GitHubPullRequests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github.model; 18 | 19 | import java.util.List; 20 | 21 | import com.arcbees.vcs.model.PullRequest; 22 | import com.arcbees.vcs.model.PullRequests; 23 | 24 | public class GitHubPullRequests implements PullRequests { 25 | private List pullRequests; 26 | 27 | @Override 28 | public List getPullRequests() { 29 | return pullRequests; 30 | } 31 | 32 | @Override 33 | public void setPullRequests(List pullRequests) { 34 | this.pullRequests = pullRequests; 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashBranch.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * This file is part of Stash TeamCity plugin. 5 | * 6 | * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU 7 | * General Public License as published by the Free Software Foundation, either version 3 of the License, 8 | * or (at your option) any later version. 9 | * 10 | * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, 15 | * see http://www.gnu.org/licenses/. 16 | */ 17 | 18 | package com.arcbees.vcs.stash.model; 19 | 20 | import com.arcbees.vcs.model.Branch; 21 | 22 | public class StashBranch implements Branch { 23 | private String name; 24 | 25 | public StashBranch() { 26 | } 27 | 28 | public StashBranch(String name) { 29 | this.name = name; 30 | } 31 | 32 | @Override 33 | public String getName() { 34 | return name; 35 | } 36 | 37 | @Override 38 | public void setName(String name) { 39 | this.name = name; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashCommit.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * This file is part of Stash TeamCity plugin. 5 | * 6 | * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU 7 | * General Public License as published by the Free Software Foundation, either version 3 of the License, 8 | * or (at your option) any later version. 9 | * 10 | * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, 15 | * see http://www.gnu.org/licenses/. 16 | */ 17 | 18 | package com.arcbees.vcs.stash.model; 19 | 20 | import com.arcbees.vcs.model.Commit; 21 | 22 | public class StashCommit implements Commit { 23 | private String hash; 24 | 25 | public StashCommit() { 26 | } 27 | 28 | public StashCommit(String hash) { 29 | this.hash = hash; 30 | } 31 | 32 | @Override 33 | public String getHash() { 34 | return hash; 35 | } 36 | 37 | @Override 38 | public void setHash(String hash) { 39 | this.hash = hash; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /staging/src/main/java/com/arcbees/staging/TomcatManagerFactoryImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.staging; 18 | 19 | import java.net.MalformedURLException; 20 | import java.net.URI; 21 | import java.net.URISyntaxException; 22 | import java.net.URL; 23 | 24 | import org.apache.tomcat.maven.common.deployer.TomcatManager; 25 | 26 | public class TomcatManagerFactoryImpl implements TomcatManagerFactory { 27 | @Override 28 | public TomcatManager create(StagingPropertiesHelper propertiesHelper) 29 | throws URISyntaxException, MalformedURLException { 30 | URI uri = new URI(propertiesHelper.getTomcatUrl()); 31 | URL url = uri.toURL(); 32 | 33 | return new TomcatManager(url, propertiesHelper.getUserName(), propertiesHelper.getPassword()); 34 | } 35 | } 36 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket.model; 18 | 19 | import java.util.List; 20 | 21 | import com.arcbees.vcs.model.PullRequest; 22 | import com.arcbees.vcs.model.PullRequests; 23 | import com.google.gson.annotations.SerializedName; 24 | 25 | public class BitbucketPullRequests implements PullRequests { 26 | @SerializedName("values") 27 | private List pullRequests; 28 | 29 | @Override 30 | public List getPullRequests() { 31 | return pullRequests; 32 | } 33 | 34 | @Override 35 | public void setPullRequests(List pullRequests) { 36 | this.pullRequests = pullRequests; 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /pullrequests/src/main/java/com/arcbees/pullrequest/Constants.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.pullrequest; 18 | 19 | public class Constants { 20 | private static final String BUILD_SUCCESS = "BUILD SUCCESS "; 21 | private static final String BUILD_FAILURE = "BUILD FAILURE "; 22 | private static final String BUILD_STARTED = "TeamCity Build Started : "; 23 | private static final String APPROVE_ON_SUCCESS_KEY = "pullrequest_approve"; 24 | 25 | public String getBuildSuccess() { 26 | return BUILD_SUCCESS; 27 | } 28 | 29 | public String getBuildFailure() { 30 | return BUILD_FAILURE; 31 | } 32 | 33 | public String getBuildStarted() { 34 | return BUILD_STARTED; 35 | } 36 | 37 | public String getApproveOnSuccessKey() { 38 | return APPROVE_ON_SUCCESS_KEY; 39 | } 40 | } 41 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/VcsApiFactories.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs; 18 | 19 | import java.util.List; 20 | 21 | import org.springframework.beans.factory.annotation.Autowired; 22 | import org.springframework.stereotype.Component; 23 | 24 | @Component 25 | public class VcsApiFactories { 26 | @Autowired 27 | private List factories; 28 | @Autowired 29 | private VcsTypes vcsTypes; 30 | 31 | public VcsApi create(VcsPropertiesHelper vcsPropertiesHelper) { 32 | VcsType vcsType = vcsTypes.getVcsType(vcsPropertiesHelper.getVcsType()); 33 | for (VcsApiFactory factory : factories) { 34 | if (factory.handles(vcsType)) { 35 | return factory.create(vcsPropertiesHelper); 36 | } 37 | } 38 | 39 | return null; 40 | } 41 | } 42 | -------------------------------------------------------------------------------- /pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestPropertiesHelper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.pullrequest; 18 | 19 | import java.util.Map; 20 | 21 | import com.arcbees.vcs.VcsConstants; 22 | import com.arcbees.vcs.VcsPropertiesHelper; 23 | 24 | public class PullRequestPropertiesHelper extends VcsPropertiesHelper { 25 | private final Constants pullRequestConstants; 26 | 27 | public PullRequestPropertiesHelper(Map properties, 28 | VcsConstants vcsConstants, 29 | Constants pullRequestConstants) { 30 | super(properties, vcsConstants); 31 | 32 | this.pullRequestConstants = pullRequestConstants; 33 | } 34 | 35 | public boolean getApproveOnSuccessKey() { 36 | return Boolean.parseBoolean(properties.get(pullRequestConstants.getApproveOnSuccessKey())); 37 | } 38 | } 39 | -------------------------------------------------------------------------------- /staging/src/test/java/com/arcbees/vcs/util/GsonDateTypeAdapterTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.util; 18 | 19 | import java.lang.reflect.Type; 20 | 21 | import org.junit.Test; 22 | 23 | import com.google.gson.JsonDeserializationContext; 24 | import com.google.gson.JsonElement; 25 | import com.google.gson.JsonPrimitive; 26 | 27 | import static org.mockito.BDDMockito.given; 28 | import static org.mockito.Mockito.mock; 29 | 30 | public class GsonDateTypeAdapterTest { 31 | @Test 32 | public void deserialize() throws Exception { 33 | JsonElement jsonElement = mock(JsonElement.class); 34 | given(jsonElement.getAsJsonPrimitive()).willReturn(new JsonPrimitive("2015-07-29T17:31:29.962962+00:00")); 35 | GsonDateTypeAdapter typeAdapter = new GsonDateTypeAdapter(); 36 | 37 | typeAdapter.deserialize(jsonElement, mock(Type.class), mock(JsonDeserializationContext.class)); 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequestTarget.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket.model; 18 | 19 | import com.arcbees.vcs.model.Branch; 20 | import com.arcbees.vcs.model.Commit; 21 | import com.arcbees.vcs.model.PullRequestTarget; 22 | 23 | public class BitbucketPullRequestTarget implements PullRequestTarget { 24 | private BitbucketCommit commit; 25 | private BitbucketBranch branch; 26 | 27 | @Override 28 | public Commit getCommit() { 29 | return commit; 30 | } 31 | 32 | @Override 33 | public void setCommit(BitbucketCommit commit) { 34 | this.commit = commit; 35 | } 36 | 37 | @Override 38 | public Branch getBranch() { 39 | return branch; 40 | } 41 | 42 | @Override 43 | public void setBranch(BitbucketBranch branch) { 44 | this.branch = branch; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequests.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * This file is part of Stash TeamCity plugin. 5 | * 6 | * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU 7 | * General Public License as published by the Free Software Foundation, either version 3 of the License, 8 | * or (at your option) any later version. 9 | * 10 | * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, 15 | * see http://www.gnu.org/licenses/. 16 | */ 17 | 18 | package com.arcbees.vcs.stash.model; 19 | 20 | import java.util.List; 21 | 22 | import com.arcbees.vcs.model.PullRequest; 23 | import com.arcbees.vcs.model.PullRequests; 24 | import com.google.gson.annotations.SerializedName; 25 | 26 | public class StashPullRequests implements PullRequests { 27 | @SerializedName("values") 28 | private List pullRequests; 29 | 30 | @Override 31 | public List getPullRequests() { 32 | return pullRequests; 33 | } 34 | 35 | @Override 36 | public void setPullRequests(List pullRequests) { 37 | this.pullRequests = pullRequests; 38 | } 39 | } 40 | -------------------------------------------------------------------------------- /staging/pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | 8 | com.arcbees.teamcity 9 | plugins 10 | 1.0-SNAPSHOT 11 | 12 | 13 | staging 14 | 1.0-SNAPSHOT 15 | 16 | 17 | 2.2 18 | 19 | 20 | 21 | 22 | org.apache.tomcat.maven 23 | common-tomcat-maven-plugin 24 | ${tomcat.maven.version} 25 | 26 | 27 | com.arcbees.teamcity 28 | vcs-utils 29 | ${project.version} 30 | 31 | 32 | 33 | 34 | 35 | 36 | com.google.code.maven-replacer-plugin 37 | replacer 38 | 39 | 40 | maven-assembly-plugin 41 | 42 | 43 | 44 | 45 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/model/PullRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.model; 18 | 19 | import java.util.Date; 20 | import java.util.List; 21 | 22 | public interface PullRequest { 23 | String getStatus(); 24 | 25 | void setStatus(String status); 26 | 27 | String getDescription(); 28 | 29 | void setDescription(String description); 30 | 31 | String getTitle(); 32 | 33 | void setTitle(String title); 34 | 35 | int getId(); 36 | 37 | void setId(int id); 38 | 39 | Date getCreatedOn(); 40 | 41 | void setCreatedOn(Date createdOn); 42 | 43 | Date getUpdatedOn(); 44 | 45 | void setUpdatedOn(Date updatedOn); 46 | 47 | PullRequestTarget getSource(); 48 | 49 | void setSource(T source); 50 | 51 | PullRequestTarget getDestination(); 52 | 53 | void setDestination(T destination); 54 | 55 | List getBranchChain(); 56 | 57 | void setBranchChain(List chain); 58 | } 59 | -------------------------------------------------------------------------------- /staging/src/main/java/com/arcbees/staging/Constants.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.staging; 18 | 19 | public class Constants { 20 | private static final String USERNAME_KEY = "staging_username"; 21 | private static final String PASSWORD_KEY = jetbrains.buildServer.agent.Constants.SECURE_PROPERTY_PREFIX + 22 | "staging_password"; 23 | private static final String TOMCAT_URL = "staging_manager"; 24 | private static final String MERGE_BRANCH = "staging_branch"; 25 | private static final String BASE_CONTEXT = "staging_context"; 26 | 27 | public String getUserNameKey() { 28 | return USERNAME_KEY; 29 | } 30 | 31 | public String getPasswordKey() { 32 | return PASSWORD_KEY; 33 | } 34 | 35 | public String getTomcatMergeBranch() { 36 | return MERGE_BRANCH; 37 | } 38 | 39 | public String getTomcatUrl() { 40 | return TOMCAT_URL; 41 | } 42 | 43 | public String getBaseContextKey() { 44 | return BASE_CONTEXT; 45 | } 46 | } 47 | -------------------------------------------------------------------------------- /staging/src/main/java/com/arcbees/staging/StagingPropertiesHelper.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.staging; 18 | 19 | import java.util.Map; 20 | 21 | public class StagingPropertiesHelper { 22 | private final Map properties; 23 | private final Constants constants; 24 | 25 | public StagingPropertiesHelper(Map properties, 26 | Constants constants) { 27 | this.properties = properties; 28 | this.constants = constants; 29 | } 30 | 31 | public String getTomcatUrl() { 32 | return properties.get(constants.getTomcatUrl()); 33 | } 34 | 35 | public String getMergeBranch() { 36 | return properties.get(constants.getTomcatMergeBranch()); 37 | } 38 | 39 | public String getUserName() { 40 | return properties.get(constants.getUserNameKey()); 41 | } 42 | 43 | public String getPassword() { 44 | return properties.get(constants.getPasswordKey()); 45 | } 46 | 47 | public String getBaseContext() { 48 | return properties.get(constants.getBaseContextKey()); 49 | } 50 | } 51 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashComment.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * This file is part of Stash TeamCity plugin. 5 | * 6 | * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU 7 | * General Public License as published by the Free Software Foundation, either version 3 of the License, 8 | * or (at your option) any later version. 9 | * 10 | * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, 15 | * see http://www.gnu.org/licenses/. 16 | */ 17 | 18 | package com.arcbees.vcs.stash.model; 19 | 20 | import com.arcbees.vcs.model.Comment; 21 | 22 | public class StashComment implements Comment { 23 | private Long id; 24 | private String text; 25 | private String version; 26 | 27 | public StashComment() { 28 | } 29 | 30 | public StashComment(String text) { 31 | this.text = text; 32 | } 33 | 34 | @Override 35 | public Long getCommentId() { 36 | return id; 37 | } 38 | 39 | @Override 40 | public void setCommentId(Long commentId) { 41 | this.id = commentId; 42 | } 43 | 44 | public String getText() { 45 | return text; 46 | } 47 | 48 | public void setText(String text) { 49 | this.text = text; 50 | } 51 | 52 | public String getVersion() { 53 | return version; 54 | } 55 | 56 | public void setVersion(String version) { 57 | this.version = version; 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/model/GitHubPullRequestTarget.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github.model; 18 | 19 | import com.arcbees.vcs.model.Branch; 20 | import com.arcbees.vcs.model.Commit; 21 | import com.arcbees.vcs.model.PullRequestTarget; 22 | 23 | public class GitHubPullRequestTarget implements PullRequestTarget { 24 | private GitHubCommit commit; 25 | private GitHubBranch branch; 26 | 27 | // For serialization 28 | private String sha; 29 | private String ref; 30 | 31 | @Override 32 | public Commit getCommit() { 33 | if (commit == null) { 34 | setCommit(new GitHubCommit(sha)); 35 | } 36 | return commit; 37 | } 38 | 39 | @Override 40 | public void setCommit(GitHubCommit commit) { 41 | this.commit = commit; 42 | } 43 | 44 | @Override 45 | public Branch getBranch() { 46 | if (branch == null) { 47 | setBranch(new GitHubBranch(ref)); 48 | } 49 | return branch; 50 | } 51 | 52 | @Override 53 | public void setBranch(GitHubBranch branch) { 54 | this.branch = branch; 55 | } 56 | } 57 | -------------------------------------------------------------------------------- /pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestBuild.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.pullrequest; 18 | 19 | import com.arcbees.vcs.model.Comment; 20 | import com.arcbees.vcs.model.Commit; 21 | import com.arcbees.vcs.model.PullRequest; 22 | import com.arcbees.vcs.model.PullRequestTarget; 23 | 24 | import jetbrains.buildServer.messages.Status; 25 | 26 | public class PullRequestBuild { 27 | private final PullRequest pullRequest; 28 | private final Status lastStatus; 29 | private final Comment lastComment; 30 | 31 | public PullRequestBuild(PullRequest pullRequest, Status lastStatus, Comment lastComment) { 32 | this.pullRequest = pullRequest; 33 | this.lastStatus = lastStatus; 34 | this.lastComment = lastComment; 35 | } 36 | 37 | public PullRequest getPullRequest() { 38 | return pullRequest; 39 | } 40 | 41 | public Status getLastStatus() { 42 | return lastStatus; 43 | } 44 | 45 | public String getLastCommitHash() { 46 | PullRequestTarget source = pullRequest.getSource(); 47 | Commit commit = source.getCommit(); 48 | 49 | return commit.getHash(); 50 | } 51 | 52 | public Comment getLastComment() { 53 | return lastComment; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/VcsApi.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs; 18 | 19 | import java.io.IOException; 20 | 21 | import com.arcbees.vcs.model.Comment; 22 | import com.arcbees.vcs.model.CommitStatus; 23 | import com.arcbees.vcs.model.PullRequest; 24 | import com.arcbees.vcs.model.PullRequests; 25 | 26 | import jetbrains.buildServer.serverSide.SRunningBuild; 27 | 28 | public interface VcsApi { 29 | PullRequests getOpenedPullRequests() throws IOException; 30 | 31 | PullRequests getMergedPullRequests() throws IOException; 32 | 33 | Comment postComment(Integer pullRequestId, 34 | String comment) throws IOException; 35 | 36 | PullRequest getPullRequestForBranch(String branchName) throws IOException; 37 | 38 | void deleteComment(Integer pullRequestId, Long commentId) throws IOException; 39 | 40 | void updateStatus(String commitHash, String message, CommitStatus status, String targetUrl, SRunningBuild build) 41 | throws IOException, UnsupportedOperationException; 42 | 43 | void approvePullRequest(Integer pullRequestId) throws IOException, UnsupportedOperationException; 44 | 45 | void deletePullRequestApproval(Integer pullRequestId) throws IOException, UnsupportedOperationException; 46 | } 47 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/GitHubApiFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github; 18 | 19 | import com.arcbees.vcs.VcsApi; 20 | import com.arcbees.vcs.VcsApiFactory; 21 | import com.arcbees.vcs.VcsPropertiesHelper; 22 | import com.arcbees.vcs.VcsType; 23 | import com.arcbees.vcs.util.HttpClientWrapper; 24 | 25 | public class GitHubApiFactory implements VcsApiFactory { 26 | private final HttpClientWrapper httpClient; 27 | private final GitHubVcsType gitHubVcsType; 28 | 29 | public GitHubApiFactory(HttpClientWrapper httpClient, 30 | GitHubVcsType gitHubVcsType) { 31 | this.httpClient = httpClient; 32 | this.gitHubVcsType = gitHubVcsType; 33 | } 34 | 35 | @Override 36 | public boolean handles(VcsType vcsType) { 37 | return vcsType.equals(gitHubVcsType); 38 | } 39 | 40 | @Override 41 | public VcsApi create(VcsPropertiesHelper vcsPropertiesHelper) { 42 | return new GitHubApi(httpClient, new GitHubApiPaths(vcsPropertiesHelper.getServerUrl()), 43 | vcsPropertiesHelper.getUserName(), 44 | vcsPropertiesHelper.getPassword(), 45 | vcsPropertiesHelper.getRepositoryOwner(), 46 | vcsPropertiesHelper.getRepositoryName()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequestTarget.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * This file is part of Stash TeamCity plugin. 5 | * 6 | * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU 7 | * General Public License as published by the Free Software Foundation, either version 3 of the License, 8 | * or (at your option) any later version. 9 | * 10 | * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, 15 | * see http://www.gnu.org/licenses/. 16 | */ 17 | 18 | package com.arcbees.vcs.stash.model; 19 | 20 | import com.arcbees.vcs.model.Branch; 21 | import com.arcbees.vcs.model.Commit; 22 | import com.arcbees.vcs.model.PullRequestTarget; 23 | 24 | public class StashPullRequestTarget implements PullRequestTarget { 25 | private StashCommit commit; 26 | private StashBranch branch; 27 | private String latestChangeset; 28 | private String displayId; 29 | 30 | @Override 31 | public Commit getCommit() { 32 | if (commit == null) { 33 | setCommit(new StashCommit(latestChangeset)); 34 | } 35 | return commit; 36 | } 37 | 38 | @Override 39 | public void setCommit(StashCommit commit) { 40 | this.commit = commit; 41 | } 42 | 43 | @Override 44 | public Branch getBranch() { 45 | if (branch == null) { 46 | setBranch(new StashBranch(displayId)); 47 | } 48 | return branch; 49 | } 50 | 51 | @Override 52 | public void setBranch(StashBranch branch) { 53 | this.branch = branch; 54 | } 55 | } 56 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket; 18 | 19 | import com.arcbees.vcs.VcsApi; 20 | import com.arcbees.vcs.VcsApiFactory; 21 | import com.arcbees.vcs.VcsPropertiesHelper; 22 | import com.arcbees.vcs.VcsType; 23 | import com.arcbees.vcs.util.HttpClientWrapper; 24 | 25 | public class BitbucketApiFactory implements VcsApiFactory { 26 | private final HttpClientWrapper httpClient; 27 | private final BitbucketVcsType bitbucketVcsType; 28 | 29 | public BitbucketApiFactory(HttpClientWrapper httpClient, 30 | BitbucketVcsType bitbucketVcsType) { 31 | this.httpClient = httpClient; 32 | this.bitbucketVcsType = bitbucketVcsType; 33 | } 34 | 35 | @Override 36 | public boolean handles(VcsType vcsType) { 37 | return vcsType.equals(bitbucketVcsType); 38 | } 39 | 40 | @Override 41 | public VcsApi create(VcsPropertiesHelper vcsPropertiesHelper) { 42 | return new BitbucketApi(httpClient, new BitbucketApiPaths(vcsPropertiesHelper.getServerUrl()), 43 | vcsPropertiesHelper.getUserName(), 44 | vcsPropertiesHelper.getPassword(), 45 | vcsPropertiesHelper.getRepositoryOwner(), 46 | vcsPropertiesHelper.getRepositoryName()); 47 | } 48 | } 49 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/VcsPropertiesHelper.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs; 18 | 19 | import java.util.Map; 20 | 21 | public class VcsPropertiesHelper { 22 | protected final Map properties; 23 | 24 | private final VcsConstants vcsConstants; 25 | 26 | public VcsPropertiesHelper(Map properties, 27 | VcsConstants vcsConstants) { 28 | this.properties = properties; 29 | this.vcsConstants = vcsConstants; 30 | } 31 | 32 | public String getRepositoryName() { 33 | return properties.get(vcsConstants.getRepositoryNameKey()); 34 | } 35 | 36 | public String getRepositoryOwner() { 37 | return properties.get(vcsConstants.getRepositoryOwnerKey()); 38 | } 39 | 40 | public String getPassword() { 41 | return properties.get(vcsConstants.getPasswordKey()); 42 | } 43 | 44 | public String getUserName() { 45 | return properties.get(vcsConstants.getUserNameKey()); 46 | } 47 | 48 | public String getVcsType() { 49 | return properties.get(vcsConstants.getVcsType()); 50 | } 51 | 52 | public String getServerUrl() { 53 | return properties.get(vcsConstants.getServerUrl()); 54 | } 55 | 56 | public String getBaseBranch() { 57 | return properties.get(vcsConstants.getBaseBranchKey()); 58 | } 59 | } 60 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiFactory.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * This file is part of Stash TeamCity plugin. 5 | * 6 | * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU 7 | * General Public License as published by the Free Software Foundation, either version 3 of the License, 8 | * or (at your option) any later version. 9 | * 10 | * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, 15 | * see http://www.gnu.org/licenses/. 16 | */ 17 | 18 | package com.arcbees.vcs.stash; 19 | 20 | import com.arcbees.vcs.VcsApi; 21 | import com.arcbees.vcs.VcsApiFactory; 22 | import com.arcbees.vcs.VcsPropertiesHelper; 23 | import com.arcbees.vcs.VcsType; 24 | import com.arcbees.vcs.util.HttpClientWrapper; 25 | 26 | public class StashApiFactory implements VcsApiFactory { 27 | private final HttpClientWrapper httpClient; 28 | private final StashVcsType stashVcsType; 29 | 30 | public StashApiFactory(HttpClientWrapper httpClient, 31 | StashVcsType stashVcsType) { 32 | this.httpClient = httpClient; 33 | this.stashVcsType = stashVcsType; 34 | } 35 | 36 | @Override 37 | public boolean handles(VcsType vcsType) { 38 | return vcsType.equals(stashVcsType); 39 | } 40 | 41 | @Override 42 | public VcsApi create(VcsPropertiesHelper vcsPropertiesHelper) { 43 | return new StashApi(httpClient, new StashApiPaths(vcsPropertiesHelper.getServerUrl()), 44 | vcsPropertiesHelper.getUserName(), 45 | vcsPropertiesHelper.getPassword(), 46 | vcsPropertiesHelper.getRepositoryOwner(), 47 | vcsPropertiesHelper.getRepositoryName()); 48 | } 49 | } 50 | -------------------------------------------------------------------------------- /pullrequests/src/main/resources/buildServerResources/pullrequests.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="/include.jsp" %> 2 | <%@ include file="/include-internal.jsp" %> 3 | 4 | 5 | 6 | 7 | 33 | 34 | <%@ include file="vcsSettings.jsp" %> 35 | 36 | Base branch: 37 | 38 | 39 | 40 | Base VCS branch 41 | 42 | 43 | 44 | 45 | Approve on success: 46 | 47 | 48 | 49 | User should approve request on build success 50 | 51 | 52 | 53 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/VcsConstants.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs; 18 | 19 | import static jetbrains.buildServer.agent.Constants.SECURE_PROPERTY_PREFIX; 20 | 21 | public class VcsConstants { 22 | private static final String USERNAME_KEY = "vcs_username"; 23 | private static final String PASSWORD_KEY = SECURE_PROPERTY_PREFIX + "vcs_password"; 24 | private static final String SERVER_URL = "vcs_server"; 25 | private static final String REPOSITORY_KEY = "vcs_repo"; 26 | private static final String REPOSITORY_OWNER = "vcs_owner"; 27 | private static final String PULLREQUEST_KEY = "vcs_pullrequest_"; 28 | private static final String VCS_TYPE = "vcs_type"; 29 | private static final String BASE_BRANCH_KEY = "base_branch"; 30 | 31 | public String getUserNameKey() { 32 | return USERNAME_KEY; 33 | } 34 | 35 | public String getPasswordKey() { 36 | return PASSWORD_KEY; 37 | } 38 | 39 | public String getRepositoryNameKey() { 40 | return REPOSITORY_KEY; 41 | } 42 | 43 | public String getRepositoryOwnerKey() { 44 | return REPOSITORY_OWNER; 45 | } 46 | 47 | public String getServerUrl() { 48 | return SERVER_URL; 49 | } 50 | 51 | public String getPullRequestKey() { 52 | return PULLREQUEST_KEY; 53 | } 54 | 55 | public String getVcsType() { 56 | return VCS_TYPE; 57 | } 58 | 59 | public String getBaseBranchKey() { 60 | return BASE_BRANCH_KEY; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/model/GitHubCommitStatus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github.model; 18 | 19 | import com.arcbees.vcs.model.CommitStatus; 20 | import com.google.gson.annotations.SerializedName; 21 | 22 | public class GitHubCommitStatus { 23 | private CommitStatus state; 24 | @SerializedName("target_url") 25 | private String targetUrl; 26 | private String description; 27 | private String context; 28 | 29 | public GitHubCommitStatus() { 30 | } 31 | 32 | public GitHubCommitStatus(CommitStatus state, 33 | String description, 34 | String targetUrl) { 35 | this.state = state; 36 | this.description = description; 37 | this.targetUrl = targetUrl; 38 | } 39 | 40 | public CommitStatus getState() { 41 | return state; 42 | } 43 | 44 | public void setState(CommitStatus state) { 45 | this.state = state; 46 | } 47 | 48 | public String getTargetUrl() { 49 | return targetUrl; 50 | } 51 | 52 | public void setTargetUrl(String targetUrl) { 53 | this.targetUrl = targetUrl; 54 | } 55 | 56 | public String getDescription() { 57 | return description; 58 | } 59 | 60 | public void setDescription(String description) { 61 | this.description = description; 62 | } 63 | 64 | public String getContext() { 65 | return context; 66 | } 67 | 68 | public void setContext(String context) { 69 | this.context = context; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/util/GitHubPullRequestsTypeAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github.util; 18 | 19 | import java.lang.reflect.Type; 20 | import java.util.List; 21 | 22 | import com.arcbees.vcs.github.model.GitHubPullRequest; 23 | import com.arcbees.vcs.github.model.GitHubPullRequests; 24 | import com.google.common.base.Function; 25 | import com.google.common.collect.FluentIterable; 26 | import com.google.gson.JsonArray; 27 | import com.google.gson.JsonDeserializationContext; 28 | import com.google.gson.JsonDeserializer; 29 | import com.google.gson.JsonElement; 30 | import com.google.gson.JsonParseException; 31 | 32 | public class GitHubPullRequestsTypeAdapter implements JsonDeserializer { 33 | @Override 34 | public GitHubPullRequests deserialize(JsonElement json, Type typeOfT, final JsonDeserializationContext context) 35 | throws JsonParseException { 36 | JsonArray jsonArray = json.getAsJsonArray(); 37 | 38 | List pullRequests = FluentIterable.from(jsonArray) 39 | .transform(new Function() { 40 | @Override 41 | public GitHubPullRequest apply(JsonElement input) { 42 | return context.deserialize(input, GitHubPullRequest.class); 43 | } 44 | }).toImmutableList(); 45 | 46 | GitHubPullRequests gitHubPullRequests = new GitHubPullRequests(); 47 | gitHubPullRequests.setPullRequests(pullRequests); 48 | 49 | return gitHubPullRequests; 50 | } 51 | } 52 | -------------------------------------------------------------------------------- /staging/src/main/java/com/arcbees/staging/TomcatStagingDeploy.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.staging; 18 | 19 | import com.arcbees.vcs.model.Comment; 20 | import com.arcbees.vcs.model.PullRequest; 21 | 22 | public class TomcatStagingDeploy { 23 | private final PullRequest pullRequest; 24 | 25 | private Comment comment; 26 | private boolean deployed; 27 | private boolean undeployed; 28 | private String webPath; 29 | 30 | public TomcatStagingDeploy(PullRequest pullRequest, boolean deployed) { 31 | this(pullRequest, deployed, false); 32 | } 33 | 34 | public TomcatStagingDeploy(PullRequest pullRequest, boolean deployed, boolean undeployed) { 35 | this.pullRequest = pullRequest; 36 | this.deployed = deployed; 37 | this.undeployed = undeployed; 38 | } 39 | 40 | public PullRequest getPullRequest() { 41 | return pullRequest; 42 | } 43 | 44 | public boolean isUndeployed() { 45 | return undeployed; 46 | } 47 | 48 | public boolean isDeployed() { 49 | return deployed; 50 | } 51 | 52 | public void setDeployed(boolean deployed) { 53 | this.deployed = deployed; 54 | } 55 | 56 | public void setUndeployed(boolean undeployed) { 57 | this.undeployed = undeployed; 58 | } 59 | 60 | public Comment getComment() { 61 | return comment; 62 | } 63 | 64 | public void setComment(Comment comment) { 65 | this.comment = comment; 66 | } 67 | 68 | public String getWebPath() { 69 | return webPath; 70 | } 71 | 72 | public void setWebPath(String webPath) { 73 | this.webPath = webPath; 74 | } 75 | } 76 | -------------------------------------------------------------------------------- /pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestChainParser.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2015 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.pullrequest; 18 | 19 | import java.util.List; 20 | import java.util.Map; 21 | 22 | import com.arcbees.vcs.model.PullRequest; 23 | import com.arcbees.vcs.model.PullRequestTarget; 24 | import com.arcbees.vcs.model.PullRequests; 25 | import com.google.common.collect.Lists; 26 | import com.google.common.collect.Maps; 27 | 28 | public class PullRequestChainParser { 29 | public void parsePullRequestChains(PullRequests pullRequests) { 30 | Map pullRequestsMap = Maps.newHashMap(); 31 | for (PullRequest pullRequest : pullRequests.getPullRequests()) { 32 | pullRequestsMap.put(pullRequest.getSource().getBranch().getName(), pullRequest); 33 | } 34 | 35 | for (PullRequest pullRequest : pullRequestsMap.values()) { 36 | List chain = Lists.newArrayList(); 37 | 38 | PullRequestTarget destination = pullRequest.getDestination(); 39 | String branchName = destination.getBranch().getName(); 40 | chain.add(branchName); 41 | do { 42 | PullRequest destinationPullRequest = pullRequestsMap.get(branchName); 43 | if (destinationPullRequest != null) { 44 | branchName = destinationPullRequest.getDestination().getBranch().getName(); 45 | chain.add(branchName); 46 | } else { 47 | break; 48 | } 49 | } while (pullRequestsMap.containsKey(branchName)); 50 | 51 | pullRequest.setBranchChain(chain); 52 | } 53 | } 54 | } 55 | -------------------------------------------------------------------------------- /pullrequests/src/main/java/com/arcbees/feature/BuildCommitFeature.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2016 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.feature; 18 | 19 | import org.jetbrains.annotations.NotNull; 20 | import org.jetbrains.annotations.Nullable; 21 | 22 | import com.arcbees.vcs.VcsPropertiesProcessor; 23 | 24 | import jetbrains.buildServer.serverSide.BuildFeature; 25 | import jetbrains.buildServer.serverSide.PropertiesProcessor; 26 | import jetbrains.buildServer.web.openapi.PluginDescriptor; 27 | 28 | public class BuildCommitFeature extends BuildFeature { 29 | public static final String NAME = "teamcity.build.commit.status"; 30 | 31 | private static final String DISPLAY_NAME = "Report commit build status"; 32 | private static final String EDIT_URL = "feature.jsp"; 33 | 34 | private final VcsPropertiesProcessor propertiesProcessor; 35 | private final PluginDescriptor pluginDescriptor; 36 | 37 | public BuildCommitFeature( 38 | VcsPropertiesProcessor propertiesProcessor, 39 | PluginDescriptor pluginDescriptor) { 40 | this.propertiesProcessor = propertiesProcessor; 41 | this.pluginDescriptor = pluginDescriptor; 42 | } 43 | 44 | @NotNull 45 | @Override 46 | public String getType() { 47 | return NAME; 48 | } 49 | 50 | @NotNull 51 | @Override 52 | public String getDisplayName() { 53 | return DISPLAY_NAME; 54 | } 55 | 56 | @Nullable 57 | @Override 58 | public String getEditParametersUrl() { 59 | return pluginDescriptor.getPluginResourcesPath(EDIT_URL); 60 | } 61 | 62 | @Nullable 63 | @Override 64 | public PropertiesProcessor getParametersProcessor() { 65 | return propertiesProcessor; 66 | } 67 | } 68 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/util/PolymorphicTypeAdapter.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.util; 18 | 19 | import java.lang.reflect.Type; 20 | 21 | import com.google.gson.JsonDeserializationContext; 22 | import com.google.gson.JsonDeserializer; 23 | import com.google.gson.JsonElement; 24 | import com.google.gson.JsonObject; 25 | import com.google.gson.JsonParseException; 26 | import com.google.gson.JsonPrimitive; 27 | import com.google.gson.JsonSerializationContext; 28 | import com.google.gson.JsonSerializer; 29 | 30 | public class PolymorphicTypeAdapter implements JsonSerializer, JsonDeserializer { 31 | private static final String CLASSNAME = "@class"; 32 | private static final String VALUE = "@value"; 33 | 34 | @Override 35 | public T deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { 36 | JsonObject jsonObject = json.getAsJsonObject(); 37 | JsonPrimitive jsonPrimitive = (JsonPrimitive) jsonObject.get(CLASSNAME); 38 | String className = jsonPrimitive.getAsString(); 39 | 40 | Class clazz; 41 | try { 42 | clazz = Class.forName(className); 43 | } catch (ClassNotFoundException e) { 44 | throw new JsonParseException(e.getMessage()); 45 | } 46 | 47 | return context.deserialize(jsonObject.get(VALUE), clazz); 48 | } 49 | 50 | @Override 51 | public JsonElement serialize(T src, Type typeOfSrc, JsonSerializationContext context) { 52 | JsonObject retValue = new JsonObject(); 53 | 54 | String className = src.getClass().getCanonicalName(); 55 | retValue.addProperty(CLASSNAME, className); 56 | 57 | JsonElement jsonElement = context.serialize(src); 58 | retValue.add(VALUE, jsonElement); 59 | 60 | return retValue; 61 | } 62 | } 63 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/VcsPropertiesProcessor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Collection; 21 | import java.util.Map; 22 | 23 | import com.google.common.base.Strings; 24 | 25 | import jetbrains.buildServer.serverSide.InvalidProperty; 26 | import jetbrains.buildServer.serverSide.PropertiesProcessor; 27 | 28 | public class VcsPropertiesProcessor implements PropertiesProcessor { 29 | private final VcsConstants vcsConstants; 30 | 31 | public VcsPropertiesProcessor(VcsConstants vcsConstants) { 32 | this.vcsConstants = vcsConstants; 33 | } 34 | 35 | @Override 36 | public Collection process(Map properties) { 37 | Collection result = new ArrayList(); 38 | if (properties == null) return result; 39 | 40 | checkNotEmpty(properties, vcsConstants.getUserNameKey(), "Username must be specified", result); 41 | checkNotEmpty(properties, vcsConstants.getPasswordKey(), "Password must be specified", result); 42 | checkNotEmpty(properties, vcsConstants.getRepositoryOwnerKey(), "Repository owner must be specified", result); 43 | checkNotEmpty(properties, vcsConstants.getRepositoryNameKey(), "Repository name must be specified", result); 44 | 45 | return result; 46 | } 47 | 48 | private void checkNotEmpty(Map properties, 49 | String key, 50 | String message, 51 | Collection result) { 52 | if (isEmptyOrSpaces(properties.get(key))) { 53 | result.add(new InvalidProperty(key, message)); 54 | } 55 | } 56 | 57 | private boolean isEmptyOrSpaces(String value) { 58 | return Strings.nullToEmpty(value).trim().isEmpty(); 59 | } 60 | } 61 | -------------------------------------------------------------------------------- /staging/src/main/java/com/arcbees/staging/TomcatStagingPropertiesProcessor.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.staging; 18 | 19 | import java.util.ArrayList; 20 | import java.util.Collection; 21 | import java.util.Map; 22 | 23 | import com.google.common.base.Strings; 24 | 25 | import jetbrains.buildServer.serverSide.InvalidProperty; 26 | import jetbrains.buildServer.serverSide.PropertiesProcessor; 27 | 28 | public class TomcatStagingPropertiesProcessor implements PropertiesProcessor { 29 | private final Constants constants; 30 | 31 | public TomcatStagingPropertiesProcessor(Constants constants) { 32 | this.constants = constants; 33 | } 34 | 35 | @Override 36 | public Collection process(Map properties) { 37 | Collection result = new ArrayList(); 38 | if (properties == null) return result; 39 | 40 | checkNotEmpty(properties, constants.getUserNameKey(), "Username must be specified", result); 41 | checkNotEmpty(properties, constants.getPasswordKey(), "Password must be specified", result); 42 | checkNotEmpty(properties, constants.getTomcatUrl(), "Tomcat Manager URL must be specified", result); 43 | 44 | String contextPath = properties.get(constants.getBaseContextKey()); 45 | if (!Strings.isNullOrEmpty(contextPath) && !contextPath.startsWith("/")) { 46 | properties.put(constants.getBaseContextKey(), "/" + contextPath); 47 | } 48 | 49 | return result; 50 | } 51 | 52 | private void checkNotEmpty(Map properties, 53 | String key, 54 | String message, 55 | Collection result) { 56 | if (isEmptyOrSpaces(properties.get(key))) { 57 | result.add(new InvalidProperty(key, message)); 58 | } 59 | } 60 | 61 | private boolean isEmptyOrSpaces(String value) { 62 | return Strings.nullToEmpty(value).trim().isEmpty(); 63 | } 64 | } 65 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/util/GsonDateTypeAdapter.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.util; 18 | 19 | import java.lang.reflect.Type; 20 | import java.text.DateFormat; 21 | import java.text.ParseException; 22 | import java.text.SimpleDateFormat; 23 | import java.util.Date; 24 | import java.util.List; 25 | 26 | import com.google.common.collect.ImmutableList; 27 | import com.google.gson.JsonDeserializationContext; 28 | import com.google.gson.JsonDeserializer; 29 | import com.google.gson.JsonElement; 30 | import com.google.gson.JsonParseException; 31 | 32 | public class GsonDateTypeAdapter implements JsonDeserializer { 33 | private static final DateFormat DATE_TIME_FORMAT = DateFormat.getDateTimeInstance(); 34 | private static final DateFormat DATE_TIME_LONG_FORMAT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSSXXX"); 35 | private static final DateFormat DATE_TIME_LONG_FORMAT_ALT = new SimpleDateFormat("yyyy-MM-dd'T'HH:mm:ss'Z'"); 36 | private static final DateFormat DATE_TIME_LONG_FORMAT_ALT2 = new SimpleDateFormat( 37 | "yyyy-MM-dd'T'HH:mm:ss.SSSSSSXXX"); 38 | private static final DateFormat CUSTOM_DATE_FORMAT = new SimpleDateFormat("yyyy-MM-dd HH:mm:ssXXX"); 39 | private static final List dateFormats = 40 | ImmutableList.of(DATE_TIME_LONG_FORMAT_ALT2, DATE_TIME_LONG_FORMAT, DATE_TIME_FORMAT, 41 | CUSTOM_DATE_FORMAT, DATE_TIME_LONG_FORMAT_ALT); 42 | 43 | @Override 44 | public Date deserialize(JsonElement json, Type type, JsonDeserializationContext context) throws JsonParseException { 45 | String value = json.getAsJsonPrimitive().getAsString(); 46 | synchronized (dateFormats) { 47 | for (DateFormat dateFormat : dateFormats) { 48 | try { 49 | return dateFormat.parse(value); 50 | } catch (ParseException e) { 51 | } 52 | } 53 | } 54 | 55 | try { 56 | return new Date(json.getAsJsonPrimitive().getAsLong()); 57 | } catch (NumberFormatException e) { 58 | throw new JsonParseException(e); 59 | } 60 | } 61 | } 62 | -------------------------------------------------------------------------------- /pullrequests/src/test/java/com/arcbees/pullrequest/PullRequestChainParserTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2015 ArcBees Inc. 3 | *

4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | *

8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | *

10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.pullrequest; 18 | 19 | import org.junit.Before; 20 | import org.junit.Test; 21 | 22 | import com.arcbees.vcs.bitbucket.model.BitbucketBranch; 23 | import com.arcbees.vcs.bitbucket.model.BitbucketPullRequest; 24 | import com.arcbees.vcs.bitbucket.model.BitbucketPullRequestTarget; 25 | import com.arcbees.vcs.bitbucket.model.BitbucketPullRequests; 26 | 27 | import static java.util.Arrays.asList; 28 | 29 | import static org.junit.Assert.assertEquals; 30 | import static org.junit.Assert.assertTrue; 31 | 32 | public class PullRequestChainParserTest { 33 | private PullRequestChainParser parser; 34 | 35 | @Before 36 | public void setUp() { 37 | parser = new PullRequestChainParser(); 38 | } 39 | 40 | @Test 41 | public void parseChain_parseCorrectly() throws Exception { 42 | BitbucketPullRequest firstPr = createPr("a", "master"); 43 | BitbucketPullRequest secondPr = createPr("b", "a"); 44 | BitbucketPullRequests pullRequests = new BitbucketPullRequests(); 45 | pullRequests.setPullRequests(asList(secondPr, firstPr)); 46 | 47 | parser.parsePullRequestChains(pullRequests); 48 | 49 | assertEquals(1, firstPr.getBranchChain().size()); 50 | assertEquals(2, secondPr.getBranchChain().size()); 51 | assertTrue(firstPr.getBranchChain().contains("master")); 52 | assertTrue(secondPr.getBranchChain().containsAll(asList("a", "master"))); 53 | } 54 | 55 | private BitbucketPullRequest createPr(String sourceBranch, String targetBranch) { 56 | BitbucketPullRequest pullRequest = new BitbucketPullRequest(); 57 | pullRequest.setSource(createPrTarget(sourceBranch)); 58 | pullRequest.setDestination(createPrTarget(targetBranch)); 59 | 60 | return pullRequest; 61 | } 62 | 63 | private BitbucketPullRequestTarget createPrTarget(String branchName) { 64 | BitbucketPullRequestTarget target = new BitbucketPullRequestTarget(); 65 | BitbucketBranch sourceBranch = new BitbucketBranch(); 66 | sourceBranch.setName(branchName); 67 | target.setBranch(sourceBranch); 68 | 69 | return target; 70 | } 71 | } 72 | -------------------------------------------------------------------------------- /staging/src/main/java/com/arcbees/staging/TomcatStagingFeature.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.staging; 18 | 19 | import org.jetbrains.annotations.NotNull; 20 | import org.jetbrains.annotations.Nullable; 21 | 22 | import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; 23 | import jetbrains.buildServer.buildTriggers.BuildTriggerService; 24 | import jetbrains.buildServer.buildTriggers.BuildTriggeringPolicy; 25 | import jetbrains.buildServer.serverSide.PropertiesProcessor; 26 | import jetbrains.buildServer.web.openapi.PluginDescriptor; 27 | 28 | public class TomcatStagingFeature extends BuildTriggerService { 29 | public static final String NAME = "TomcatStaging"; 30 | 31 | private static final String DISPLAY_NAME = "Tomcat 7 Deploy and Staging"; 32 | private static final String EDIT_URL = "staging_deploy.jsp"; 33 | 34 | private final TomcatStagingPropertiesProcessor propertiesProcessor; 35 | private final TomcatStagingTrigger triggeringPolicy; 36 | private final PluginDescriptor pluginDescriptor; 37 | 38 | public TomcatStagingFeature(TomcatStagingTrigger triggeringPolicy, 39 | TomcatStagingPropertiesProcessor propertiesProcessor, 40 | PluginDescriptor pluginDescriptor) { 41 | this.triggeringPolicy = triggeringPolicy; 42 | this.propertiesProcessor = propertiesProcessor; 43 | this.pluginDescriptor = pluginDescriptor; 44 | } 45 | 46 | @NotNull 47 | @Override 48 | public String getName() { 49 | return NAME; 50 | } 51 | 52 | @NotNull 53 | @Override 54 | public String getDisplayName() { 55 | return DISPLAY_NAME; 56 | } 57 | 58 | @NotNull 59 | @Override 60 | public String describeTrigger(@NotNull BuildTriggerDescriptor buildTriggerDescriptor) { 61 | return DISPLAY_NAME; 62 | } 63 | 64 | @NotNull 65 | @Override 66 | public BuildTriggeringPolicy getBuildTriggeringPolicy() { 67 | return triggeringPolicy; 68 | } 69 | 70 | @Nullable 71 | @Override 72 | public String getEditParametersUrl() { 73 | return pluginDescriptor.getPluginResourcesPath(EDIT_URL); 74 | } 75 | 76 | @Nullable 77 | @Override 78 | public PropertiesProcessor getTriggerPropertiesProcessor() { 79 | return propertiesProcessor; 80 | } 81 | } 82 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketCommitStatus.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket.model; 18 | 19 | import com.arcbees.vcs.model.CommitStatus; 20 | 21 | public class BitbucketCommitStatus { 22 | public enum State { 23 | INPROGRESS, 24 | SUCCESSFUL, 25 | FAILED; 26 | 27 | public static State fromCommitSatus(CommitStatus status) { 28 | switch (status) { 29 | case ERROR: 30 | case FAILURE: 31 | return FAILED; 32 | case PENDING: 33 | return INPROGRESS; 34 | case SUCCESS: 35 | return SUCCESSFUL; 36 | } 37 | 38 | return FAILED; 39 | } 40 | } 41 | 42 | private State state; 43 | private String url; 44 | private String description; 45 | private String key; 46 | private String name; 47 | 48 | public BitbucketCommitStatus() { 49 | } 50 | 51 | public BitbucketCommitStatus( 52 | CommitStatus status, 53 | String key, 54 | String name, 55 | String description, 56 | String url) { 57 | this.key = key; 58 | this.name = name; 59 | this.state = State.fromCommitSatus(status); 60 | this.description = description; 61 | this.url = url; 62 | } 63 | 64 | public State getState() { 65 | return state; 66 | } 67 | 68 | public void setState(State state) { 69 | this.state = state; 70 | } 71 | 72 | public String getUrl() { 73 | return url; 74 | } 75 | 76 | public void setUrl(String url) { 77 | this.url = url; 78 | } 79 | 80 | public String getDescription() { 81 | return description; 82 | } 83 | 84 | public void setDescription(String description) { 85 | this.description = description; 86 | } 87 | 88 | public String getKey() { 89 | return key; 90 | } 91 | 92 | public void setKey(String key) { 93 | this.key = key; 94 | } 95 | 96 | public String getName() { 97 | return name; 98 | } 99 | 100 | public void setName(String name) { 101 | this.name = name; 102 | } 103 | } 104 | -------------------------------------------------------------------------------- /pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsFeature.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.pullrequest; 18 | 19 | import org.jetbrains.annotations.NotNull; 20 | import org.jetbrains.annotations.Nullable; 21 | 22 | import com.arcbees.vcs.VcsPropertiesProcessor; 23 | 24 | import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; 25 | import jetbrains.buildServer.buildTriggers.BuildTriggerService; 26 | import jetbrains.buildServer.buildTriggers.BuildTriggeringPolicy; 27 | import jetbrains.buildServer.serverSide.PropertiesProcessor; 28 | import jetbrains.buildServer.web.openapi.PluginDescriptor; 29 | 30 | public class PullRequestsFeature extends BuildTriggerService { 31 | public static final String NAME = "PullRequests"; 32 | 33 | private static final String DISPLAY_NAME = "Pull Requests"; 34 | private static final String EDIT_URL = "pullrequests.jsp"; 35 | 36 | private final VcsPropertiesProcessor propertiesProcessor; 37 | private final PullRequestsTrigger triggeringPolicy; 38 | private final PluginDescriptor pluginDescriptor; 39 | 40 | public PullRequestsFeature(PullRequestsTrigger triggeringPolicy, 41 | VcsPropertiesProcessor propertiesProcessor, 42 | PluginDescriptor pluginDescriptor) { 43 | this.triggeringPolicy = triggeringPolicy; 44 | this.propertiesProcessor = propertiesProcessor; 45 | this.pluginDescriptor = pluginDescriptor; 46 | } 47 | 48 | @NotNull 49 | @Override 50 | public String getName() { 51 | return NAME; 52 | } 53 | 54 | @NotNull 55 | @Override 56 | public String getDisplayName() { 57 | return DISPLAY_NAME; 58 | } 59 | 60 | @NotNull 61 | @Override 62 | public String describeTrigger(@NotNull BuildTriggerDescriptor buildTriggerDescriptor) { 63 | return DISPLAY_NAME; 64 | } 65 | 66 | @NotNull 67 | @Override 68 | public BuildTriggeringPolicy getBuildTriggeringPolicy() { 69 | return triggeringPolicy; 70 | } 71 | 72 | @Nullable 73 | @Override 74 | public String getEditParametersUrl() { 75 | return pluginDescriptor.getPluginResourcesPath(EDIT_URL); 76 | } 77 | 78 | @Nullable 79 | @Override 80 | public PropertiesProcessor getTriggerPropertiesProcessor() { 81 | return propertiesProcessor; 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashCommitStatus.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.stash.model; 18 | 19 | import com.arcbees.vcs.model.CommitStatus; 20 | 21 | public class StashCommitStatus { 22 | public static enum State { 23 | INPROGRESS, 24 | SUCCESSFUL, 25 | FAILED; 26 | 27 | public static State fromCommitSatus(CommitStatus status) { 28 | switch (status) { 29 | case ERROR: 30 | case FAILURE: 31 | return FAILED; 32 | case PENDING: 33 | return INPROGRESS; 34 | case SUCCESS: 35 | return SUCCESSFUL; 36 | } 37 | 38 | return FAILED; 39 | } 40 | } 41 | 42 | private State state; 43 | private String url; 44 | private String description; 45 | private String key; 46 | private String name; 47 | 48 | public StashCommitStatus() { 49 | } 50 | 51 | public StashCommitStatus(CommitStatus status, 52 | String key, 53 | String name, 54 | String description, 55 | String url) { 56 | this.key = key; 57 | this.name = name; 58 | this.state = State.fromCommitSatus(status); 59 | this.description = description; 60 | this.url = url; 61 | } 62 | 63 | public State getState() { 64 | return state; 65 | } 66 | 67 | public void setState(State state) { 68 | this.state = state; 69 | } 70 | 71 | public String getUrl() { 72 | return url; 73 | } 74 | 75 | public void setUrl(String url) { 76 | this.url = url; 77 | } 78 | 79 | public String getDescription() { 80 | return description; 81 | } 82 | 83 | public void setDescription(String description) { 84 | this.description = description; 85 | } 86 | 87 | public String getKey() { 88 | return key; 89 | } 90 | 91 | public void setKey(String key) { 92 | this.key = key; 93 | } 94 | 95 | public String getName() { 96 | return name; 97 | } 98 | 99 | public void setName(String name) { 100 | this.name = name; 101 | } 102 | } 103 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/util/JsonCustomDataStorage.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.util; 18 | 19 | import com.arcbees.vcs.model.Comment; 20 | import com.arcbees.vcs.model.PullRequest; 21 | import com.google.gson.Gson; 22 | import com.google.gson.GsonBuilder; 23 | import com.google.gson.JsonSyntaxException; 24 | import com.google.gson.reflect.TypeToken; 25 | 26 | import jetbrains.buildServer.serverSide.CustomDataStorage; 27 | 28 | public class JsonCustomDataStorage { 29 | public static JsonCustomDataStorage create(CustomDataStorage dataStorage, Class clazz) { 30 | return new JsonCustomDataStorage(dataStorage, clazz); 31 | } 32 | 33 | public static JsonCustomDataStorage create(CustomDataStorage dataStorage, TypeToken typeToken) { 34 | return new JsonCustomDataStorage(dataStorage, typeToken); 35 | } 36 | 37 | private final CustomDataStorage dataStorage; 38 | private final Class clazz; 39 | private final TypeToken typeToken; 40 | private final Gson gson = new GsonBuilder() 41 | .registerTypeAdapter(PullRequest.class, new PolymorphicTypeAdapter()) 42 | .registerTypeAdapter(Comment.class, new PolymorphicTypeAdapter()) 43 | .create(); 44 | 45 | private JsonCustomDataStorage(CustomDataStorage dataStorage, 46 | Class clazz) { 47 | this.dataStorage = dataStorage; 48 | this.clazz = clazz; 49 | typeToken = null; 50 | } 51 | 52 | private JsonCustomDataStorage(CustomDataStorage dataStorage, 53 | TypeToken typeToken) { 54 | this.dataStorage = dataStorage; 55 | this.typeToken = typeToken; 56 | clazz = null; 57 | } 58 | 59 | public T getValue(String key) { 60 | String value = dataStorage.getValue(key); 61 | 62 | T object; 63 | try { 64 | if (clazz != null) { 65 | object = gson.fromJson(value, clazz); 66 | } else { 67 | object = gson.fromJson(value, typeToken.getType()); 68 | } 69 | } catch (JsonSyntaxException e) { 70 | object = null; 71 | } 72 | 73 | return object; 74 | } 75 | 76 | public void putValue(String key, T object) { 77 | String value = gson.toJson(object); 78 | dataStorage.putValue(key, value); 79 | } 80 | } 81 | -------------------------------------------------------------------------------- /vcs-utils/src/main/resources/buildServerResources/vcsSettings.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="/include.jsp" %> 2 | <%@ include file="/include-internal.jsp" %> 3 | 4 | 5 | 6 | 24 | 25 | 26 | Specify VCS repository name and credentials 27 | 28 | 29 | VCS Type 30 | 31 | 32 | Bitbucket 33 | Stash 34 | GitHub 35 | 36 | 37 | 38 | 39 | API URL: 40 | 41 | 42 | 43 | API Base URL 44 | 45 | 46 | 47 | 48 | User Name: 49 | 50 | 51 | 52 | VCS user name 53 | 54 | 55 | 56 | Password: 57 | 58 | 59 | 60 | VCS password 61 | 62 | 63 | 64 | 65 | 66 | Owner: 67 | 68 | 69 | 70 | VCS repository owner (user or organization) 71 | 72 | 73 | 74 | Repository: 75 | 76 | 77 | 78 | VCS repository name 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/util/HttpClientWrapperImpl.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.util; 18 | 19 | import java.io.IOException; 20 | 21 | import org.apache.http.HttpResponse; 22 | import org.apache.http.client.HttpClient; 23 | import org.apache.http.client.config.RequestConfig; 24 | import org.apache.http.client.methods.HttpUriRequest; 25 | import org.apache.http.client.protocol.RequestAcceptEncoding; 26 | import org.apache.http.client.protocol.ResponseContentEncoding; 27 | import org.apache.http.impl.client.CloseableHttpClient; 28 | import org.apache.http.impl.client.DefaultHttpRequestRetryHandler; 29 | import org.apache.http.impl.client.HttpClientBuilder; 30 | import org.apache.http.impl.conn.PoolingHttpClientConnectionManager; 31 | 32 | import jetbrains.buildServer.version.ServerVersionHolder; 33 | 34 | public class HttpClientWrapperImpl implements HttpClientWrapper { 35 | private static final int RETRY_COUNT = 3; 36 | private static final int TIMEOUT = 30 * 1000; 37 | 38 | private final HttpClient httpClient; 39 | 40 | private PoolingHttpClientConnectionManager connectionManager; 41 | 42 | public HttpClientWrapperImpl() { 43 | httpClient = initHttpClient(); 44 | } 45 | 46 | private CloseableHttpClient initHttpClient() { 47 | RequestConfig requestConfig = getRequestConfig(); 48 | 49 | String serverVersion = ServerVersionHolder.getVersion().getDisplayVersion(); 50 | 51 | connectionManager = new PoolingHttpClientConnectionManager(); 52 | 53 | return HttpClientBuilder.create() 54 | .useSystemProperties() 55 | .addInterceptorFirst(new RequestAcceptEncoding()) 56 | .addInterceptorFirst(new ResponseContentEncoding()) 57 | .setRetryHandler(new DefaultHttpRequestRetryHandler(RETRY_COUNT, true)) 58 | .setConnectionManager(connectionManager) 59 | .setDefaultRequestConfig(requestConfig) 60 | .setUserAgent("JetBrains TeamCity " + serverVersion) 61 | .build(); 62 | } 63 | 64 | private RequestConfig getRequestConfig() { 65 | return RequestConfig.custom() 66 | .setConnectTimeout(TIMEOUT) 67 | .setSocketTimeout(TIMEOUT) 68 | .build(); 69 | } 70 | 71 | public HttpResponse execute(HttpUriRequest request) throws IOException { 72 | try { 73 | return httpClient.execute(request); 74 | } catch (IOException e) { 75 | request.abort(); 76 | throw e; 77 | } 78 | } 79 | 80 | public void shutdown() { 81 | connectionManager.shutdown(); 82 | } 83 | } 84 | -------------------------------------------------------------------------------- /staging/src/main/resources/buildServerResources/staging_deploy.jsp: -------------------------------------------------------------------------------- 1 | <%@ include file="/include.jsp" %> 2 | <%@ include file="/include-internal.jsp" %> 3 | 4 | 5 | 6 | 7 | 33 | 34 | <%@ include file="vcsSettings.jsp" %> 35 | 36 | Specify Tomcat Manager URL and credentials 37 | 38 | 39 | 40 | User Name: 41 | 42 | 43 | 44 | Manager user name 45 | 46 | 47 | 48 | Password: 49 | 50 | 51 | 52 | Manager password 53 | 54 | 55 | 56 | Manager URL: 57 | 58 | 59 | 60 | Tomcat Manager URL (ie: http://url.com/manager/text) 61 | 62 | 63 | 64 | 65 | 66 | Base Context Path: 67 | 68 | 69 | 70 | Base Context Path 71 | 72 | 73 | 74 | Undeploy Branch: 75 | 76 | 77 | 78 | Undeploy when merged into this branch 79 | 80 | 81 | 82 | -------------------------------------------------------------------------------- /staging/src/main/java/com/arcbees/staging/StagingBuildListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.staging; 18 | 19 | import java.io.IOException; 20 | import java.util.concurrent.ExecutorService; 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | import org.jetbrains.annotations.NotNull; 25 | 26 | import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; 27 | import jetbrains.buildServer.serverSide.Branch; 28 | import jetbrains.buildServer.serverSide.BuildServerAdapter; 29 | import jetbrains.buildServer.serverSide.BuildServerListener; 30 | import jetbrains.buildServer.serverSide.SBuildType; 31 | import jetbrains.buildServer.serverSide.SRunningBuild; 32 | import jetbrains.buildServer.serverSide.executors.ExecutorServices; 33 | import jetbrains.buildServer.util.EventDispatcher; 34 | import jetbrains.buildServer.util.ExceptionUtil; 35 | 36 | public class StagingBuildListener { 37 | private static final Logger LOGGER = Logger.getLogger(StagingBuildListener.class.getName()); 38 | 39 | private final TomcatDeployHandler deployHandler; 40 | private final ExecutorService executorService; 41 | 42 | public StagingBuildListener(EventDispatcher listener, 43 | ExecutorServices executorServices, 44 | TomcatDeployHandler deployHandler) { 45 | this.deployHandler = deployHandler; 46 | executorService = executorServices.getLowPriorityExecutorService(); 47 | 48 | listener.addListener(new BuildServerAdapter() { 49 | @Override 50 | public void buildFinished(@NotNull SRunningBuild build) { 51 | onBuildFinished(build); 52 | } 53 | }); 54 | } 55 | 56 | private void onBuildFinished(final SRunningBuild build) { 57 | SBuildType buildType = build.getBuildType(); 58 | if (buildType == null) { 59 | return; 60 | } 61 | 62 | for (final BuildTriggerDescriptor trigger : buildType.getResolvedSettings().getBuildTriggersCollection()) { 63 | if (!trigger.getType().equals(TomcatStagingFeature.NAME)) { 64 | continue; 65 | } 66 | 67 | Branch branch = build.getBranch(); 68 | if (branch != null) { 69 | handleDeploy(build, trigger); 70 | } else { 71 | LOGGER.severe("Unknown branch name"); 72 | } 73 | } 74 | } 75 | 76 | private void handleDeploy(final SRunningBuild build, final BuildTriggerDescriptor trigger) { 77 | executorService.submit(ExceptionUtil.catchAll("Tomcat7 Deploy", new Runnable() { 78 | @Override 79 | public void run() { 80 | try { 81 | deployHandler.handle(build, trigger); 82 | } catch (IOException e) { 83 | LOGGER.log(Level.SEVERE, "Error getting pull request infos", e); 84 | } 85 | } 86 | })); 87 | } 88 | } 89 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/GitHubApiPaths.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github; 18 | 19 | public class GitHubApiPaths { 20 | private static final String REPOSITORIES = "/repos/"; 21 | private static final String PULLREQUESTS = "/pulls"; 22 | private static final String COMMENTS = "/comments"; 23 | private static final String SLASH = "/"; 24 | private static final String STATE_MERGED = "?state=closed"; 25 | private static final String STATUSES = "/statuses/"; 26 | private static final String ISSUES = "/issues"; 27 | 28 | private final String baseUrl; 29 | 30 | public GitHubApiPaths(String baseUrl) { 31 | if (baseUrl.endsWith("/")) { 32 | baseUrl = baseUrl.substring(0, baseUrl.length() - 1); 33 | } 34 | 35 | this.baseUrl = baseUrl; 36 | } 37 | 38 | public String getOpenedPullRequests(String repositoryOwner, 39 | String repositoryName) { 40 | return getPullRequests(repositoryOwner, repositoryName); 41 | } 42 | 43 | public String getMergedPullRequests(String repositoryOwner, String repositoryName) { 44 | return getPullRequests(repositoryOwner, repositoryName) + STATE_MERGED; 45 | } 46 | 47 | public String getPullRequest(String repositoryOwner, 48 | String repositoryName, 49 | Integer pullRequestId) { 50 | return baseUrl + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId); 51 | } 52 | 53 | public String addComment(String repositoryOwner, 54 | String repositoryName, 55 | Integer pullRequestId) { 56 | return baseUrl + pathToIssues(repositoryOwner, repositoryName, pullRequestId) + COMMENTS; 57 | } 58 | 59 | public String deleteComment(String repositoryOwner, 60 | String repositoryName, 61 | Integer pullRequestId, 62 | Long commentId) { 63 | return baseUrl + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId) 64 | + COMMENTS + SLASH + commentId; 65 | } 66 | 67 | public String updateStatus(String repositoryOwner, String repositoryName, String commitHash) { 68 | return baseUrl + REPOSITORIES + repositoryOwner + SLASH + repositoryName + STATUSES + commitHash; 69 | } 70 | 71 | private String getPullRequests(String repositoryOwner, String repositoryName) { 72 | return baseUrl + REPOSITORIES + repositoryOwner + SLASH + repositoryName + PULLREQUESTS; 73 | } 74 | 75 | private String pathToPullRequest(String repositoryOwner, String repositoryName, Integer pullRequestId) { 76 | return REPOSITORIES + repositoryOwner + SLASH + repositoryName + PULLREQUESTS + SLASH + pullRequestId; 77 | } 78 | 79 | private String pathToIssues(String repositoryOwner, String repositoryName, Integer pullRequestId) { 80 | return REPOSITORIES + repositoryOwner + SLASH + repositoryName + ISSUES + SLASH + pullRequestId; 81 | } 82 | } 83 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/model/GitHubPullRequest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github.model; 18 | 19 | import java.util.Date; 20 | import java.util.List; 21 | 22 | import com.arcbees.vcs.model.PullRequest; 23 | import com.arcbees.vcs.model.PullRequestTarget; 24 | import com.google.common.collect.Lists; 25 | import com.google.gson.annotations.Expose; 26 | import com.google.gson.annotations.SerializedName; 27 | 28 | public class GitHubPullRequest implements PullRequest { 29 | private String state; 30 | private String body; 31 | private String title; 32 | private int number; 33 | @SerializedName("created_at") 34 | private Date createdOn; 35 | @SerializedName("updated_at") 36 | private Date updatedOn; 37 | private GitHubPullRequestTarget head; 38 | private GitHubPullRequestTarget base; 39 | @Expose(serialize = false, deserialize = false) 40 | private List branchChain = Lists.newArrayList(); 41 | 42 | @Override 43 | public String getStatus() { 44 | return state; 45 | } 46 | 47 | @Override 48 | public void setStatus(String status) { 49 | this.state = status; 50 | } 51 | 52 | @Override 53 | public String getDescription() { 54 | return body; 55 | } 56 | 57 | @Override 58 | public void setDescription(String description) { 59 | this.body = description; 60 | } 61 | 62 | @Override 63 | public String getTitle() { 64 | return title; 65 | } 66 | 67 | @Override 68 | public void setTitle(String title) { 69 | this.title = title; 70 | } 71 | 72 | @Override 73 | public int getId() { 74 | return number; 75 | } 76 | 77 | @Override 78 | public void setId(int id) { 79 | this.number = id; 80 | } 81 | 82 | @Override 83 | public Date getCreatedOn() { 84 | return createdOn; 85 | } 86 | 87 | @Override 88 | public void setCreatedOn(Date createdOn) { 89 | this.createdOn = createdOn; 90 | } 91 | 92 | @Override 93 | public Date getUpdatedOn() { 94 | return updatedOn; 95 | } 96 | 97 | @Override 98 | public void setUpdatedOn(Date updatedOn) { 99 | this.updatedOn = updatedOn; 100 | } 101 | 102 | @Override 103 | public PullRequestTarget getSource() { 104 | return head; 105 | } 106 | 107 | @Override 108 | public void setSource(GitHubPullRequestTarget source) { 109 | this.head = source; 110 | } 111 | 112 | @Override 113 | public PullRequestTarget getDestination() { 114 | return base; 115 | } 116 | 117 | @Override 118 | public void setDestination(GitHubPullRequestTarget destination) { 119 | this.base = destination; 120 | } 121 | 122 | @Override 123 | public List getBranchChain() { 124 | return branchChain; 125 | } 126 | 127 | @Override 128 | public void setBranchChain(List chain) { 129 | branchChain.clear(); 130 | if (chain != null) { 131 | branchChain.addAll(chain); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/model/StashPullRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * This file is part of Stash TeamCity plugin. 5 | * 6 | * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU 7 | * General Public License as published by the Free Software Foundation, either version 3 of the License, 8 | * or (at your option) any later version. 9 | * 10 | * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, 15 | * see http://www.gnu.org/licenses/. 16 | */ 17 | 18 | package com.arcbees.vcs.stash.model; 19 | 20 | import java.util.Date; 21 | import java.util.List; 22 | 23 | import com.arcbees.vcs.model.PullRequest; 24 | import com.arcbees.vcs.model.PullRequestTarget; 25 | import com.google.common.collect.Lists; 26 | import com.google.gson.annotations.Expose; 27 | 28 | public class StashPullRequest implements PullRequest { 29 | private String state; 30 | private String description; 31 | private String title; 32 | private int id; 33 | private Date createdDate; 34 | private Date updatedDate; 35 | private StashPullRequestTarget fromRef; 36 | private StashPullRequestTarget toRef; 37 | @Expose(serialize = false, deserialize = false) 38 | private List branchChain = Lists.newArrayList(); 39 | 40 | @Override 41 | public String getStatus() { 42 | return state; 43 | } 44 | 45 | @Override 46 | public void setStatus(String status) { 47 | this.state = status; 48 | } 49 | 50 | @Override 51 | public String getDescription() { 52 | return description; 53 | } 54 | 55 | @Override 56 | public void setDescription(String description) { 57 | this.description = description; 58 | } 59 | 60 | @Override 61 | public String getTitle() { 62 | return title; 63 | } 64 | 65 | @Override 66 | public void setTitle(String title) { 67 | this.title = title; 68 | } 69 | 70 | @Override 71 | public int getId() { 72 | return id; 73 | } 74 | 75 | @Override 76 | public void setId(int id) { 77 | this.id = id; 78 | } 79 | 80 | @Override 81 | public Date getCreatedOn() { 82 | return createdDate; 83 | } 84 | 85 | @Override 86 | public void setCreatedOn(Date createdOn) { 87 | this.createdDate = createdOn; 88 | } 89 | 90 | @Override 91 | public Date getUpdatedOn() { 92 | return updatedDate; 93 | } 94 | 95 | @Override 96 | public void setUpdatedOn(Date updatedOn) { 97 | this.updatedDate = updatedOn; 98 | } 99 | 100 | @Override 101 | public PullRequestTarget getSource() { 102 | return fromRef; 103 | } 104 | 105 | @Override 106 | public void setSource(StashPullRequestTarget source) { 107 | this.fromRef = source; 108 | } 109 | 110 | @Override 111 | public PullRequestTarget getDestination() { 112 | return toRef; 113 | } 114 | 115 | @Override 116 | public void setDestination(StashPullRequestTarget destination) { 117 | this.toRef = destination; 118 | } 119 | 120 | @Override 121 | public List getBranchChain() { 122 | return branchChain; 123 | } 124 | 125 | @Override 126 | public void setBranchChain(List chain) { 127 | branchChain.clear(); 128 | if (chain != null) { 129 | branchChain.addAll(chain); 130 | } 131 | } 132 | } 133 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/model/BitbucketPullRequest.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket.model; 18 | 19 | import java.util.Date; 20 | import java.util.List; 21 | 22 | import com.arcbees.vcs.model.PullRequest; 23 | import com.arcbees.vcs.model.PullRequestTarget; 24 | import com.google.common.collect.Lists; 25 | import com.google.gson.annotations.Expose; 26 | import com.google.gson.annotations.SerializedName; 27 | 28 | public class BitbucketPullRequest implements PullRequest { 29 | private String status; 30 | private String description; 31 | private String title; 32 | private int id; 33 | @SerializedName("created_on") 34 | private Date createdOn; 35 | @SerializedName("updated_on") 36 | private Date updatedOn; 37 | private BitbucketPullRequestTarget source; 38 | private BitbucketPullRequestTarget destination; 39 | @Expose(serialize = false, deserialize = false) 40 | private List branchChain = Lists.newArrayList(); 41 | 42 | @Override 43 | public String getStatus() { 44 | return status; 45 | } 46 | 47 | @Override 48 | public void setStatus(String status) { 49 | this.status = status; 50 | } 51 | 52 | @Override 53 | public String getDescription() { 54 | return description; 55 | } 56 | 57 | @Override 58 | public void setDescription(String description) { 59 | this.description = description; 60 | } 61 | 62 | @Override 63 | public String getTitle() { 64 | return title; 65 | } 66 | 67 | @Override 68 | public void setTitle(String title) { 69 | this.title = title; 70 | } 71 | 72 | @Override 73 | public int getId() { 74 | return id; 75 | } 76 | 77 | @Override 78 | public void setId(int id) { 79 | this.id = id; 80 | } 81 | 82 | @Override 83 | public Date getCreatedOn() { 84 | return createdOn; 85 | } 86 | 87 | @Override 88 | public void setCreatedOn(Date createdOn) { 89 | this.createdOn = createdOn; 90 | } 91 | 92 | @Override 93 | public Date getUpdatedOn() { 94 | return updatedOn; 95 | } 96 | 97 | @Override 98 | public void setUpdatedOn(Date updatedOn) { 99 | this.updatedOn = updatedOn; 100 | } 101 | 102 | @Override 103 | public PullRequestTarget getSource() { 104 | return source; 105 | } 106 | 107 | @Override 108 | public void setSource(BitbucketPullRequestTarget source) { 109 | this.source = source; 110 | } 111 | 112 | @Override 113 | public PullRequestTarget getDestination() { 114 | return destination; 115 | } 116 | 117 | @Override 118 | public void setDestination(BitbucketPullRequestTarget destination) { 119 | this.destination = destination; 120 | } 121 | 122 | @Override 123 | public List getBranchChain() { 124 | return branchChain; 125 | } 126 | 127 | @Override 128 | public void setBranchChain(List chain) { 129 | branchChain.clear(); 130 | if (chain != null) { 131 | branchChain.addAll(chain); 132 | } 133 | } 134 | } 135 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApiPaths.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket; 18 | 19 | public class BitbucketApiPaths { 20 | private static final String API_2 = "/2.0/"; 21 | private static final String API_1 = "/1.0/"; 22 | private static final String REPOSITORIES = "repositories/"; 23 | private static final String PULLREQUESTS = "/pullrequests/"; 24 | private static final String COMMENTS = "/comments"; 25 | private static final String COMMIT = "/commit"; 26 | private static final String STATUS = "/statuses/build"; 27 | private static final String APPROVE = "/approve"; 28 | private static final String SLASH = "/"; 29 | private static final String STATE_MERGED = "?state=MERGED"; 30 | 31 | private final String baseUrl; 32 | 33 | public BitbucketApiPaths(String baseUrl) { 34 | if (baseUrl.endsWith("/")) { 35 | baseUrl = baseUrl.substring(0, baseUrl.length() - 1); 36 | } 37 | 38 | this.baseUrl = baseUrl; 39 | } 40 | 41 | public String getOpenedPullRequests(String repositoryOwner, 42 | String repositoryName) { 43 | return getPullRequests(repositoryOwner, repositoryName); 44 | } 45 | 46 | public String getMergedPullRequests(String repositoryOwner, String repositoryName) { 47 | return getPullRequests(repositoryOwner, repositoryName) + STATE_MERGED; 48 | } 49 | 50 | public String getPullRequest(String repositoryOwner, 51 | String repositoryName, 52 | Integer pullRequestId) { 53 | return baseUrl + API_2 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId); 54 | } 55 | 56 | public String updateStatus(String repositoryOwner, 57 | String repositoryName, 58 | String commitHash) { 59 | return baseUrl + API_2 + REPOSITORIES + repositoryOwner + SLASH + repositoryName + COMMIT + SLASH + commitHash + STATUS; 60 | } 61 | 62 | public String addComment(String repositoryOwner, 63 | String repositoryName, 64 | Integer pullRequestId) { 65 | return baseUrl + API_1 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId) + COMMENTS; 66 | } 67 | 68 | public String deleteComment(String repositoryOwner, 69 | String repositoryName, 70 | Integer pullRequestId, 71 | Long commentId) { 72 | return baseUrl + API_1 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId) 73 | + COMMENTS + SLASH + commentId; 74 | } 75 | 76 | private String getPullRequests(String repositoryOwner, String repositoryName) { 77 | return baseUrl + API_2 + REPOSITORIES + repositoryOwner + SLASH + repositoryName + PULLREQUESTS; 78 | } 79 | 80 | private String pathToPullRequest(String repositoryOwner, String repositoryName, Integer pullRequestId) { 81 | return REPOSITORIES + repositoryOwner + SLASH + repositoryName + PULLREQUESTS + pullRequestId; 82 | } 83 | 84 | public String approvePullRequest(String repositoryOwner, String repositoryName, Integer pullRequestId) { 85 | return baseUrl + API_2 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId) + APPROVE; 86 | } 87 | } 88 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApiPaths.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * This file is part of Stash TeamCity plugin. 5 | * 6 | * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU 7 | * General Public License as published by the Free Software Foundation, either version 3 of the License, 8 | * or (at your option) any later version. 9 | * 10 | * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, 15 | * see http://www.gnu.org/licenses/. 16 | */ 17 | 18 | package com.arcbees.vcs.stash; 19 | 20 | public class StashApiPaths { 21 | private static final String API_1 = "/rest/api/1.0/projects/"; 22 | private static final String BUILD_STATUS = "/rest/build-status/1.0"; 23 | private static final String BUILD_STATUS_COMMITS = BUILD_STATUS + "/commits/"; 24 | private static final String REPOSITORIES = "repos/"; 25 | private static final String PULLREQUESTS = "/pull-requests/"; 26 | private static final String COMMENTS = "/comments"; 27 | private static final String APPROVE = "/approve"; 28 | private static final String SLASH = "/"; 29 | private static final String STATE_MERGED = "?state=MERGED"; 30 | 31 | private final String baseUrl; 32 | 33 | public StashApiPaths(String baseUrl) { 34 | if (baseUrl.endsWith("/")) { 35 | baseUrl = baseUrl.substring(0, baseUrl.length() - 1); 36 | } 37 | 38 | this.baseUrl = baseUrl; 39 | } 40 | 41 | public String getOpenedPullRequests(String repositoryOwner, 42 | String repositoryName) { 43 | return getPullRequests(repositoryOwner, repositoryName); 44 | } 45 | 46 | public String getMergedPullRequests(String repositoryOwner, String repositoryName) { 47 | return getPullRequests(repositoryOwner, repositoryName) + STATE_MERGED; 48 | } 49 | 50 | public String getPullRequest(String repositoryOwner, 51 | String repositoryName, 52 | Integer pullRequestId) { 53 | return baseUrl + API_1 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId); 54 | } 55 | 56 | public String addComment(String repositoryOwner, 57 | String repositoryName, 58 | Integer pullRequestId) { 59 | return baseUrl + API_1 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId) + COMMENTS; 60 | } 61 | 62 | public String pullRequestComment(String repositoryOwner, 63 | String repositoryName, 64 | Integer pullRequestId, 65 | Long commentId) { 66 | return baseUrl + API_1 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId) 67 | + COMMENTS + SLASH + commentId; 68 | } 69 | 70 | public String updateStatus(String commitHash) { 71 | return baseUrl + BUILD_STATUS_COMMITS + commitHash; 72 | } 73 | 74 | public String approvePullRequest(String repositoryOwner, String repositoryName, Integer pullRequestId) { 75 | return baseUrl + API_1 + pathToPullRequest(repositoryOwner, repositoryName, pullRequestId) + APPROVE; 76 | } 77 | 78 | private String getPullRequests(String repositoryOwner, String repositoryName) { 79 | return baseUrl + API_1 + repositoryOwner + SLASH + REPOSITORIES + repositoryName + PULLREQUESTS; 80 | } 81 | 82 | private String pathToPullRequest(String repositoryOwner, String repositoryName, Integer pullRequestId) { 83 | return repositoryOwner + SLASH + REPOSITORIES + repositoryName + PULLREQUESTS + pullRequestId; 84 | } 85 | } 86 | -------------------------------------------------------------------------------- /pullrequests/src/main/java/com/arcbees/feature/BuildCommitBuildListener.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.feature; 18 | 19 | import java.io.IOException; 20 | import java.util.concurrent.ExecutorService; 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | import org.jetbrains.annotations.NotNull; 25 | 26 | import com.arcbees.pullrequest.BuildStatus; 27 | 28 | import jetbrains.buildServer.serverSide.Branch; 29 | import jetbrains.buildServer.serverSide.BuildServerAdapter; 30 | import jetbrains.buildServer.serverSide.BuildServerListener; 31 | import jetbrains.buildServer.serverSide.SBuildFeatureDescriptor; 32 | import jetbrains.buildServer.serverSide.SBuildType; 33 | import jetbrains.buildServer.serverSide.SRunningBuild; 34 | import jetbrains.buildServer.serverSide.executors.ExecutorServices; 35 | import jetbrains.buildServer.util.EventDispatcher; 36 | import jetbrains.buildServer.util.ExceptionUtil; 37 | 38 | public class BuildCommitBuildListener { 39 | private static final Logger LOGGER = Logger.getLogger(BuildCommitBuildListener.class.getName()); 40 | 41 | private final BuildCommitStatusHandler statusHandler; 42 | private final ExecutorService executorService; 43 | 44 | public BuildCommitBuildListener( 45 | EventDispatcher listener, 46 | ExecutorServices executorServices, 47 | BuildCommitStatusHandler statusHandler) { 48 | this.statusHandler = statusHandler; 49 | executorService = executorServices.getLowPriorityExecutorService(); 50 | 51 | listener.addListener(new BuildServerAdapter() { 52 | @Override 53 | public void changesLoaded(@NotNull SRunningBuild build) { 54 | onBuildStatusChanged(build, BuildStatus.STARTING); 55 | } 56 | 57 | @Override 58 | public void buildInterrupted(@NotNull SRunningBuild build) { 59 | onBuildStatusChanged(build, BuildStatus.INTERRUPTED); 60 | } 61 | 62 | @Override 63 | public void buildFinished(@NotNull SRunningBuild build) { 64 | onBuildStatusChanged(build, BuildStatus.FINISHED); 65 | } 66 | }); 67 | } 68 | 69 | private void onBuildStatusChanged( 70 | SRunningBuild build, 71 | BuildStatus buildStatus) { 72 | SBuildFeatureDescriptor feature = getFeature(build); 73 | 74 | if (feature != null) { 75 | Branch branch = build.getBranch(); 76 | if (branch != null) { 77 | handleBuildStatus(build, buildStatus, feature); 78 | } else { 79 | LOGGER.severe("Unknown branch name"); 80 | } 81 | } 82 | } 83 | 84 | private void handleBuildStatus( 85 | final SRunningBuild build, 86 | final BuildStatus buildStatus, 87 | final SBuildFeatureDescriptor feature) { 88 | executorService.submit(ExceptionUtil.catchAll("BuildCommitStatus Handler", new Runnable() { 89 | @Override 90 | public void run() { 91 | try { 92 | statusHandler.handle(build, feature, buildStatus); 93 | } catch (IOException e) { 94 | LOGGER.log(Level.SEVERE, "Error updating commit status.", e); 95 | } 96 | } 97 | })); 98 | } 99 | 100 | private SBuildFeatureDescriptor getFeature(SRunningBuild build) { 101 | SBuildType buildType = build.getBuildType(); 102 | if (buildType == null) { 103 | return null; 104 | } 105 | 106 | for (SBuildFeatureDescriptor feature : buildType.getResolvedSettings().getBuildFeatures()) { 107 | if (BuildCommitFeature.NAME.equals(feature.getType())) { 108 | return feature; 109 | } 110 | } 111 | 112 | return null; 113 | } 114 | } 115 | -------------------------------------------------------------------------------- /pullrequests/src/main/java/com/arcbees/pullrequest/PullRequestsBuildListener.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.pullrequest; 18 | 19 | import java.io.IOException; 20 | import java.util.concurrent.ExecutorService; 21 | import java.util.logging.Level; 22 | import java.util.logging.Logger; 23 | 24 | import org.jetbrains.annotations.NotNull; 25 | 26 | import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; 27 | import jetbrains.buildServer.serverSide.Branch; 28 | import jetbrains.buildServer.serverSide.BuildServerAdapter; 29 | import jetbrains.buildServer.serverSide.BuildServerListener; 30 | import jetbrains.buildServer.serverSide.SBuildType; 31 | import jetbrains.buildServer.serverSide.SRunningBuild; 32 | import jetbrains.buildServer.serverSide.executors.ExecutorServices; 33 | import jetbrains.buildServer.util.EventDispatcher; 34 | import jetbrains.buildServer.util.ExceptionUtil; 35 | 36 | public class PullRequestsBuildListener { 37 | private static final Logger LOGGER = Logger.getLogger(PullRequestsBuildListener.class.getName()); 38 | 39 | private final PullRequestStatusHandler statusHandler; 40 | private final ExecutorService executorService; 41 | 42 | public PullRequestsBuildListener(EventDispatcher listener, 43 | ExecutorServices executorServices, 44 | PullRequestStatusHandler statusHandler) { 45 | this.statusHandler = statusHandler; 46 | executorService = executorServices.getLowPriorityExecutorService(); 47 | 48 | listener.addListener(new BuildServerAdapter() { 49 | @Override 50 | public void buildStarted(@NotNull SRunningBuild build) { 51 | onBuildStatusChanged(build, BuildStatus.STARTING); 52 | } 53 | 54 | @Override 55 | public void buildInterrupted(@NotNull SRunningBuild build) { 56 | onBuildStatusChanged(build, BuildStatus.INTERRUPTED); 57 | } 58 | 59 | @Override 60 | public void buildFinished(@NotNull SRunningBuild build) { 61 | onBuildStatusChanged(build, BuildStatus.FINISHED); 62 | } 63 | }); 64 | } 65 | 66 | private void onBuildStatusChanged(final SRunningBuild build, 67 | final BuildStatus buildStatus) { 68 | final BuildTriggerDescriptor trigger = getTrigger(build); 69 | 70 | if (trigger != null) { 71 | Branch branch = build.getBranch(); 72 | if (branch != null) { 73 | handleBuildStatus(build, buildStatus, trigger); 74 | } else { 75 | LOGGER.severe("Unknown branch name"); 76 | } 77 | } 78 | } 79 | 80 | private void handleBuildStatus(final SRunningBuild build, 81 | final BuildStatus buildStatus, 82 | final BuildTriggerDescriptor trigger) { 83 | executorService.submit(ExceptionUtil.catchAll("PullRequest Handler", new Runnable() { 84 | @Override 85 | public void run() { 86 | try { 87 | statusHandler.handle(build, trigger, buildStatus); 88 | } catch (IOException e) { 89 | LOGGER.log(Level.SEVERE, "Error updating pull request status.", e); 90 | } 91 | } 92 | })); 93 | } 94 | 95 | private BuildTriggerDescriptor getTrigger(SRunningBuild build) { 96 | SBuildType buildType = build.getBuildType(); 97 | if (buildType == null) { 98 | return null; 99 | } 100 | 101 | for (BuildTriggerDescriptor trigger : buildType.getResolvedSettings().getBuildTriggersCollection()) { 102 | if (trigger.getType().equals(PullRequestsFeature.NAME)) { 103 | return trigger; 104 | } 105 | } 106 | 107 | return null; 108 | } 109 | } 110 | -------------------------------------------------------------------------------- /pullrequests/src/main/java/com/arcbees/feature/BuildCommitStatusHandler.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2016 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.feature; 18 | 19 | import java.io.IOException; 20 | import java.util.ArrayList; 21 | import java.util.List; 22 | import java.util.logging.Level; 23 | import java.util.logging.Logger; 24 | 25 | import com.arcbees.pullrequest.BuildStatus; 26 | import com.arcbees.pullrequest.Constants; 27 | import com.arcbees.vcs.VcsApi; 28 | import com.arcbees.vcs.VcsApiFactories; 29 | import com.arcbees.vcs.VcsConstants; 30 | import com.arcbees.vcs.VcsPropertiesHelper; 31 | import com.arcbees.vcs.model.CommitStatus; 32 | import com.google.common.base.Strings; 33 | 34 | import jetbrains.buildServer.messages.Status; 35 | import jetbrains.buildServer.serverSide.Branch; 36 | import jetbrains.buildServer.serverSide.BuildRevision; 37 | import jetbrains.buildServer.serverSide.SBuildFeatureDescriptor; 38 | import jetbrains.buildServer.serverSide.SRunningBuild; 39 | import jetbrains.buildServer.serverSide.WebLinks; 40 | 41 | public class BuildCommitStatusHandler { 42 | private static final Logger LOGGER = Logger.getLogger(BuildCommitStatusHandler.class.getName()); 43 | 44 | private final VcsApiFactories vcsApiFactories; 45 | private final VcsConstants vcsConstants; 46 | private final Constants constants; 47 | private final WebLinks webLinks; 48 | 49 | public BuildCommitStatusHandler(VcsApiFactories vcsApiFactories, 50 | VcsConstants vcsConstants, 51 | Constants constants, 52 | WebLinks webLinks) { 53 | this.vcsApiFactories = vcsApiFactories; 54 | this.vcsConstants = vcsConstants; 55 | this.constants = constants; 56 | this.webLinks = webLinks; 57 | } 58 | 59 | public void handle(SRunningBuild build, SBuildFeatureDescriptor feature, BuildStatus buildStatus) 60 | throws IOException { 61 | LOGGER.log(Level.INFO, "Handling build status - Build Status: {0}, Branch: {1}, isSuccessful: {2}", 62 | new Object[]{buildStatus, build.getBranch() == null ? null : build.getBranch().getName(), 63 | build.getBuildStatus().isSuccessful()}); 64 | 65 | Branch branch = build.getBranch(); 66 | if (branch != null) { 67 | VcsPropertiesHelper vcsPropertiesHelper = 68 | new VcsPropertiesHelper(feature.getParameters(), vcsConstants); 69 | VcsApi vcsApi = vcsApiFactories.create(vcsPropertiesHelper); 70 | 71 | CommitStatus commitStatus = getCommitStatus(build.getBuildStatus(), buildStatus); 72 | 73 | updateStatus(build, vcsApi, commitStatus); 74 | } 75 | } 76 | 77 | private CommitStatus getCommitStatus(Status status, BuildStatus buildStatus) { 78 | switch (buildStatus) { 79 | case STARTING: 80 | return CommitStatus.PENDING; 81 | case FINISHED: 82 | if (status.isSuccessful()) { 83 | return CommitStatus.SUCCESS; 84 | } else { 85 | return CommitStatus.FAILURE; 86 | } 87 | default: 88 | return CommitStatus.ERROR; 89 | } 90 | } 91 | 92 | private void updateStatus( 93 | SRunningBuild build, 94 | VcsApi vcsApi, 95 | CommitStatus commitStatus) throws IOException { 96 | try { 97 | String statusMessage = getStatusMessage(build, commitStatus); 98 | 99 | List changes = getSourceCommitsHashes(build); 100 | for (BuildRevision change : changes) { 101 | String version = change.getRepositoryVersion().getVersion(); 102 | vcsApi.updateStatus(version, statusMessage, commitStatus, getTargetUrl(build), build); 103 | } 104 | } catch (UnsupportedOperationException e) { 105 | // Shouldn't happen 106 | } 107 | } 108 | 109 | private String getStatusMessage( 110 | SRunningBuild build, 111 | CommitStatus commitStatus) { 112 | switch (commitStatus) { 113 | case ERROR: 114 | case FAILURE: 115 | case SUCCESS: 116 | String buildDescription = Strings.nullToEmpty(build.getStatusDescriptor().getText()); 117 | 118 | if (!buildDescription.isEmpty()) { 119 | buildDescription = " : " + buildDescription; 120 | } 121 | 122 | return build.getFullName() + buildDescription; 123 | case PENDING: 124 | return constants.getBuildStarted() + build.getFullName(); 125 | default: 126 | return ""; 127 | } 128 | } 129 | 130 | private String getTargetUrl(SRunningBuild build) { 131 | return webLinks.getViewResultsUrl(build); 132 | } 133 | 134 | private List getSourceCommitsHashes(SRunningBuild build) { 135 | List result = new ArrayList<>(); 136 | for (BuildRevision rev : build.getRevisions()) { 137 | if ("jetbrains.git".equals(rev.getRoot().getVcsName())) { 138 | result.add(rev); 139 | } 140 | } 141 | 142 | return result; 143 | } 144 | } 145 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/AbstractVcsApi.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs; 18 | 19 | import java.io.ByteArrayOutputStream; 20 | import java.io.IOException; 21 | import java.net.HttpURLConnection; 22 | 23 | import org.apache.commons.codec.CharEncoding; 24 | import org.apache.http.HttpEntity; 25 | import org.apache.http.HttpHeaders; 26 | import org.apache.http.HttpRequest; 27 | import org.apache.http.HttpResponse; 28 | import org.apache.http.auth.AuthenticationException; 29 | import org.apache.http.auth.Credentials; 30 | import org.apache.http.client.methods.HttpUriRequest; 31 | import org.apache.http.entity.ContentType; 32 | import org.apache.http.impl.auth.BasicScheme; 33 | import org.apache.http.message.BasicHeader; 34 | import org.apache.http.util.EntityUtils; 35 | 36 | import com.arcbees.vcs.model.Branch; 37 | import com.arcbees.vcs.model.PullRequest; 38 | import com.arcbees.vcs.model.PullRequestTarget; 39 | import com.arcbees.vcs.model.PullRequests; 40 | import com.arcbees.vcs.util.HttpClientWrapper; 41 | import com.arcbees.vcs.util.UnexpectedHttpStatusException; 42 | import com.google.common.base.Predicate; 43 | import com.google.common.collect.Iterables; 44 | import com.google.gson.Gson; 45 | 46 | public abstract class AbstractVcsApi implements VcsApi { 47 | protected HttpResponse executeRequest(HttpClientWrapper httpClient, 48 | HttpUriRequest request, 49 | Credentials credentials) throws IOException { 50 | try { 51 | return doExecuteRequest(httpClient, request, credentials); 52 | } finally { 53 | request.abort(); 54 | } 55 | } 56 | 57 | protected T processResponse(HttpClientWrapper httpClient, 58 | HttpUriRequest request, 59 | Credentials credentials, 60 | Gson gson, 61 | Class clazz) throws IOException { 62 | try { 63 | HttpResponse httpResponse = doExecuteRequest(httpClient, request, credentials); 64 | 65 | HttpEntity entity = httpResponse.getEntity(); 66 | if (entity == null) { 67 | throw new IOException( 68 | "Failed to complete request. Empty response. Status: " + httpResponse.getStatusLine()); 69 | } 70 | 71 | try { 72 | return readEntity(clazz, entity, gson); 73 | } finally { 74 | EntityUtils.consumeQuietly(entity); 75 | } 76 | } finally { 77 | request.abort(); 78 | } 79 | } 80 | 81 | protected T readEntity(Class clazz, HttpEntity entity, Gson gson) throws IOException { 82 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 83 | entity.writeTo(outputStream); 84 | String json = outputStream.toString(CharEncoding.UTF_8); 85 | 86 | return gson.fromJson(json, clazz); 87 | } 88 | 89 | protected void includeAuthentication(HttpRequest request, 90 | Credentials credentials) throws IOException { 91 | try { 92 | request.addHeader(new BasicScheme().authenticate(credentials, request, null)); 93 | } catch (AuthenticationException e) { 94 | throw new IOException("Failed to set authentication for request. " + e.getMessage(), e); 95 | } 96 | } 97 | 98 | protected void setDefaultHeaders(HttpUriRequest request) { 99 | request.setHeader(new BasicHeader(HttpHeaders.ACCEPT_ENCODING, CharEncoding.UTF_8)); 100 | request.setHeader(new BasicHeader(HttpHeaders.ACCEPT, ContentType.APPLICATION_JSON.getMimeType())); 101 | } 102 | 103 | protected PullRequest findPullRequestForBranch(final String branchName, PullRequests pullRequests) { 104 | return (PullRequest) Iterables.tryFind(pullRequests.getPullRequests(), new Predicate() { 105 | @Override 106 | public boolean apply(PullRequest pullRequest) { 107 | PullRequestTarget source = pullRequest.getSource(); 108 | Branch branch = source.getBranch(); 109 | String pullRequestBranchName = branch.getName(); 110 | 111 | return pullRequestBranchName.equals(branchName); 112 | } 113 | }).orNull(); 114 | } 115 | 116 | private HttpResponse doExecuteRequest(HttpClientWrapper httpClient, HttpUriRequest request, Credentials credentials) 117 | throws IOException { 118 | includeAuthentication(request, credentials); 119 | setDefaultHeaders(request); 120 | 121 | HttpResponse httpResponse = httpClient.execute(request); 122 | int statusCode = httpResponse.getStatusLine().getStatusCode(); 123 | if (statusCode != HttpURLConnection.HTTP_OK && statusCode != HttpURLConnection.HTTP_CREATED) { 124 | ByteArrayOutputStream outputStream = new ByteArrayOutputStream(); 125 | httpResponse.getEntity().writeTo(outputStream); 126 | String json = outputStream.toString(CharEncoding.UTF_8); 127 | throw new UnexpectedHttpStatusException(statusCode, 128 | "Failed to complete request. Status: " + httpResponse.getStatusLine() + '\n' + json); 129 | } 130 | 131 | return httpResponse; 132 | } 133 | } 134 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/github/GitHubApi.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.github; 18 | 19 | import java.io.IOException; 20 | import java.util.Date; 21 | 22 | import org.apache.http.HttpHeaders; 23 | import org.apache.http.auth.UsernamePasswordCredentials; 24 | import org.apache.http.client.methods.HttpDelete; 25 | import org.apache.http.client.methods.HttpGet; 26 | import org.apache.http.client.methods.HttpPost; 27 | import org.apache.http.entity.ByteArrayEntity; 28 | import org.apache.http.entity.ContentType; 29 | import org.apache.http.entity.StringEntity; 30 | import org.apache.http.message.BasicHeader; 31 | 32 | import com.arcbees.vcs.AbstractVcsApi; 33 | import com.arcbees.vcs.github.model.GitHubComment; 34 | import com.arcbees.vcs.github.model.GitHubCommitStatus; 35 | import com.arcbees.vcs.github.model.GitHubCreateComment; 36 | import com.arcbees.vcs.github.model.GitHubPullRequests; 37 | import com.arcbees.vcs.github.util.GitHubPullRequestsTypeAdapter; 38 | import com.arcbees.vcs.model.Comment; 39 | import com.arcbees.vcs.model.CommitStatus; 40 | import com.arcbees.vcs.model.PullRequest; 41 | import com.arcbees.vcs.model.PullRequests; 42 | import com.arcbees.vcs.util.CommitStatusTypeAdapter; 43 | import com.arcbees.vcs.util.GsonDateTypeAdapter; 44 | import com.arcbees.vcs.util.HttpClientWrapper; 45 | import com.google.common.base.Charsets; 46 | import com.google.gson.Gson; 47 | import com.google.gson.GsonBuilder; 48 | 49 | import jetbrains.buildServer.serverSide.SRunningBuild; 50 | 51 | public class GitHubApi extends AbstractVcsApi { 52 | private final HttpClientWrapper httpClient; 53 | private final Gson gson; 54 | private final GitHubApiPaths apiPaths; 55 | private final String repositoryOwner; 56 | private final String repositoryName; 57 | private final UsernamePasswordCredentials credentials; 58 | 59 | public GitHubApi(HttpClientWrapper httpClient, 60 | GitHubApiPaths apiPaths, 61 | String userName, 62 | String password, 63 | String repositoryOwner, 64 | String repositoryName) { 65 | this.httpClient = httpClient; 66 | this.apiPaths = apiPaths; 67 | this.repositoryOwner = repositoryOwner; 68 | this.repositoryName = repositoryName; 69 | this.credentials = new UsernamePasswordCredentials(userName, password); 70 | this.gson = new GsonBuilder() 71 | .registerTypeAdapter(Date.class, new GsonDateTypeAdapter()) 72 | .registerTypeAdapter(GitHubPullRequests.class, new GitHubPullRequestsTypeAdapter()) 73 | .registerTypeAdapter(CommitStatus.class, new CommitStatusTypeAdapter()) 74 | .create(); 75 | } 76 | 77 | @Override 78 | public PullRequests getOpenedPullRequests() throws IOException { 79 | String requestUrl = apiPaths.getOpenedPullRequests(repositoryOwner, repositoryName); 80 | 81 | HttpGet request = new HttpGet(requestUrl); 82 | 83 | return processResponse(httpClient, request, credentials, gson, GitHubPullRequests.class); 84 | } 85 | 86 | @Override 87 | public PullRequests getMergedPullRequests() throws IOException { 88 | String requestUrl = apiPaths.getMergedPullRequests(repositoryOwner, repositoryName); 89 | 90 | HttpGet request = new HttpGet(requestUrl); 91 | 92 | return processResponse(httpClient, request, credentials, gson, GitHubPullRequests.class); 93 | } 94 | 95 | @Override 96 | public PullRequest getPullRequestForBranch(final String branchName) throws IOException { 97 | PullRequest pullRequestForBranch = findPullRequestForBranch(branchName, getOpenedPullRequests()); 98 | 99 | if (pullRequestForBranch == null) { 100 | pullRequestForBranch = findPullRequestForBranch(branchName, getMergedPullRequests()); 101 | } 102 | 103 | return pullRequestForBranch; 104 | } 105 | 106 | @Override 107 | public void deleteComment(Integer pullRequestId, Long commentId) throws IOException { 108 | String requestUrl = apiPaths.deleteComment(repositoryOwner, repositoryName, pullRequestId, commentId); 109 | 110 | HttpDelete request = new HttpDelete(requestUrl); 111 | 112 | executeRequest(httpClient, request, credentials); 113 | } 114 | 115 | @Override 116 | public Comment postComment(Integer pullRequestId, 117 | String comment) throws IOException { 118 | String requestUrl = apiPaths.addComment(repositoryOwner, repositoryName, pullRequestId); 119 | 120 | HttpPost request = new HttpPost(requestUrl); 121 | request.setHeader(new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType())); 122 | request.setEntity(new ByteArrayEntity(gson.toJson(new GitHubCreateComment(comment)).getBytes(Charsets.UTF_8))); 123 | 124 | return processResponse(httpClient, request, credentials, gson, GitHubComment.class); 125 | } 126 | 127 | @Override 128 | public void updateStatus(String commitHash, String message, CommitStatus status, String targetUrl, 129 | SRunningBuild build) 130 | throws IOException { 131 | String requestUrl = apiPaths.updateStatus(repositoryOwner, repositoryName, commitHash); 132 | 133 | HttpPost request = new HttpPost(requestUrl); 134 | request.setHeader(new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType())); 135 | 136 | String entityAsJson = gson.toJson(new GitHubCommitStatus(status, message, targetUrl)); 137 | request.setEntity(new StringEntity(entityAsJson)); 138 | 139 | executeRequest(httpClient, request, credentials); 140 | } 141 | 142 | @Override 143 | public void approvePullRequest(Integer pullRequestId) throws IOException, UnsupportedOperationException { 144 | throw new UnsupportedOperationException(); 145 | } 146 | 147 | @Override 148 | public void deletePullRequestApproval(Integer pullRequestId) throws IOException, UnsupportedOperationException { 149 | throw new UnsupportedOperationException(); 150 | } 151 | } 152 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/bitbucket/BitbucketApi.java: -------------------------------------------------------------------------------- 1 | /* 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket; 18 | 19 | import java.io.IOException; 20 | import java.util.Date; 21 | import java.util.List; 22 | 23 | import org.apache.http.HttpHeaders; 24 | import org.apache.http.NameValuePair; 25 | import org.apache.http.auth.UsernamePasswordCredentials; 26 | import org.apache.http.client.entity.UrlEncodedFormEntity; 27 | import org.apache.http.client.methods.HttpDelete; 28 | import org.apache.http.client.methods.HttpGet; 29 | import org.apache.http.client.methods.HttpPost; 30 | import org.apache.http.entity.ContentType; 31 | import org.apache.http.entity.StringEntity; 32 | import org.apache.http.message.BasicHeader; 33 | import org.apache.http.message.BasicNameValuePair; 34 | 35 | import com.arcbees.vcs.AbstractVcsApi; 36 | import com.arcbees.vcs.bitbucket.model.BitbucketComment; 37 | import com.arcbees.vcs.bitbucket.model.BitbucketCommitStatus; 38 | import com.arcbees.vcs.bitbucket.model.BitbucketPullRequests; 39 | import com.arcbees.vcs.model.Comment; 40 | import com.arcbees.vcs.model.CommitStatus; 41 | import com.arcbees.vcs.model.PullRequest; 42 | import com.arcbees.vcs.model.PullRequests; 43 | import com.arcbees.vcs.util.GsonDateTypeAdapter; 44 | import com.arcbees.vcs.util.HttpClientWrapper; 45 | import com.google.common.collect.Lists; 46 | import com.google.gson.Gson; 47 | import com.google.gson.GsonBuilder; 48 | 49 | import jetbrains.buildServer.serverSide.SRunningBuild; 50 | 51 | public class BitbucketApi extends AbstractVcsApi { 52 | private final HttpClientWrapper httpClient; 53 | private final Gson gson; 54 | private final BitbucketApiPaths apiPaths; 55 | private final String repositoryOwner; 56 | private final String repositoryName; 57 | private final UsernamePasswordCredentials credentials; 58 | 59 | public BitbucketApi(HttpClientWrapper httpClient, 60 | BitbucketApiPaths apiPaths, 61 | String userName, 62 | String password, 63 | String repositoryOwner, 64 | String repositoryName) { 65 | this.httpClient = httpClient; 66 | this.apiPaths = apiPaths; 67 | this.repositoryOwner = repositoryOwner; 68 | this.repositoryName = repositoryName; 69 | this.credentials = new UsernamePasswordCredentials(userName, password); 70 | this.gson = new GsonBuilder().registerTypeAdapter(Date.class, new GsonDateTypeAdapter()).create(); 71 | } 72 | 73 | @Override 74 | public PullRequests getOpenedPullRequests() throws IOException { 75 | String requestUrl = apiPaths.getOpenedPullRequests(repositoryOwner, repositoryName); 76 | 77 | HttpGet request = new HttpGet(requestUrl); 78 | 79 | return processResponse(httpClient, request, credentials, gson, BitbucketPullRequests.class); 80 | } 81 | 82 | @Override 83 | public PullRequests getMergedPullRequests() throws IOException { 84 | String requestUrl = apiPaths.getMergedPullRequests(repositoryOwner, repositoryName); 85 | 86 | HttpGet request = new HttpGet(requestUrl); 87 | 88 | return processResponse(httpClient, request, credentials, gson, BitbucketPullRequests.class); 89 | } 90 | 91 | @Override 92 | public PullRequest getPullRequestForBranch(final String branchName) throws IOException { 93 | PullRequest pullRequestForBranch = findPullRequestForBranch(branchName, getOpenedPullRequests()); 94 | 95 | if (pullRequestForBranch == null) { 96 | pullRequestForBranch = findPullRequestForBranch(branchName, getMergedPullRequests()); 97 | } 98 | 99 | return pullRequestForBranch; 100 | } 101 | 102 | @Override 103 | public void deleteComment(Integer pullRequestId, Long commentId) throws IOException { 104 | String requestUrl = apiPaths.deleteComment(repositoryOwner, repositoryName, pullRequestId, commentId); 105 | 106 | HttpDelete request = new HttpDelete(requestUrl); 107 | 108 | executeRequest(httpClient, request, credentials); 109 | } 110 | 111 | @Override 112 | public Comment postComment(Integer pullRequestId, 113 | String comment) throws IOException { 114 | String requestUrl = apiPaths.addComment(repositoryOwner, repositoryName, pullRequestId); 115 | 116 | HttpPost request = new HttpPost(requestUrl); 117 | 118 | List postParameters = Lists.newArrayList(); 119 | postParameters.add(new BasicNameValuePair("content", comment)); 120 | 121 | request.setEntity(new UrlEncodedFormEntity(postParameters)); 122 | 123 | return processResponse(httpClient, request, credentials, gson, BitbucketComment.class); 124 | } 125 | 126 | @Override 127 | public void updateStatus(String commitHash, String message, CommitStatus status, String targetUrl, 128 | SRunningBuild build) 129 | throws IOException, UnsupportedOperationException { 130 | String requestUrl = apiPaths.updateStatus(repositoryOwner, repositoryName, commitHash); 131 | 132 | HttpPost request = new HttpPost(requestUrl); 133 | request.setHeader(new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType())); 134 | 135 | String entityAsJson = gson.toJson( 136 | new BitbucketCommitStatus(status, build.getBuildTypeId(), build.getFullName(), message, targetUrl)); 137 | 138 | request.setEntity(new StringEntity(entityAsJson)); 139 | 140 | executeRequest(httpClient, request, credentials); 141 | } 142 | 143 | @Override 144 | public void approvePullRequest(Integer pullRequestId) throws IOException, UnsupportedOperationException { 145 | String requestUrl = apiPaths.approvePullRequest(repositoryOwner, repositoryName, pullRequestId); 146 | 147 | HttpPost request = new HttpPost(requestUrl); 148 | 149 | executeRequest(httpClient, request, credentials); 150 | } 151 | 152 | @Override 153 | public void deletePullRequestApproval(Integer pullRequestId) throws IOException, UnsupportedOperationException { 154 | String requestUrl = apiPaths.approvePullRequest(repositoryOwner, repositoryName, pullRequestId); 155 | 156 | HttpDelete request = new HttpDelete(requestUrl); 157 | 158 | executeRequest(httpClient, request, credentials); 159 | } 160 | } 161 | -------------------------------------------------------------------------------- /pom.xml: -------------------------------------------------------------------------------- 1 | 2 | 5 | 4.0.0 6 | 7 | com.arcbees.teamcity 8 | plugins 9 | 1.0-SNAPSHOT 10 | pom 11 | Plugins 12 | 13 | 14 | vcs-utils 15 | pullrequests 16 | staging 17 | 18 | 19 | 20 | 10.0 21 | 7.0.3 22 | 23 | 13.0.1 24 | 25 | 2.2.4 26 | 4.3.3 27 | 28 | 4.11 29 | 1.9.5 30 | 1.4 31 | 32 | yyyyddMMHHmmss 33 | 34 | 1.5.2 35 | 2.4 36 | 37 | 1.7 38 | 39 | 40 | 41 | 42 | teamcity-repository 43 | http://download.jetbrains.com/teamcity-repository 44 | 45 | 46 | jetbrains-all 47 | http://repository.jetbrains.com/all 48 | 49 | 50 | 51 | 52 | 53 | org.jetbrains.teamcity 54 | server-api 55 | ${teamcity.version} 56 | provided 57 | 58 | 59 | org.jetbrains.teamcity.internal 60 | server 61 | ${teamcity.version} 62 | provided 63 | 64 | 65 | com.intellij 66 | openapi 67 | ${openapi.version} 68 | provided 69 | 70 | 71 | 72 | com.google.code.gson 73 | gson 74 | 75 | 76 | org.apache.httpcomponents 77 | httpclient 78 | ${httpclient.version} 79 | 80 | 81 | 82 | com.google.guava 83 | guava 84 | ${guava.version} 85 | 86 | 87 | 88 | junit 89 | junit 90 | ${junit.version} 91 | test 92 | 93 | 94 | org.mockito 95 | mockito-all 96 | ${mockito-all.version} 97 | test 98 | 99 | 100 | org.jukito 101 | jukito 102 | ${jukito.version} 103 | test 104 | 105 | 106 | 107 | 108 | 109 | 110 | com.google.code.gson 111 | gson 112 | ${gson.version} 113 | 114 | 115 | 116 | 117 | 118 | 119 | 120 | src/main/resources/META-INF 121 | META-INF 122 | 123 | 124 | src/main/resources/buildServerResources 125 | buildServerResources 126 | 127 | 128 | 129 | 130 | 131 | 132 | com.google.code.maven-replacer-plugin 133 | replacer 134 | ${replacer.version} 135 | 136 | 137 | process-sources 138 | 139 | replace 140 | 141 | 142 | 143 | 144 | ${project.basedir}/teamcity-plugin.xml 145 | ${project.basedir}/target/teamcity-plugin.xml 146 | 147 | 148 | @Version@ 149 | snapshot-${maven.build.timestamp} 150 | 151 | 152 | 153 | 154 | 155 | maven-assembly-plugin 156 | ${maven-assembly-plugin.version} 157 | 158 | 159 | make-assembly 160 | package 161 | 162 | single 163 | 164 | 165 | ${project.artifactId} 166 | ${project.build.directory} 167 | false 168 | 169 | ${basedir}/plugin-assembly.xml 170 | 171 | 172 | 173 | 174 | 175 | 176 | 177 | maven-compiler-plugin 178 | 179 | ${target.jdk} 180 | ${target.jdk} 181 | 182 | 183 | 184 | 185 | 186 | 187 | -------------------------------------------------------------------------------- /vcs-utils/src/main/java/com/arcbees/vcs/stash/StashApi.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * This file is part of Stash TeamCity plugin. 5 | * 6 | * Stash TeamCity plugin is free software: you can redistribute it and/or modify it under the terms of the GNU 7 | * General Public License as published by the Free Software Foundation, either version 3 of the License, 8 | * or (at your option) any later version. 9 | * 10 | * Stash TeamCity plugin is distributed in the hope that it will be useful, but WITHOUT ANY WARRANTY; without even 11 | * the implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 | * for more details. 13 | * 14 | * You should have received a copy of the GNU General Public License along with Stash TeamCity plugin. If not, 15 | * see http://www.gnu.org/licenses/. 16 | */ 17 | 18 | package com.arcbees.vcs.stash; 19 | 20 | import java.io.IOException; 21 | import java.util.Date; 22 | 23 | import org.apache.http.HttpHeaders; 24 | import org.apache.http.auth.UsernamePasswordCredentials; 25 | import org.apache.http.client.methods.HttpDelete; 26 | import org.apache.http.client.methods.HttpGet; 27 | import org.apache.http.client.methods.HttpPost; 28 | import org.apache.http.entity.ByteArrayEntity; 29 | import org.apache.http.entity.ContentType; 30 | import org.apache.http.entity.StringEntity; 31 | import org.apache.http.message.BasicHeader; 32 | 33 | import com.arcbees.vcs.AbstractVcsApi; 34 | import com.arcbees.vcs.model.Comment; 35 | import com.arcbees.vcs.model.CommitStatus; 36 | import com.arcbees.vcs.model.PullRequest; 37 | import com.arcbees.vcs.model.PullRequests; 38 | import com.arcbees.vcs.stash.model.StashComment; 39 | import com.arcbees.vcs.stash.model.StashCommitStatus; 40 | import com.arcbees.vcs.stash.model.StashPullRequests; 41 | import com.arcbees.vcs.util.GsonDateTypeAdapter; 42 | import com.arcbees.vcs.util.HttpClientWrapper; 43 | import com.arcbees.vcs.util.UnexpectedHttpStatusException; 44 | import com.google.common.base.Charsets; 45 | import com.google.gson.Gson; 46 | import com.google.gson.GsonBuilder; 47 | 48 | import jetbrains.buildServer.serverSide.SRunningBuild; 49 | 50 | public class StashApi extends AbstractVcsApi { 51 | private final HttpClientWrapper httpClient; 52 | private final Gson gson; 53 | private final StashApiPaths apiPaths; 54 | private final String repositoryOwner; 55 | private final String repositoryName; 56 | private final UsernamePasswordCredentials credentials; 57 | 58 | public StashApi(HttpClientWrapper httpClient, 59 | StashApiPaths apiPaths, 60 | String userName, 61 | String password, 62 | String repositoryOwner, 63 | String repositoryName) { 64 | this.httpClient = httpClient; 65 | this.apiPaths = apiPaths; 66 | this.repositoryOwner = repositoryOwner; 67 | this.repositoryName = repositoryName; 68 | this.credentials = new UsernamePasswordCredentials(userName, password); 69 | this.gson = new GsonBuilder().registerTypeAdapter(Date.class, new GsonDateTypeAdapter()).create(); 70 | } 71 | 72 | @Override 73 | public PullRequests getOpenedPullRequests() throws IOException { 74 | String requestUrl = apiPaths.getOpenedPullRequests(repositoryOwner, repositoryName); 75 | 76 | HttpGet request = new HttpGet(requestUrl); 77 | 78 | return processResponse(httpClient, request, credentials, gson, StashPullRequests.class); 79 | } 80 | 81 | @Override 82 | public PullRequests getMergedPullRequests() throws IOException { 83 | String requestUrl = apiPaths.getMergedPullRequests(repositoryOwner, repositoryName); 84 | 85 | HttpGet request = new HttpGet(requestUrl); 86 | 87 | return processResponse(httpClient, request, credentials, gson, StashPullRequests.class); 88 | } 89 | 90 | @Override 91 | public PullRequest getPullRequestForBranch(final String branchName) throws IOException { 92 | PullRequest pullRequestForBranch = findPullRequestForBranch(branchName, getOpenedPullRequests()); 93 | 94 | if (pullRequestForBranch == null) { 95 | pullRequestForBranch = findPullRequestForBranch(branchName, getMergedPullRequests()); 96 | } 97 | 98 | return pullRequestForBranch; 99 | } 100 | 101 | @Override 102 | public void deleteComment(Integer pullRequestId, Long commentId) throws IOException { 103 | StashComment oldComment = getComment(pullRequestId, commentId); 104 | 105 | if (oldComment != null) { 106 | String requestUrl = apiPaths.pullRequestComment(repositoryOwner, repositoryName, pullRequestId, commentId) 107 | + "?version=" + oldComment.getVersion(); 108 | 109 | HttpDelete request = new HttpDelete(requestUrl); 110 | 111 | executeRequest(httpClient, request, credentials); 112 | } 113 | } 114 | 115 | @Override 116 | public Comment postComment(Integer pullRequestId, 117 | String comment) throws IOException { 118 | String requestUrl = apiPaths.addComment(repositoryOwner, repositoryName, pullRequestId); 119 | 120 | HttpPost request = new HttpPost(requestUrl); 121 | request.setHeader(new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType())); 122 | request.setEntity(new ByteArrayEntity(gson.toJson(new StashComment(comment)).getBytes(Charsets.UTF_8))); 123 | 124 | return processResponse(httpClient, request, credentials, gson, StashComment.class); 125 | } 126 | 127 | @Override 128 | public void updateStatus(String commitHash, String message, CommitStatus status, String targetUrl, 129 | SRunningBuild build) 130 | throws IOException, UnsupportedOperationException { 131 | String requestUrl = apiPaths.updateStatus(commitHash); 132 | 133 | HttpPost request = new HttpPost(requestUrl); 134 | request.setHeader(new BasicHeader(HttpHeaders.CONTENT_TYPE, ContentType.APPLICATION_JSON.getMimeType())); 135 | 136 | String entityAsJson = gson.toJson( 137 | new StashCommitStatus(status, build.getBuildTypeName() + build.getBuildId(), build.getFullName(), 138 | message, targetUrl)); 139 | request.setEntity(new StringEntity(entityAsJson)); 140 | 141 | executeRequest(httpClient, request, credentials); 142 | } 143 | 144 | @Override 145 | public void approvePullRequest(Integer pullRequestId) throws IOException, UnsupportedOperationException { 146 | String requestUrl = apiPaths.approvePullRequest(repositoryOwner, repositoryName, pullRequestId); 147 | 148 | HttpPost request = new HttpPost(requestUrl); 149 | 150 | executeRequest(httpClient, request, credentials); 151 | } 152 | 153 | @Override 154 | public void deletePullRequestApproval(Integer pullRequestId) throws IOException, UnsupportedOperationException { 155 | String requestUrl = apiPaths.approvePullRequest(repositoryOwner, repositoryName, pullRequestId); 156 | 157 | HttpDelete request = new HttpDelete(requestUrl); 158 | 159 | executeRequest(httpClient, request, credentials); 160 | } 161 | 162 | private StashComment getComment(Integer pullRequestId, Long commentId) throws IOException { 163 | String requestUrl = apiPaths.pullRequestComment(repositoryOwner, repositoryName, pullRequestId, commentId); 164 | 165 | HttpGet request = new HttpGet(requestUrl); 166 | 167 | includeAuthentication(request, credentials); 168 | setDefaultHeaders(request); 169 | 170 | try { 171 | return processResponse(httpClient, request, credentials, gson, StashComment.class); 172 | } catch (UnexpectedHttpStatusException e) { 173 | return null; 174 | } 175 | } 176 | } 177 | -------------------------------------------------------------------------------- /pullrequests/src/test/java/com/arcbees/vcs/bitbucket/PullRequestStatusHandlerTest.java: -------------------------------------------------------------------------------- 1 | /** 2 | * Copyright 2014 ArcBees Inc. 3 | * 4 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5 | * use this file except in compliance with the License. You may obtain a copy of 6 | * the License at 7 | * 8 | * http://www.apache.org/licenses/LICENSE-2.0 9 | * 10 | * Unless required by applicable law or agreed to in writing, software 11 | * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12 | * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13 | * License for the specific language governing permissions and limitations under 14 | * the License. 15 | */ 16 | 17 | package com.arcbees.vcs.bitbucket; 18 | 19 | import java.io.IOException; 20 | 21 | import org.junit.Before; 22 | import org.junit.Test; 23 | 24 | import com.arcbees.pullrequest.BuildStatus; 25 | import com.arcbees.pullrequest.Constants; 26 | import com.arcbees.pullrequest.PullRequestBuild; 27 | import com.arcbees.pullrequest.PullRequestStatusHandler; 28 | import com.arcbees.vcs.VcsApi; 29 | import com.arcbees.vcs.VcsApiFactories; 30 | import com.arcbees.vcs.VcsConstants; 31 | import com.arcbees.vcs.VcsPropertiesHelper; 32 | import com.arcbees.vcs.bitbucket.model.BitbucketComment; 33 | import com.arcbees.vcs.bitbucket.model.BitbucketCommit; 34 | import com.arcbees.vcs.bitbucket.model.BitbucketPullRequest; 35 | import com.arcbees.vcs.bitbucket.model.BitbucketPullRequestTarget; 36 | import com.arcbees.vcs.model.Comment; 37 | import com.arcbees.vcs.model.CommitStatus; 38 | import com.arcbees.vcs.model.PullRequest; 39 | import com.arcbees.vcs.util.PolymorphicTypeAdapter; 40 | import com.google.gson.Gson; 41 | import com.google.gson.GsonBuilder; 42 | 43 | import jetbrains.buildServer.StatusDescriptor; 44 | import jetbrains.buildServer.buildTriggers.BuildTriggerDescriptor; 45 | import jetbrains.buildServer.buildTriggers.BuildTriggerService; 46 | import jetbrains.buildServer.messages.Status; 47 | import jetbrains.buildServer.serverSide.Branch; 48 | import jetbrains.buildServer.serverSide.CustomDataStorage; 49 | import jetbrains.buildServer.serverSide.SBuildType; 50 | import jetbrains.buildServer.serverSide.SRunningBuild; 51 | import jetbrains.buildServer.serverSide.WebLinks; 52 | 53 | import static org.mockito.BDDMockito.given; 54 | import static org.mockito.Matchers.any; 55 | import static org.mockito.Matchers.anyInt; 56 | import static org.mockito.Matchers.anyLong; 57 | import static org.mockito.Matchers.anyString; 58 | import static org.mockito.Matchers.eq; 59 | import static org.mockito.Mockito.doThrow; 60 | import static org.mockito.Mockito.mock; 61 | import static org.mockito.Mockito.never; 62 | import static org.mockito.Mockito.times; 63 | import static org.mockito.Mockito.verify; 64 | 65 | public class PullRequestStatusHandlerTest { 66 | private PullRequestStatusHandler commentHandler; 67 | private VcsApi vcsApi; 68 | private BuildTriggerDescriptor trigger; 69 | private CustomDataStorage dataStorage; 70 | private SRunningBuild build; 71 | 72 | @Before 73 | public void setUp() throws IOException { 74 | VcsApiFactories apiFactory = mock(VcsApiFactories.class); 75 | vcsApi = mock(VcsApi.class); 76 | given(apiFactory.create(any(VcsPropertiesHelper.class))).willReturn(vcsApi); 77 | 78 | commentHandler = new PullRequestStatusHandler(apiFactory, new VcsConstants(), new Constants(), 79 | mock(WebLinks.class)); 80 | 81 | trigger = mock(BuildTriggerDescriptor.class); 82 | 83 | SBuildType buildType = mock(SBuildType.class); 84 | dataStorage = mock(CustomDataStorage.class); 85 | given(buildType.getCustomDataStorage(anyString())).willReturn(dataStorage); 86 | 87 | build = mock(SRunningBuild.class); 88 | given(build.getBuildType()).willReturn(buildType); 89 | given(build.getBranch()).willReturn(mock(Branch.class)); 90 | given(build.getStatusDescriptor()).willReturn(mock(StatusDescriptor.class)); 91 | 92 | given(trigger.getBuildTriggerService()).willReturn(mock(BuildTriggerService.class)); 93 | given(vcsApi.getPullRequestForBranch(anyString())).willReturn(createPullRequest()); 94 | } 95 | 96 | @Test 97 | public void firstBuild_postComment() throws IOException { 98 | doThrow(UnsupportedOperationException.class).when(vcsApi) 99 | .updateStatus(anyString(), anyString(), any(CommitStatus.class), anyString(), eq(build)); 100 | given(build.getBuildStatus()).willReturn(Status.NORMAL); 101 | 102 | commentHandler.handle(build, trigger, BuildStatus.FINISHED); 103 | 104 | verify(vcsApi, never()).deleteComment(anyInt(), anyLong()); 105 | verify(vcsApi).postComment(anyInt(), anyString()); 106 | } 107 | 108 | @Test 109 | public void secondSuccess_newComment() throws IOException { 110 | doThrow(UnsupportedOperationException.class).when(vcsApi) 111 | .updateStatus(anyString(), anyString(), any(CommitStatus.class), anyString(), eq(build)); 112 | given(build.getBuildStatus()).willReturn(Status.NORMAL); 113 | PullRequestBuild pullRequestBuild = 114 | new PullRequestBuild(createPullRequest(), Status.NORMAL, new BitbucketComment()); 115 | 116 | given(dataStorage.getValue(anyString())).willReturn(getGson().toJson(pullRequestBuild)); 117 | 118 | commentHandler.handle(build, trigger, BuildStatus.FINISHED); 119 | 120 | verify(vcsApi, times(1)).deleteComment(anyInt(), anyLong()); 121 | verify(vcsApi, times(1)).postComment(anyInt(), anyString()); 122 | } 123 | 124 | @Test 125 | public void failureAfterSuccess_newComment() throws IOException { 126 | doThrow(UnsupportedOperationException.class).when(vcsApi) 127 | .updateStatus(anyString(), anyString(), any(CommitStatus.class), anyString(), eq(build)); 128 | given(build.getBuildStatus()).willReturn(Status.FAILURE); 129 | PullRequestBuild pullRequestBuild = 130 | new PullRequestBuild(createPullRequest(), Status.NORMAL, new BitbucketComment()); 131 | 132 | given(dataStorage.getValue(anyString())).willReturn(getGson().toJson(pullRequestBuild)); 133 | 134 | commentHandler.handle(build, trigger, BuildStatus.FINISHED); 135 | 136 | verify(vcsApi, times(1)).deleteComment(anyInt(), anyLong()); 137 | verify(vcsApi, times(1)).postComment(anyInt(), anyString()); 138 | } 139 | 140 | @Test 141 | public void failureAfterFailure_newComment() throws IOException { 142 | doThrow(UnsupportedOperationException.class).when(vcsApi) 143 | .updateStatus(anyString(), anyString(), any(CommitStatus.class), anyString(), eq(build)); 144 | given(build.getBuildStatus()).willReturn(Status.FAILURE); 145 | PullRequestBuild pullRequestBuild = 146 | new PullRequestBuild(createPullRequest(), Status.FAILURE, new BitbucketComment()); 147 | 148 | given(dataStorage.getValue(anyString())).willReturn(getGson().toJson(pullRequestBuild)); 149 | 150 | commentHandler.handle(build, trigger, BuildStatus.FINISHED); 151 | 152 | verify(vcsApi, times(1)).deleteComment(anyInt(), anyLong()); 153 | verify(vcsApi, times(1)).postComment(anyInt(), anyString()); 154 | } 155 | 156 | private PullRequest createPullRequest() { 157 | PullRequest pullRequest = new BitbucketPullRequest(); 158 | pullRequest.setId(1); 159 | 160 | BitbucketPullRequestTarget pullRequestTarget = new BitbucketPullRequestTarget(); 161 | pullRequestTarget.setCommit(new BitbucketCommit()); 162 | pullRequest.setSource(pullRequestTarget); 163 | 164 | return pullRequest; 165 | } 166 | 167 | private Gson getGson() { 168 | return new GsonBuilder() 169 | .registerTypeAdapter(PullRequest.class, new PolymorphicTypeAdapter()) 170 | .registerTypeAdapter(Comment.class, new PolymorphicTypeAdapter()) 171 | .create(); 172 | } 173 | } 174 | --------------------------------------------------------------------------------