Skip to content

Commit c839530

Browse files
authored
Merge pull request e-gineering#129 from Thales-Netherlands/feature/retain-specific-plugins-on-master
Allow explicit configured plugins to execute on master as well
2 parents 7ac1213 + 735ec61 commit c839530

File tree

6 files changed

+164
-19
lines changed

6 files changed

+164
-19
lines changed

README.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -449,8 +449,8 @@ directly from master**. Rather, master is really only used for tracking releases
449449
To accomplish this the `promote-master` goal and a Maven build extension work together.
450450

451451
With the build extension added to your project, any build where the `gitBranchExpression` matches the `masterBranchPattern` or `supportBranchPattern` will have it's
452-
build lifecycle (plugins, goals, etc) altered. Any plugin other than the gitflow-helper-maven-plugin, the maven-deploy-plugin, or plugins with goals
453-
explicitly referenced on the command line will be ignored (removed from the project reactor).
452+
build lifecycle (plugins, goals, etc) altered. Any plugin other than the gitflow-helper-maven-plugin, the maven-deploy-plugin, plugins with goals
453+
explicitly referenced on the command line or those configured explicitly in the `retainPlugins` list, will be ignored (removed from the project reactor).
454454
This allows us to enforce the ideal that code should never be built in the master branch.
455455

456456
The `promote-master` goal executes when the `gitBranchExpression` resolves to a value matching the `masterBranchPattern` or `supportBranchPattern` regular expression.

src/main/java/com/e_gineering/maven/gitflowhelper/AbstractBranchDetectingExtension.java

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
import org.codehaus.plexus.util.xml.Xpp3Dom;
1414

1515
import java.io.IOException;
16+
import java.util.ArrayList;
17+
import java.util.List;
1618
import java.util.Properties;
1719

1820
public abstract class AbstractBranchDetectingExtension extends AbstractMavenLifecycleParticipant {
@@ -34,6 +36,7 @@ public abstract class AbstractBranchDetectingExtension extends AbstractMavenLife
3436
String featureOrBugfixBranchPattern;
3537
String otherDeployBranchPattern;
3638
String otherBranchVersionDelimiter;
39+
List<String> retainPlugins;
3740
GitBranchInfo branchInfo;
3841
Properties systemEnvVars;
3942

@@ -93,6 +96,10 @@ public void afterProjectsRead(MavenSession session) throws MavenExecutionExcepti
9396
if (gitBranchExpression == null) {
9497
gitBranchExpression = extractPluginConfigValue("gitBranchExpression", plugin);
9598
}
99+
100+
if (retainPlugins == null) {
101+
retainPlugins = extractPluginConfigList("retainPlugins", plugin);
102+
}
96103
}
97104
}
98105
}
@@ -145,6 +152,10 @@ public void afterProjectsRead(MavenSession session) throws MavenExecutionExcepti
145152
logger.debug("Using default otherBranchVersionDelimiter.");
146153
otherBranchVersionDelimiter = "+";
147154
}
155+
156+
if (retainPlugins == null) {
157+
logger.debug("No additional plugin executions will be retained on master");
158+
}
148159

149160
ScmUtils scmUtils = new ScmUtils(systemEnvVars, scmManager, session.getTopLevelProject(), new PlexusLoggerToMavenLog(logger), masterBranchPattern, supportBranchPattern, releaseBranchPattern, hotfixBranchPattern, developmentBranchPattern);
150161
branchInfo = scmUtils.resolveBranchInfo(gitBranchExpression);
@@ -168,4 +179,25 @@ private String extractConfigValue(String parameter, Object configuration) {
168179
}
169180
return null;
170181
}
182+
183+
private List<String> extractPluginConfigList(String parameter, Plugin plugin) {
184+
List<String> value = extractConfigList(parameter, plugin.getConfiguration());
185+
for (int i = 0; i < plugin.getExecutions().size() && value == null; i++) {
186+
value = extractConfigList(parameter, plugin.getExecutions().get(i).getConfiguration());
187+
}
188+
return value;
189+
}
190+
191+
private List<String> extractConfigList(String parameter, Object configuration) {
192+
try {
193+
List<String> result = new ArrayList<>();
194+
Xpp3Dom parameterNode = ((Xpp3Dom) configuration).getChild(parameter);
195+
for (int i = 0; i < parameterNode.getChildCount(); i++) {
196+
result.add(parameterNode.getChild(i).getValue());
197+
}
198+
return result;
199+
} catch (Exception ignored) {
200+
}
201+
return null;
202+
}
171203
}

src/main/java/com/e_gineering/maven/gitflowhelper/MasterPromoteExtension.java

Lines changed: 31 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,14 @@
99
import org.codehaus.plexus.component.annotations.Component;
1010

