Skip to content

Commit

Permalink
Browse files Browse the repository at this point in the history
Support for ciManagement maven notifications.
In order to enable ciManagement maven notifications you have to check the
option "E-mail Notification" into the section "Build Settings" from the
job, and add a ciManagement section to the pom.xml with the following
settings:

ciManagement
|-- system=hudson (you have to put "hudson" here )
|-- ur=http://serverurl/
|-- notifiers
|----- notifier
|-------- type=mail (you have to put "mail" here)
|-------- sendOnError=true
|-------- sendOnFailure=true
|-------- sendOnSuccess>false
|-------- sendOnWarning>false
|-------- configuration
|------------ recipients=some.email@domain.org (recipients have the same
format than the same field in the Job configuration page)

You can override this configuration in any module of the maven proyect.

[FIXED JENKINS-1201]
[FIXED JENKINS-6421]
  • Loading branch information
mrebasti committed Oct 7, 2013
1 parent 53987d1 commit 2f924d8
Show file tree
Hide file tree
Showing 7 changed files with 246 additions and 40 deletions.
94 changes: 75 additions & 19 deletions src/main/java/hudson/maven/MavenModule.java
Expand Up @@ -25,6 +25,7 @@

import com.google.common.collect.HashMultimap;
import com.google.common.collect.Multimap;

import hudson.CopyOnWrite;
import hudson.Functions;
import hudson.Util;
Expand All @@ -48,21 +49,26 @@
import hudson.util.AlternativeUiTextProvider;
import hudson.util.DescribableList;
import jenkins.model.Jenkins;

import org.apache.maven.model.Notifier;
import org.apache.maven.project.MavenProject;
import org.kohsuke.stapler.StaplerRequest;
import org.kohsuke.stapler.StaplerResponse;
import org.kohsuke.stapler.export.Exported;

import javax.servlet.ServletException;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;
import java.util.TreeSet;
import java.util.logging.Level;
import java.util.logging.Logger;

