Skip to content

Commit 166d3df

Browse files
committed
first commit
0 parents  commit 166d3df

24 files changed

+1548
-0
lines changed

Diff for: .gitignore

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
target/
2+
work/
3+
4+
#
5+
# Eclipse metadata.
6+
#
7+
.project
8+
.classpath
9+
.settings/
10+
11+
#
12+
# Eclipse and Maven build results
13+
#
14+
bin/
15+
16+
# IntelliJ metadata.
17+
*.iml
18+
*.ipr
19+
*.iws
20+
.idea/

Diff for: COPYING

+22
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
Copyright 2014 Nathan McCarthy. All rights reserved.
2+
3+
Redistribution and use in source and binary forms, with or without
4+
modification, are permitted provided that the following conditions are met:
5+
6+
1. Redistributions of source code must retain the above copyright notice, this
7+
list of conditions and the following disclaimer.
8+
9+
2. Redistributions in binary form must reproduce the above copyright notice,
10+
this list of conditions and the following disclaimer in the documentation
11+
and/or other materials provided with the distribution.
12+
13+
THIS SOFTWARE IS PROVIDED BY Nathan McCarthy "AS IS" AND ANY EXPRESS OR IMPLIED
14+
WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
15+
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO
16+
EVENT SHALL Nathan McCarthy OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
17+
INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
18+
LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
19+
PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
20+
LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
21+
OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
22+
ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.