1111
import java.util.ArrayList;
12+
import java.util.Arrays;
13+
import java.util.Collections;
1214
import java.util.HashMap;
15+
import java.util.HashSet;
1316
import java.util.List;
17+
import java.util.Map;
18+
import java.util.Set;
19+
import java.util.stream.Collectors;
1420

1521
/**
1622
* Maven extension which removes (skips) undesired plugins from the build reactor when running on a master branch.
@@ -19,6 +25,15 @@
1925
*/
2026
@Component(role = AbstractMavenLifecycleParticipant.class, hint = "promote-master")
2127
public class MasterPromoteExtension extends AbstractBranchDetectingExtension {
28+
29+
private static final Set<String> PLUGIN_WHITELIST = Collections.unmodifiableSet(
30+
new HashSet<>(
31+
Arrays.asList(
32+
"org.apache.maven.plugins:maven-deploy-plugin",
33+
"com.e-gineering:gitflow-helper-maven-plugin"
34+
)
35+
)
36+
);
2237

2338
@Override
2439
public void afterProjectsRead(final MavenSession session) throws MavenExecutionException {
@@ -41,26 +56,25 @@ public void afterProjectsRead(final MavenSession session) throws MavenExecutionE
4156
}
4257

4358
// Build up a map of plugins to remove from projects, if we're on the master branch.
44-
HashMap<MavenProject, List<Plugin>> pluginsToDrop = new HashMap<>();
59+
Map<MavenProject, List<Plugin>> pluginsToDrop = new HashMap<>();
60+
61+
final List<String> configuredPluginsToRetain;
62+
if (this.retainPlugins != null) {
63+
configuredPluginsToRetain = this.retainPlugins;
64+
} else {
65+
configuredPluginsToRetain = Collections.emptyList();
66+
}
4567

4668
for (MavenProject project : session.getProjects()) {
47-
List<Plugin> dropPlugins = new ArrayList<>();
4869

49-
for (Plugin plugin : project.getModel().getBuild().getPlugins()) {
50-
// Don't drop our plugin.
51-
if (plugin.getKey().equals("com.e-gineering:gitflow-helper-maven-plugin")) {
52-
continue;
53-
// Don't drop things we declare goals for.
54-
} else if (pluginsToRetain.contains(plugin)) {
55-
logger.debug("gitflow-helper-maven-plugin retaining plugin: " + plugin + " from project: " + project.getName());
56-
// Don't drop the maven-deploy-plugin
57-
} else if (plugin.getKey().equals("org.apache.maven.plugins:maven-deploy-plugin")) {
58-
logger.debug("gitflow-helper-maven-plugin retaining plugin: " + plugin + " from project: " + project.getName());
59-
} else {
60-
logger.debug("gitflow-helper-maven-plugin removing plugin: " + plugin + " from project: " + project.getName());
61-
dropPlugins.add(plugin);
62-
}
63-
}
70+
// Create a list of all plugins that are not in the whitelist, not explicitly invoked from the commandline,
71+
// and not configured to be allowed on master/support.
72+
List<Plugin> dropPlugins = project.getModel().getBuild().getPlugins()
73+
.stream()
74+
.filter(plugin -> !PLUGIN_WHITELIST.contains(plugin.getKey()))
75+
.filter(plugin -> !pluginsToRetain.contains(plugin))
76+
.filter(plugin -> !configuredPluginsToRetain.contains(plugin.getKey()))
77+
.collect(Collectors.toList());
6478

6579
pluginsToDrop.put(project, dropPlugins);
6680
}

src/main/java/com/e_gineering/maven/gitflowhelper/PromoteMasterMojo.java

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@
44
import org.apache.maven.plugin.MojoFailureException;
55
import org.apache.maven.plugins.annotations.LifecyclePhase;
66
import org.apache.maven.plugins.annotations.Mojo;
7+
import org.apache.maven.plugins.annotations.Parameter;
8+
9+
import java.util.List;
710

811
/**
912
* If the build is being executed from a DEVELOPMENT, HOTFIX or RELEASE branch, attach an artifact containing a list of
@@ -17,6 +20,15 @@
1720
@Mojo(name = "promote-master", defaultPhase = LifecyclePhase.INSTALL)
1821
public class PromoteMasterMojo extends AbstractGitflowBasedRepositoryMojo {
1922

23+
/**
24+
* List of groupId:artifactId strings that refer to plugins that should be retained while building on master.
25+
*
26+
* Note that this property is listed here for documentation purposes, but it is handled within
27+
* {@link MasterPromoteExtension}.
28+
*/
29+
@Parameter(property = "retainPlugins")
30+
private List<String> retainPlugins;
31+
2032
@Override
2133
protected void execute(final GitBranchInfo gitBranchInfo) throws MojoExecutionException, MojoFailureException {
2234
switch (gitBranchInfo.getType()) {

src/test/java/com/e_gineering/maven/gitflowhelper/MasterSupportBranchIT.java

Lines changed: 52 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,16 @@ public void promotionOfRelease() throws Exception {
7171
// Otherwise, it's the VerificationException from looking for "Compiling", and that's expected to fail.
7272
}
7373

74+
try {
75+
// The flatten-maven-plugin should not activate, fail if it does.
76+
verifier.verifyTextInLog("Generating flattened POM of project");
77+
throw new VerificationException(PROMOTION_FAILED_MESSAGE);
78+
} catch (VerificationException ve) {
79+
if (ve.getMessage().equals(PROMOTION_FAILED_MESSAGE)) {
80+
throw ve;
81+
}
82+
}
83+
7484
verifier.verifyTextInLog(
7585
"gitflow-helper-maven-plugin: Enabling MasterPromoteExtension. GIT_BRANCH: [origin/master] matches masterBranchPattern");
7686
verifier.verifyTextInLog("[INFO] Setting release artifact repository to: [releases]");
@@ -121,4 +131,46 @@ public void dontPruneExplicitlyInvokedPlugins() throws Exception {
121131
verifier.resetStreams();
122132
}
123133
}
134+
135+
@Test
136+
public void dontPruneExplicitlyConfiguredPlugins() throws Exception {
137+
// Create a release version and get it deployed.
138+
Verifier verifier = createVerifier("/project-stub", "origin/release/1.2.0", "1.2.0");
139+
140+
try {
141+
verifier.executeGoal("deploy");
142+
143+
verifier.verifyErrorFreeLog();
144+
} finally {
145+
verifier.resetStreams();
146+
}
147+
148+
// Promote (deploy) from /origin/master
149+
verifier = createVerifier("/project-stub", "origin/master", "1.2.0");
150+
// Activate a profile to enable the retainPlugins configuration
151+
verifier.addCliOption("-Pretain-configuration");
152+
try {
153+
verifier.executeGoal("deploy");
154+
155+
try {
156+
verifier.verifyTextInLog("Compiling");
157+
throw new VerificationException(PROMOTION_FAILED_MESSAGE);
158+
} catch (VerificationException ve) {
159+
if (ve.getMessage().equals(PROMOTION_FAILED_MESSAGE)) {
160+
throw ve;
161+
}
162+
// Otherwise, it's the VerificationException from looking for "Compiling", and that's expected to fail.
163+
}
164+
165+
verifier.verifyTextInLog("Generating flattened POM of project"); // This should still be there.
166+
verifier.verifyTextInLog(
167+
"gitflow-helper-maven-plugin: Enabling MasterPromoteExtension. GIT_BRANCH: [origin/master] matches masterBranchPattern");
168+
verifier.verifyTextInLog("[INFO] Setting release artifact repository to: [releases]");
169+
verifier.verifyTextInLog(
170+
"[INFO] Resolving & Reattaching existing artifacts from stageDeploymentRepository [test-releases");
171+
verifier.verifyErrorFreeLog();
172+
} finally {
173+
verifier.resetStreams();
174+
}
175+
}
124176
}

src/test/resources/project-stub/pom.xml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -118,7 +118,42 @@
118118
<version>4.2.0</version>
119119
<extensions>true</extensions>
120120
</plugin>
121+
<plugin>
122+
<groupId>org.codehaus.mojo</groupId>
123+
<artifactId>flatten-maven-plugin</artifactId>
124+
<version>1.2.2</version>
125+
<executions>
126+
<execution>
127+
<goals>
128+
<goal>flatten</goal>
129+
</goals>
130+
<phase>process-resources</phase>
131+
</execution>
132+
</executions>
133+
</plugin>
121134
</plugins>
122135
</build>
123136

137+
<profiles>
138+
<profile>
139+
<id>retain-configuration</id>
140+
<build>
141+
<pluginManagement>
142+
<plugins>
143+
<plugin>
144+
<groupId>com.e-gineering</groupId>
145+
<artifactId>gitflow-helper-maven-plugin</artifactId>
146+
<version>${version.gitflow.plugin}</version>
147+
<configuration>
148+
<retainPlugins>
149+
<retainPlugin>org.codehaus.mojo:flatten-maven-plugin</retainPlugin>
150+
</retainPlugins>
151+
</configuration>
152+
</plugin>
153+
</plugins>
154+
</pluginManagement>
155+
</build>
156+
</profile>
157+
</profiles>
158+
124159
</project>

0 commit comments

Comments
 (0)