Skip to content

Commit

Permalink
Merge branch 'master' of github.com:groupon/DotCi
Browse files Browse the repository at this point in the history
  • Loading branch information
suryagaddipati committed Nov 22, 2015
2 parents 533f9ca + 654b422 commit 9edbb32
Show file tree
Hide file tree
Showing 12 changed files with 480 additions and 91 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -54,12 +54,11 @@ public BuildConfiguration(Map config) {
this.config = config;
}

public ShellCommands getBeforeRunCommandWithCheckoutIfPresent(Map<String, Object> dotCiEnvVars) {
public ShellCommands getBeforeRunCommandIfPresent() {
if (!config.containsKey("before_run")) {
return null;
}
ShellCommands shellCommands = new ShellCommands();
shellCommands.add(getCheckoutCommands(dotCiEnvVars));
shellCommands.add(String.format("sh -xc '%s'", SHELL_ESCAPE.escape((String) config.get("before_run"))));
return shellCommands;
}
Expand All @@ -70,7 +69,7 @@ public ShellCommands getCommands(Combination combination, Map<String, Object> do
String fileName = getDockerComposeFileName();

ShellCommands shellCommands = new ShellCommands();
shellCommands.add(getCheckoutCommands(dotCiEnvVars));
shellCommands.add(BuildConfiguration.getCheckoutCommands(dotCiEnvVars));

if (config.containsKey("before_run") && !isParallelized()) {
shellCommands.add(String.format("sh -xc '%s'", SHELL_ESCAPE.escape((String) config.get("before_run"))));
Expand Down Expand Up @@ -147,7 +146,8 @@ public List<PostBuildNotifier> getNotifiers() {
public String getDockerComposeFileName() {
return config.get("docker-compose-file") !=null ? (String) config.get("docker-compose-file") : "docker-compose.yml";
}
private ShellCommands getCheckoutCommands(Map<String, Object> dotCiEnvVars) {

public static ShellCommands getCheckoutCommands(Map<String, Object> dotCiEnvVars) {
String gitCloneUrl = (String) dotCiEnvVars.get("DOTCI_DOCKER_COMPOSE_GIT_CLONE_URL");
GitUrl gitRepoUrl = new GitUrl(gitCloneUrl);
boolean isPrivateRepo = Boolean.parseBoolean((String) dotCiEnvVars.get("DOTCI_IS_PRIVATE_REPO"));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -35,9 +35,11 @@
import com.groupon.jenkins.dynamic.build.execution.SubBuildRunner;
import com.groupon.jenkins.dynamic.build.execution.SubBuildScheduler;
import com.groupon.jenkins.dynamic.buildtype.BuildType;
import com.groupon.jenkins.git.GitUrl;
import com.groupon.jenkins.notifications.PostBuildNotifier;
import com.groupon.jenkins.util.GroovyYamlTemplateProcessor;
import hudson.Extension;
import hudson.FilePath;
import hudson.Launcher;
import hudson.matrix.Combination;
import hudson.model.BuildListener;
Expand All @@ -48,6 +50,8 @@
import java.util.List;
import java.util.Map;

import static java.lang.String.format;

@Extension
public class DockerComposeBuild extends BuildType implements SubBuildRunner {
private BuildConfiguration buildConfiguration;
Expand All @@ -60,11 +64,16 @@ public String getDescription() {
@Override
public Result runBuild(DynamicBuild build, BuildExecutionContext buildExecutionContext, Launcher launcher, BuildListener listener) throws IOException, InterruptedException {
Map<String,Object> buildEnvironment = build.getEnvironmentWithChangeSet(listener);

Result result = doCheckout(buildEnvironment, buildExecutionContext, listener);
if (!Result.SUCCESS.equals(result)) {
return result;
}

Map config = new GroovyYamlTemplateProcessor(getDotCiYml(build), buildEnvironment).getConfig();
this.buildConfiguration = new BuildConfiguration(config);
build.setAxisList(buildConfiguration.getAxisList());

Result result;
if(buildConfiguration.isParallelized()){
result = runParallelBuild(build, buildExecutionContext, buildConfiguration, listener);
}else{
Expand All @@ -82,17 +91,23 @@ public Result runSubBuild(Combination combination, BuildExecutionContext buildEx
return runCommands(commands, buildExecutionContext, listener);
}

private Result doCheckout(Map<String,Object> buildEnvironment, BuildExecutionContext buildExecutionContext, BuildListener listener) throws IOException, InterruptedException {
ShellCommands commands = BuildConfiguration.getCheckoutCommands(buildEnvironment);
return runCommands(commands, buildExecutionContext, listener);
}

private Result runCommands(ShellCommands commands, BuildExecutionContext buildExecutionContext, BuildListener listener) throws IOException, InterruptedException {
ShellScriptRunner shellScriptRunner = new ShellScriptRunner(buildExecutionContext, listener);
return shellScriptRunner.runScript(commands);
}

private String getDotCiYml(DynamicBuild build) throws IOException {
try {
return build.getGithubRepositoryService().getGHFile(".ci.yml", build.getSha()).getContent();
} catch (FileNotFoundException _){
private String getDotCiYml(DynamicBuild build) throws IOException, InterruptedException {
FilePath fp = new FilePath(build.getWorkspace(), ".ci.yml");
if (!fp.exists()) {
throw new InvalidBuildConfigurationException("No .ci.yml found.");
}

return fp.readToString();
}

private Result runParallelBuild(final DynamicBuild dynamicBuild, final BuildExecutionContext buildExecutionContext, final BuildConfiguration buildConfiguration, final BuildListener listener) throws IOException, InterruptedException {
Expand Down Expand Up @@ -122,7 +137,7 @@ public void runFinished(DynamicSubBuild subBuild) throws IOException {
}

private Result runBeforeCommands(final BuildExecutionContext buildExecutionContext, final BuildListener listener) throws IOException, InterruptedException {
ShellCommands beforeCommands = buildConfiguration.getBeforeRunCommandWithCheckoutIfPresent(buildExecutionContext.getBuildEnvironmentVariables());
ShellCommands beforeCommands = buildConfiguration.getBeforeRunCommandIfPresent();
if (beforeCommands != null) {
return runCommands(beforeCommands, buildExecutionContext, listener);
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -115,12 +115,6 @@ public boolean shouldBuildTags() {
return getProperty(BuildTagsProperty.class)!=null && getProperty(BuildTagsProperty.class).isShouldBuildTags();
}

public boolean shouldBuildPullRequestFromSameRepo() {
PullRequestRebuildProperty buildPrProperty = getProperty(PullRequestRebuildProperty.class);
return buildPrProperty !=null && buildPrProperty.shouldRebuildPullRequestsFromSameRepo();

}

public static final class DescriptorImpl extends AbstractProjectDescriptor {
/**
* We are hiding the "DotCI" project from "/newJob" page, because we'll
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -23,11 +23,11 @@
*/
package com.groupon.jenkins.dynamic.build;

import hudson.*;
import hudson.model.*;
import net.sf.json.*;
import org.kohsuke.stapler.*;

@Deprecated
public class PullRequestRebuildProperty extends JobProperty<Job<?, ?>> {

private final boolean buildPullRequestsFromSameRepo;
Expand All @@ -41,7 +41,6 @@ public boolean shouldRebuildPullRequestsFromSameRepo() {
}


@Extension
public static final class PullRequestRebuildPropertyDescriptor extends JobPropertyDescriptor {

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,7 @@ public void processGitHubPayload(String payloadData) {
LOGGER.info("Received kicking off build for " + payload.getProjectUrl());
for (final DynamicProject job : makeDynamicProjectRepo().getJobsFor(payload.getProjectUrl())) {

if (payload.needsBuild(job.shouldBuildTags(), job.shouldBuildPullRequestFromSameRepo())) {
if (payload.needsBuild(job.shouldBuildTags())) {
LOGGER.info("starting job" + job.getName());
queue.execute(new Runnable() {
@Override
Expand Down
21 changes: 7 additions & 14 deletions src/main/java/com/groupon/jenkins/github/Payload.java
Original file line number Diff line number Diff line change
Expand Up @@ -76,26 +76,25 @@ public String getBranch() {
return payloadJson.getString("ref").replaceAll("refs/", "").replaceAll("heads/", "");
}

public boolean needsBuild(boolean shouldBuildTags, boolean buildPrsFromSameRepo) {
public boolean needsBuild(boolean shouldBuildTags) {
if (payloadJson.has("ref") && payloadJson.getString("ref").startsWith("refs/tags/")) {
return shouldBuildTags;
}
if (isPullRequest()) {
return shouldBuildPullRequest(buildPrsFromSameRepo);
return shouldBuildPullRequest();
}
return !payloadJson.getBoolean("deleted");
}

private boolean shouldBuildPullRequest(boolean buildPrsFromSameRepo) {
private boolean shouldBuildPullRequest() {
return !isPullRequestClosed() &&
shouldBuildPullRequestBasedOnAction() &&
( buildPrsFromSameRepo || !isPullRequestFromWithinSameRepo());
shouldBuildPullRequestBasedOnAction();
}

//only build for webhook actions of "opened", "reopened", or "synchronize"
//https://developer.github.com/v3/activity/events/types/#events-api-payload-17
private boolean shouldBuildPullRequestBasedOnAction() {
return isOpenedAction() || isReOpenedAction() || isSynchronizeAction();
return isOpenedAction() || isReOpenedAction() || isSynchronizeAction();
}

private boolean isPullRequestClosed() {
Expand All @@ -107,17 +106,11 @@ private boolean isOpenedAction() {
}

private boolean isReOpenedAction() {
return isPullRequest() && "reopened".equals(payloadJson.getString("action"));
return isPullRequest() && "reopened".equals(payloadJson.getString("action"));
}

private boolean isSynchronizeAction() {
return isPullRequest() && "synchronize".equals(payloadJson.getString("action"));
}

private boolean isPullRequestFromWithinSameRepo() {
String headRepoUrl = getPullRequest().getJSONObject("head").getJSONObject("repo").getString("ssh_url");
String pullRequestRepoUrl = getPullRequest().getJSONObject("base").getJSONObject("repo").getString("ssh_url");
return headRepoUrl.equals(pullRequestRepoUrl);
return isPullRequest() && "synchronize".equals(payloadJson.getString("action"));
}

public String getPullRequestSourceBranch() {
Expand Down

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -77,15 +77,10 @@ public void should_run_before_run_command_in_before_run_if_present(){
}

@Test
public void should_run_before_run_with_checkout_command_with_non_parallel_build(){
public void should_run_before_run_with_parallel_build(){
BuildConfiguration buildConfiguration = new BuildConfiguration(ImmutableMap.of("before_run", "before_run cmd", "run", of("unit", "command", "integration", "integration")));
ShellCommands commands = buildConfiguration.getBeforeRunCommandWithCheckoutIfPresent(getEnvVars());
Assert.assertEquals("chmod -R u+w . ; find . ! -path \"./deploykey_rsa.pub\" ! -path \"./deploykey_rsa\" -delete", commands.get(0));
Assert.assertEquals("git init", commands.get(1));
Assert.assertEquals("git remote add origin [email protected]:groupon/DotCi.git", commands.get(2));
Assert.assertEquals("git fetch origin master", commands.get(3));
Assert.assertEquals("git reset --hard abc123", commands.get(4));
Assert.assertEquals("sh -xc 'before_run cmd'", commands.get(6));
ShellCommands commands = buildConfiguration.getBeforeRunCommandIfPresent();
Assert.assertEquals("sh -xc 'before_run cmd'", commands.get(0));
}

@Test
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ protected void kickOffBuildTrigger(StaplerRequest request, DynamicProject projec

DynamicProjectRepository projectRepo = mock(DynamicProjectRepository.class);

when(payload.needsBuild(false,false)).thenReturn(true);
when(payload.needsBuild(false)).thenReturn(true);
when(payload.getProjectUrl()).thenReturn("git@repo");
when(projectRepo.getJobsFor("git@repo")).thenReturn(newArrayList(projectForRepo));

Expand Down
39 changes: 19 additions & 20 deletions src/test/java/com/groupon/jenkins/github/PayloadTest.java
Original file line number Diff line number Diff line change
Expand Up @@ -71,52 +71,51 @@ public void testProjectPullRequestUnmergableBranch() throws IOException {
@Test
public void testProjectPushDeleteBranch() throws IOException {
Payload payload = new Payload(readFile("push_delete.json"));
assertFalse(payload.needsBuild(false,false));
assertFalse(payload.needsBuild(false));
}

@Test
public void pullRequestLabeledShouldNotTriggerABuild() throws IOException {
Payload payload = new Payload(readFile("pull_request_labeled.json"));
assertFalse(payload.needsBuild(false,true));
public void pullRequestOpenedShouldTriggerABuild() throws IOException {
Payload payload = new Payload(readFile("pull_request_opened.json"));
assertTrue(payload.needsBuild(false));
}

@Test
public void pullRequestReopenedShouldTriggerABuild() throws IOException {
String payloadReq = readFile("pull_request_reopened.json");
Payload payload = new Payload(payloadReq);
assertTrue(payload.needsBuild(false, true));
assertTrue(payload.needsBuild(false));
}

@Test
public void testNonDeletePushShouldTriggerAbuild() throws IOException {
Payload payload = new Payload(readFile("push.json"));
assertTrue(payload.needsBuild(false,false));
public void pullRequestSynchronizeShouldTriggerABuild() throws IOException {
String payloadReq = readFile("pull_request_synchronized.json");
Payload payload = new Payload(payloadReq);
assertTrue(payload.needsBuild(false));
}

@Test
public void pullRequestFromTheSameRepoShouldNotTriggerABuild() throws IOException {
String payloadReq = readFile("pull_request_from_the_same_repo.json");
Payload payload = new Payload(payloadReq);
assertFalse(payload.needsBuild(false,false));
public void pullRequestLabeledShouldNotTriggerABuild() throws IOException {
Payload payload = new Payload(readFile("pull_request_labeled.json"));
assertFalse(payload.needsBuild(false));
}

@Test
public void pullRequestFromTheSameRepoShouldTriggerABuildIfAllowed() throws IOException {
String payloadReq = readFile("pull_request_from_the_same_repo.json");
Payload payload = new Payload(payloadReq);
assertTrue(payload.needsBuild(false, true));
public void testNonDeletePushShouldTriggerAbuild() throws IOException {
Payload payload = new Payload(readFile("push.json"));
assertTrue(payload.needsBuild(false));
}

@Test
public void pullRequestFromForkShouldTriggerABuild() throws IOException {
Payload payload = new Payload(readFile("pull_request_from_fork.json"));
assertTrue(payload.needsBuild(false,false));
assertTrue(payload.needsBuild(false));
}

@Test
public void closedPullRequestFromForkShouldNotTriggerABuild() throws IOException {
Payload payload = new Payload(readFile("pull_request_from_fork_closed.json"));
assertFalse(payload.needsBuild(false,false));
assertFalse(payload.needsBuild(false));
}

@Test
Expand Down Expand Up @@ -172,12 +171,12 @@ public void branchDescriptionForPullRequest() throws IOException {
@Test
public void should_not_build_tags() throws IOException {
Payload payload = new Payload(readFile("push_tags.json"));
Assert.assertFalse(payload.needsBuild(false,false));
Assert.assertFalse(payload.needsBuild(false));
}
@Test
public void should_build_tags_if_specified_in_project_config() throws IOException {
Payload payload = new Payload(readFile("push_tags.json"));
Assert.assertTrue(payload.needsBuild(true,false));
Assert.assertTrue(payload.needsBuild(true));
}

@Test
Expand Down
Loading

0 comments on commit 9edbb32

Please sign in to comment.