Diff for: README.md

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
Stash Pull Request Builder Plugin
2+
================================
3+
4+
This Jenkins plugin builds pull requests from a Atlassian Stash server and will report the test results as a comment.
5+
This plugin was inspired by the GitHub & BitBucket pull request builder plugins.
6+
7+
8+
Prerequisites
9+
================================
10+
11+
- Jenkins 1.532 or higher.
12+
- Git Plugin - https://wiki.jenkins-ci.org/display/JENKINS/Git+Plugin
13+
14+
15+
Creating a Job
16+
=================================
17+
18+
- Create a new job
19+
- Select Git SCM
20+
- Add Repository URL as bellow
21+
- git@stash.org:${projectCode}/${repositoryName}.git
22+
- In Branch Specifier, type as bellow
23+
- */${sourceBranch}
24+
- Under Build Triggers, check Stash Pull Request Builder
25+
- In Cron, enter crontab for this job.
26+
- e.g. every minute: * * * * *
27+
- In Stash BasicAuth Username - Stash username like jenkins-buildbot
28+
- In Stash BasicAuth Password - Jenkins Build Bot password
29+
- Supply project code (this is the abbreviated project code, e.g. PRJ)
30+
- Supply Repository Name (e.g. myRepo)
31+
- Save to preserve your changes
32+
33+
Merge the Pull Request's Source Branch into the Target Branch Before Building
34+
==============================================================================
35+
You may want Jenkins to attempt to merge your PR before doing the build -- this way it will find conflicts for you automatically.
36+
37+
- Follow the steps above in "Creating a Job"
38+
- In the "Source Code Management" > "Git" > "Additional Behaviors" section, click "Add" > "Merge Before Building"
39+
- In "Name of Repository" put "origin" (or, if not using default name, use your remote repository's name. Note: unlike in the main part of the Git Repository config, you cannot leave this item blank for "default".)
40+
- In "Branch to merge to" put "${targetBranch}"
41+
- Note that as long as you don't push these changes to your remote repository, the merge only happens in your local repository.
42+
43+
44+
If you are merging into your target branch, you might want Jenkins to do a new build of the Pull Request when the target branch changes.
45+
- There is a checkbox that says, "Rebuild if destination branch changes?" which enables this check.
46+
47+
48+
Rerun test builds
49+
====================
50+
51+
If you want to rerun pull request test, write *“test this please”* comment to your pull request.
52+
53+
54+
55+
Copyright
56+
=============================
57+
58+
Copyright © 2015 Nathan McCarthy.
59+
60+
61+
License
62+
=============================
63+
64+
- BSD License

Diff for: pom.xml

+68
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,68 @@
1+
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
2+
<modelVersion>4.0.0</modelVersion>
3+
<parent>
4+
<groupId>org.jenkins-ci.plugins</groupId>
5+
<artifactId>plugin</artifactId>
6+
<version>1.532</version><!-- which version of Jenkins is this plugin built against? -->
7+
</parent>
8+
9+
<artifactId>stash-pullrequest-builder</artifactId>
10+
<name>Stash Pullrequest Builder Plugin</name>
11+
<version>1.0.0-SNAPSHOT</version>
12+
<description>This Jenkins plugin builds pull requests from Stash and will report the test results.</description>
13+
<packaging>hpi</packaging>
14+
<url>https://wiki.jenkins-ci.org/display/JENKINS/Stash+pullrequest+builder+plugin</url>
15+
16+
<scm>
17+
<connection>scm:git:ssh://git@github.com/jenkinsci/stash-pullrequest-builder-plugin.git</connection>
18+
<developerConnection>scm:git:ssh://git@github.com/jenkinsci/stash-pullrequest-builder-plugin.git</developerConnection>
19+
<url>https://github.com/jenkinsci/stash-pullrequest-builder-plugin.git</url>
20+
<tag>HEAD</tag>
21+
</scm>
22+
<developers>
23+
<developer>
24+
<id>nemccarthy</id>
25+
<name>nemccarthy</name>
26+
<email>nem@nemccarthy.me</email>
27+
</developer>
28+
</developers>
29+
30+
<!-- get every artifact through repo.jenkins-ci.org, which proxies all the artifacts that we need -->
31+
<repositories>
32+
<repository>
33+
<id>repo.jenkins-ci.org</id>
34+
<url>http://repo.jenkins-ci.org/public/</url>
35+
</repository>
36+
</repositories>
37+
38+
<dependencies>
39+
<dependency>
40+
<groupId>org.apache.maven.wagon</groupId>
41+
<artifactId>wagon-http</artifactId>
42+
<version>2.4</version>
43+
</dependency>
44+
<dependency>
45+
<groupId>commons-httpclient</groupId>
46+
<artifactId>commons-httpclient</artifactId>
47+
<version>3.1</version>
48+
</dependency>
49+
<dependency>
50+
<groupId>commons-codec</groupId>
51+
<artifactId>commons-codec</artifactId>
52+
<version>1.9</version>
53+
</dependency>
54+
<dependency>
55+
<groupId>org.codehaus.jackson</groupId>
56+
<artifactId>jackson-jaxrs</artifactId>
57+
<version>1.9.13</version>
58+
</dependency>
59+
</dependencies>
60+
61+
<pluginRepositories>
62+
<pluginRepository>
63+
<id>repo.jenkins-ci.org</id>
64+
<url>http://repo.jenkins-ci.org/public/</url>
65+
</pluginRepository>
66+
</pluginRepositories>
67+
68+
</project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
package stashpullrequestbuilder.stashpullrequestbuilder;
2+
3+
import hudson.Extension;
4+
import hudson.model.AbstractBuild;
5+
import hudson.model.TaskListener;
6+
import hudson.model.listeners.RunListener;
7+
8+
import javax.annotation.Nonnull;
9+
import java.util.logging.Logger;
10+
11+
/**
12+
* Created by Nathan McCarthy
13+
*/
14+
@Extension
15+
public class StashBuildListener extends RunListener<AbstractBuild> {
16+
private static final Logger logger = Logger.getLogger(StashBuildTrigger.class.getName());
17+
18+
@Override
19+
public void onStarted(AbstractBuild abstractBuild, TaskListener listener) {
20+
logger.info("BuildListener onStarted called.");
21+
StashBuildTrigger trigger = StashBuildTrigger.getTrigger(abstractBuild.getProject());
22+
if (trigger == null) {
23+
return;
24+
}
25+
trigger.getBuilder().getBuilds().onStarted(abstractBuild);
26+
}
27+
28+
@Override
29+
public void onCompleted(AbstractBuild abstractBuild, @Nonnull TaskListener listener) {
30+
StashBuildTrigger trigger = StashBuildTrigger.getTrigger(abstractBuild.getProject());
31+
if (trigger == null) {
32+
return;
33+
}
34+
trigger.getBuilder().getBuilds().onCompleted(abstractBuild);
35+
}
36+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,183 @@
1+
package stashpullrequestbuilder.stashpullrequestbuilder;
2+
3+
import antlr.ANTLRException;
4+
import hudson.Extension;
5+
import hudson.model.*;
6+
import hudson.model.queue.QueueTaskFuture;
7+
import hudson.triggers.Trigger;
8+
import hudson.triggers.TriggerDescriptor;
9+
import net.sf.json.JSONObject;
10+
import org.kohsuke.stapler.DataBoundConstructor;
11+
import org.kohsuke.stapler.StaplerRequest;
12+
13+
import java.util.ArrayList;
14+
import java.util.HashMap;
15+
import java.util.Map;
16+
import java.util.logging.Level;
17+
import java.util.logging.Logger;
18+
19+
/**
20+
* Created by Nathan McCarthy
21+
*/
22+
public class StashBuildTrigger extends Trigger<AbstractProject<?, ?>> {
23+
private static final Logger logger = Logger.getLogger(StashBuildTrigger.class.getName());
24+
private final String projectPath;
25+
private final String cron;
26+
private final String stashHost;
27+
private final String username;
28+
private final String password;
29+
private final String projectCode;
30+
private final String repositoryName;
31+
private final String ciSkipPhrases;
32+
private final boolean checkDestinationCommit;
33+
34+
transient private StashPullRequestsBuilder stashPullRequestsBuilder;
35+
36+
@Extension
37+
public static final StashBuildTriggerDescriptor descriptor = new StashBuildTriggerDescriptor();
38+
39+
@DataBoundConstructor
40+
public StashBuildTrigger(
41+
String projectPath,
42+
String cron,
43+
String stashHost,
44+
String username,
45+
String password,
46+
String projectCode,
47+
String repositoryName,
48+
String ciSkipPhrases,
49+
boolean checkDestinationCommit
50+
) throws ANTLRException {
51+
super(cron);
52+
this.projectPath = projectPath;
53+
this.cron = cron;
54+
this.stashHost = stashHost;
55+
this.username = username;
56+
this.password = password;
57+
this.projectCode = projectCode;
58+
this.repositoryName = repositoryName;
59+
this.ciSkipPhrases = ciSkipPhrases;
60+
this.checkDestinationCommit = checkDestinationCommit;
61+
}
62+
63+
public String getStashHost() {
64+
return stashHost;
65+
}
66+
67+
public String getProjectPath() {
68+
return this.projectPath;
69+
}
70+
71+
public String getCron() {
72+
return this.cron;
73+
}
74+
75+
public String getUsername() {
76+
return username;
77+
}
78+
79+
public String getPassword() {
80+
return password;
81+
}
82+
83+
public String getProjectCode() {
84+
return projectCode;
85+
}
86+
87+
public String getRepositoryName() {
88+
return repositoryName;
89+
}
90+
91+
public String getCiSkipPhrases() {
92+
return ciSkipPhrases;
93+
}
94+
95+
public boolean getCheckDestinationCommit() {
96+
return checkDestinationCommit;
97+
}
98+
99+
@Override
100+
public void start(AbstractProject<?, ?> project, boolean newInstance) {
101+
try {
102+
this.stashPullRequestsBuilder = StashPullRequestsBuilder.getBuilder();
103+
this.stashPullRequestsBuilder.setProject(project);
104+
this.stashPullRequestsBuilder.setTrigger(this);
105+
this.stashPullRequestsBuilder.setupBuilder();
106+
} catch(IllegalStateException e) {
107+
logger.log(Level.SEVERE, "Can't start trigger", e);
108+
return;
109+
}
110+
super.start(project, newInstance);
111+
}
112+
113+
public static StashBuildTrigger getTrigger(AbstractProject project) {
114+
Trigger trigger = project.getTrigger(StashBuildTrigger.class);
115+
return (StashBuildTrigger)trigger;
116+
}
117+
118+
public StashPullRequestsBuilder getBuilder() {
119+
return this.stashPullRequestsBuilder;
120+
}
121+
122+
public QueueTaskFuture<?> startJob(StashCause cause) {
123+
Map<String, ParameterValue> values = new HashMap<String, ParameterValue>();
124+
values.put("sourceBranch", new StringParameterValue("sourceBranch", cause.getSourceBranch()));
125+
values.put("targetBranch", new StringParameterValue("targetBranch", cause.getTargetBranch()));
126+
values.put("projectCode", new StringParameterValue("projectCode", cause.getRepositoryOwner()));
127+
values.put("repositoryName", new StringParameterValue("repositoryName", cause.getRepositoryName()));
128+
values.put("pullRequestId", new StringParameterValue("pullRequestId", cause.getPullRequestId()));
129+
values.put("destinationRepositoryOwner", new StringParameterValue("destinationRepositoryOwner", cause.getDestinationRepositoryOwner()));
130+
values.put("destinationRepositoryName", new StringParameterValue("destinationRepositoryName", cause.getDestinationRepositoryName()));
131+
values.put("pullRequestTitle", new StringParameterValue("pullRequestTitle", cause.getPullRequestTitle()));
132+
return this.job.scheduleBuild2(0, cause, new ParametersAction(new ArrayList(values.values())));
133+
}
134+
135+
private Map<String, ParameterValue> getDefaultParameters() {
136+
Map<String, ParameterValue> values = new HashMap<String, ParameterValue>();
137+
ParametersDefinitionProperty definitionProperty = this.job.getProperty(ParametersDefinitionProperty.class);
138+
139+
if (definitionProperty != null) {
140+
for (ParameterDefinition definition : definitionProperty.getParameterDefinitions()) {
141+
values.put(definition.getName(), definition.getDefaultParameterValue());
142+
}
143+
}
144+
return values;
145+
}
146+
147+
@Override
148+
public void run() {
149+
if(this.getBuilder().getProject().isDisabled()) {
150+
logger.info("Build Skip.");
151+
} else {
152+
this.stashPullRequestsBuilder.run();
153+
}
154+
this.getDescriptor().save();
155+
}
156+
157+
@Override
158+
public void stop() {
159+
super.stop();
160+
}
161+
162+
public static final class StashBuildTriggerDescriptor extends TriggerDescriptor {
163+
public StashBuildTriggerDescriptor() {
164+
load();
165+
}
166+
167+
@Override
168+
public boolean isApplicable(Item item) {
169+
return true;
170+
}
171+
172+
@Override
173+
public String getDisplayName() {
174+
return "Stash Pull Requests Builder";
175+
}
176+
177+
@Override
178+
public boolean configure(StaplerRequest req, JSONObject json) throws FormException {
179+
save();
180+
return super.configure(req, json);
181+
}
182+
}
183+
}

0 commit comments

Comments
 (0)