Expand Down Expand Up @@ -192,8 +198,9 @@ public List<MavenModule> getSubsidiaries() {
* <p>
* This method is invoked on {@link MavenModule} that has the matching
* {@link ModuleName}.
* @throws IOException
*/
/*package*/ void reconfigure(PomInfo pom) {
/*package*/ void reconfigure(PomInfo pom) throws IOException {
this.displayName = pom.displayName;
this.version = pom.version;
this.packaging = pom.packaging;
Expand All @@ -202,21 +209,61 @@ public List<MavenModule> getSubsidiaries() {
this.children = pom.children;
this.nestLevel = pom.getNestLevel();
disabled = false;

if (pom.mailNotifier != null) {
MavenReporter reporter = getReporters().get(MavenMailer.class);
if (reporter != null) {
MavenMailer mailer = (MavenMailer) reporter;
mailer.dontNotifyEveryUnstableBuild = !pom.mailNotifier.isSendOnFailure();
String recipients = pom.mailNotifier.getConfiguration().getProperty("recipients");
if (recipients != null) {
mailer.recipients = recipients;
}
}

MavenMailer projectMailer = getParent().getReporters() == null? null: getParent().getReporters().get(MavenMailer.class);
if (projectMailer != null) {
Notifier notifier = getCiManagementNotifier(pom);
if (notifier != null) {
MavenMailer mailer;

if (pom.parent == null) {//If isModuleRoot then..
mailer = projectMailer;
} else {
mailer = getOrCreateMavenMailer(pom);
}

mailer.perModuleEmail = projectMailer.perModuleEmail;
mailer.dontNotifyEveryUnstableBuild = !notifier.isSendOnFailure();

String recipients = notifier.getConfiguration().getProperty("recipients");

mailer.recipients = projectMailer.recipients;
mailer.mavenRecipients = recipients;
} else {
getReporters().remove(MavenMailer.class);
}
} else {
// When "E-mail Notification" is unchecked then I remove the
// MavenMailer from the modules.
if (getReporters() != null) {
getReporters().remove(MavenMailer.class);
}
}
}

/**
private MavenMailer getOrCreateMavenMailer(PomInfo pom) {
MavenMailer mavenMailer = getReporters().get(MavenMailer.class);
if (mavenMailer == null) {
mavenMailer = new MavenMailer();
getReporters().add(mavenMailer);
}

return mavenMailer;
}

private Notifier getCiManagementNotifier(PomInfo pom) {
Notifier notifier = null;

if (pom.mailNotifier != null) {
notifier = pom.mailNotifier;
} else if (pom.parent != null) {
notifier = getCiManagementNotifier(pom.parent);
}

return notifier;
}

/**
* Returns if the given POM likely describes the same module with the same dependencies.
* Implementation needs not be 100% accurate in the true case, but it MUST return false
* if is not the same.
Expand Down Expand Up @@ -662,20 +709,29 @@ protected void performDelete() throws IOException, InterruptedException {
* Creates a list of {@link MavenReporter}s to be used for a build of this project.
*/
protected List<MavenReporter> createReporters() {
List<MavenReporter> reporterList = new ArrayList<MavenReporter>();

getReporters().addAllTo(reporterList);
getParent().getReporters().addAllTo(reporterList);
Set<MavenReporter> reporterSet = new TreeSet<MavenReporter>(new Comparator<MavenReporter>() {
@Override
public int compare(MavenReporter o1, MavenReporter o2) {
if (o1.getClass() == o2.getClass()) {
return 0;
}
return 1;
}
});

getReporters().addAllTo(reporterSet);
getParent().getReporters().addAllTo(reporterSet);


for (MavenReporterDescriptor d : MavenReporterDescriptor.all()) {
if(getReporters().contains(d))
continue; // already configured
MavenReporter auto = d.newAutoInstance(this);
if(auto!=null)
reporterList.add(auto);
reporterSet.add(auto);
}

return reporterList;
return new ArrayList<MavenReporter>(reporterSet);
}

/**
Expand Down
2 changes: 1 addition & 1 deletion src/main/java/hudson/maven/MavenModuleSetBuild.java
Expand Up @@ -1032,7 +1032,7 @@ protected void post2(BuildListener listener) throws Exception {
public void cleanUp(BuildListener listener) throws Exception {
MavenMailer mailer = project.getReporters().get(MavenMailer.class);
if (mailer != null) {
new MailSender(mailer.recipients,
new MailSender(mailer.getAllRecipients(),
mailer.dontNotifyEveryUnstableBuild,
mailer.sendToIndividuals).execute(MavenModuleSetBuild.this, listener);
}
Expand Down
9 changes: 8 additions & 1 deletion src/main/java/hudson/maven/reporters/MavenMailer.java
Expand Up @@ -46,16 +46,23 @@ public class MavenMailer extends MavenReporter {
* @see Mailer
*/
public String recipients;
public String mavenRecipients;
public boolean dontNotifyEveryUnstableBuild;
public boolean sendToIndividuals;
public boolean perModuleEmail;

public boolean end(MavenBuild build, Launcher launcher, BuildListener listener) throws InterruptedException, IOException {
if(perModuleEmail) {
new MailSender(recipients,dontNotifyEveryUnstableBuild,sendToIndividuals).execute(build,listener);
new MailSender(getAllRecipients(),dontNotifyEveryUnstableBuild,sendToIndividuals).execute(build,listener);
}
return true;
}

public String getAllRecipients() {
return this.recipients == null ?
this.mavenRecipients :
this.recipients + " " + this.mavenRecipients;

This comment has been minimized.

Copy link
@mrebasti

mrebasti Oct 23, 2013

Author Contributor

this line seems to be causing JENKINS-20209. I'll do some tests and send a fix.

}

@Extension
public static final class DescriptorImpl extends MavenReporterDescriptor {
Expand Down
28 changes: 17 additions & 11 deletions src/test/java/hudson/maven/MavenModuleTest.java
Expand Up @@ -10,6 +10,7 @@
import hudson.model.DependencyGraph;
import hudson.model.MockHelper;

import java.io.IOException;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
Expand Down Expand Up @@ -38,7 +39,7 @@ public class MavenModuleTest {
private MavenProject project;

@Before
public void before() {
public void before() throws IOException {
suppress(constructor(AbstractProject.class));
suppress(constructor(DescriptorImpl.class));

Expand All @@ -58,10 +59,11 @@ public void before() {
/**
* Tests that a {@link MavenModule} which builds a plugin is recognized as a snapshot
* dependency in another module using that plugin.
* @throws IOException
*/
@Test
@Bug(10530)
public void testMavenModuleAsPluginDependency() {
public void testMavenModuleAsPluginDependency() throws IOException {
MavenModule pluginModule = createPluginProject();

addModuleAsPluginDependency(this.module, pluginModule);
Expand All @@ -78,7 +80,7 @@ public void testMavenModuleAsPluginDependency() {
Assert.assertSame(this.module, downstream.get(0));
}

private static void addModuleAsPluginDependency(MavenModule module, MavenModule pluginModule) {
private static void addModuleAsPluginDependency(MavenModule module, MavenModule pluginModule) throws IOException {
Build build = new Build();
Plugin plugin = new Plugin();
plugin.setGroupId(pluginModule.getModuleName().groupId);
Expand All @@ -96,7 +98,7 @@ private static void addModuleAsPluginDependency(MavenModule module, MavenModule
module.reconfigure(new PomInfo(project, null, "relPath"));
}

private static MavenModule createPluginProject() {
private static MavenModule createPluginProject() throws IOException {
MavenModule pluginModule = mock(MavenModule.class);
basicMocking(pluginModule);

Expand All @@ -112,7 +114,7 @@ private static MavenModule createPluginProject() {
return pluginModule;
}

private static void basicMocking(MavenModule mock) {
private static void basicMocking(MavenModule mock) throws IOException {
when(mock.isBuildable()).thenReturn(Boolean.TRUE);
doCallRealMethod().when(mock).reconfigure(Matchers.any(PomInfo.class));
doCallRealMethod().when(mock).buildDependencyGraph(Matchers.any(DependencyGraph.class));
Expand All @@ -129,9 +131,10 @@ private static void basicMocking(MavenModule mock) {
}
/**
* This test is a standard project that has a versioned dependency.
* @throws IOException
*/
@Test
public void testSimpleVersion() {
public void testSimpleVersion() throws IOException {
TestComponents testComponents = createTestComponents("1.0.1-SNAPSHOT");

DependencyGraph graph = testComponents.graph;
Expand All @@ -154,9 +157,10 @@ public void testSimpleVersion() {
/**
* This tests that a version range declaration in the dependency of a top level project
* resolves the up and downstream correctly.
* @throws IOException
*/
@Test
public void testSimpleVersionRange() {
public void testSimpleVersionRange() throws IOException {
TestComponents testComponents = createTestComponents("[1.0.0, )");

DependencyGraph graph = testComponents.graph;
Expand All @@ -179,9 +183,10 @@ public void testSimpleVersionRange() {
/**
* Test multiple projects with dependencies on differing library versions declared with
* multiple version definitions.
* @throws IOException
*/
@Test
public void testMultipleDependencies() {
public void testMultipleDependencies() throws IOException {

MavenProject projectA = createMavenProject("ProjectA", "test", "projectA", "1.0-SNAPSHOT", "jar");
Dependency dependencyA = createDependency("test", "library", "[1.0, 2.0)");
Expand Down Expand Up @@ -237,9 +242,10 @@ public void testMultipleDependencies() {
/**
* This tests a project that has a dependency on a specific version of X.
* The project X has moved on and so should not have any dependencies on ProjectA.
* @throws IOException
*/
@Test
public void testProjectWithSpecifiedVersionAndNoDependencies() {
public void testProjectWithSpecifiedVersionAndNoDependencies() throws IOException {
MavenProject projectA = createMavenProject("ProjectA", "test", "projectA", "1.0-SNAPSHOT", "jar");
Dependency dependencyA = createDependency("test", "library", "1.0");
projectA.getDependencies().add(dependencyA);
Expand Down Expand Up @@ -280,7 +286,7 @@ public void testProjectWithSpecifiedVersionAndNoDependencies() {
Assert.assertEquals(0, upstreamX.size());
}

private TestComponents createTestComponents(String libraryVersion) {
private TestComponents createTestComponents(String libraryVersion) throws IOException {
MavenProject appProject = createMavenProject("testapp", "test", "application", "1.0-SNAPSHOT", "jar");
Dependency dependency = createDependency("test", "library", libraryVersion);
appProject.getDependencies().add(dependency);
Expand Down Expand Up @@ -319,7 +325,7 @@ private static void enhanceMavenModuleMock(MavenModule module,
when(module.getAllMavenModules()).thenReturn(allProjects);
}

private static MavenModule mockMavenModule(MavenProject project) {
private static MavenModule mockMavenModule(MavenProject project) throws IOException {
MavenModule mavenModule = mock(MavenModule.class);
when(mavenModule.getName()).thenReturn(project.getName());
basicMocking(mavenModule);
Expand Down

2 comments on commit 2f924d8

@kutzi
Copy link
Member

@kutzi kutzi commented on 2f924d8 Oct 23, 2013

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@mrebasti
Copy link
Contributor Author

@mrebasti mrebasti commented on 2f924d8 Oct 23, 2013 via email

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please sign in to comment.