-
Notifications
You must be signed in to change notification settings - Fork 0
Implementing Custom Processing Steps
The implementation of custom processing steps can be useful if you require a certain functionality which serves a special task that must be performed often in your projects. You can add the jar with your steps to the plugin dependencies and include it into your custom workflow.
This possibility is no special feature of the unleash-maven-plugin but is part of its underlying base library Maven CDI Plugin Utils which enables CDI-based dependency injection as well as the workflow-based processing model for Maven plugins. There are also Wiki pages that explain Processing Steps and the Execution Context in detail. The following example implements a simple processing step that injects some basic data and processes some data retrieved from the execution context.
package com.itemis.maven.plugins.unleash.steps.actions;
import jakarta.inject.Inject;
import org.apache.maven.plugin.MojoExecutionException;
import org.apache.maven.plugin.MojoFailureException;
import org.apache.maven.project.MavenProject;
import com.itemis.maven.plugins.cdi.CDIMojoProcessingStep;
import com.itemis.maven.plugins.cdi.ExecutionContext;
import com.itemis.maven.plugins.cdi.annotations.ProcessingStep;
import com.itemis.maven.plugins.cdi.annotations.RollbackOnError;
import com.itemis.maven.plugins.cdi.logging.Logger;
@ProcessingStep(id = "sample", description = "A sample step that only prints out some data.")
public class SampleStep implements CDIMojoProcessingStep {
@Inject
private MavenProject project;
@Inject
private Logger log;
private int state;
@Override
public void execute(ExecutionContext context) throws MojoExecutionException, MojoFailureException {
this.log.info("This is the current project: " + this.project.getGroupId() + ':' + this.project.getArtifactId() + ':'
+ this.project.getVersion());
if (context.hasUnmappedData()) {
this.log.info("This step has unmapped execution data!");
for (String date : context.getUnmappedData()) {
this.log.debug("\t" + date);
}
}
if (context.hasMappedData()) {
this.log.info("This step has mapped execution data!");
for (String key : context.getMappedDataKeys()) {
this.log.debug("\t" + key + '=' + context.getMappedDate(key));
}
}
// put something in the state for later rollback
this.state = 42;
}
@RollbackOnError
public void rollback(ExecutionContext context, Throwable t) {
this.log.info("Rolling back sample step for project: " + this.project.getGroupId() + ':'
+ this.project.getArtifactId() + ':' + this.project.getVersion());
this.log.info("Internal state is: " + this.state);
if (context.hasUnmappedRollbackData()) {
this.log.info("This step has unmapped rollback data!");
for (String date : context.getUnmappedRollbackData()) {
this.log.debug("\t" + date);
}
}
if (context.hasMappedRollbackData()) {
this.log.info("This step has mapped rollback data!");
for (String key : context.getMappedRollbackDataKeys()) {
this.log.debug("\t" + key + '=' + context.getMappedRollbackDate(key));
}
}
}
}Although this implementation should be pretty self-explanatory here are some basic notes about it:
- The step must implement the interface
CDIMojoProcessingStepand must carry the annotationProcessingStepproviding at least the id of the step. - You can use CDI injection to inject data into your step that is provided by the plugin but be careful since this this can restrict the portability of your step massively as different plugins and even different goals produce different data for injection. In order to stay generic you should only inject data produced by the CDI base library and use dynamic data provided by the execution context.
- The step may keep state collected during the regular processing phase. This state can later be used if a rollback is necessary.
- The execution of the step prints out all dynamic data provided by the execution context, mapped and unmapped data. For more information please refer to the Execution Context Wiki page of the base plugin.
- The step also provides a rollback method which is triggered automatically if en exception is caught and the step has already been processed. There it prints all data specific to the rollback logic. Rollback methods can be customized to be triggered only under certain conditions. More about rollback is available here.
After implementing the step you will have to build a JAR and set it as a dependency to the list of plugin dependencies of the unleash-maven-plugin:
<project>
...
<build>
<pluginManagement>
<plugins>
<plugin>
<groupId>io.github.mavenplugins</groupId>
<artifactId>unleash-maven-plugin</artifactId>
<version>3.3.2</version>
<dependencies>
<dependency>
<groupId>org.example</groupId>
<artifactId>your-processing-hooks</artifactId>
<version>1.0.0</version>
</dependency>
</dependencies>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>After that you can check if your step implementation is correct by listing all available processing steps:
mvn unleash:perform -DprintSteps
This prints a table with all available steps like this one:
┌────────────────────┬──────────────────────────────────────────────────┬──────────┐
│ ID │ DESCRIPTION │ REQUIRES │
│ │ │ ONLINE │
╞════════════════════╪══════════════════════════════════════════════════╪══════════╡
│ ... │ ... │ ... │
├────────────────────┼──────────────────────────────────────────────────┼──────────┤
│ sample │ A sample step that only prints out some data. │ true │
├────────────────────┼──────────────────────────────────────────────────┼──────────┤
│ ... │ ... │ ... │
└────────────────────┴──────────────────────────────────────────────────┴──────────┘
If your step is listed there you can integrate into your custom workflow. Your custom workflow should only modify the default workflow which can be retrieved by calling:
mvn unleash:perform -DprintWorkflow
Integrating the step into the workflow could look like this:
storeScmRevision
sample
checkProjectVersions
checkParentVersions
checkDependencies
checkPlugins
checkPluginDependencies
prepareVersions
checkAether
setReleaseVersions
addSpyPlugin
buildReleaseArtifacts
removeSpyPlugin
checkForScmChanges
tagScm
detectReleaseArtifacts
setDevVersion
installArtifacts
deployArtifacts
In order to use the our custom workflow which integrates our processing step implementation we will have to call the plugin goal and pass-in the workflow which overrides the default one:
mvn unleash:perform -Dworkflow=<path_to_workflow_file>
This will process the workflow with the sample step at second position. The output should be something like this:
...
[INFO] 08:46:17,146 This is the current project: org.example:test-project:0.0.1
...
If we now want to provide some additional data for the step we can do this using system properties:
mvn unleash:perform -Dworkflow=<path_to_workflow_file> -Dsample="unmapped-date 1,unmapped-date 2,key1=>mapped-date1,key2=>mapped-date2" -Dsample-rollback="rollback-data,rb-key1=>rollback-map-data1" -X
This will result in an output like this one:
...
[INFO] 08:46:17,146 This is the current project: org.example:test-project:0.0.1
[INFO] 08:46:17,148 This step has unmapped execution data!
[DEBUG] 08:46:17,149 unmapped-date 1
[DEBUG] 08:46:17,150 unmapped-date 2
[INFO] 08:46:17,152 This step has mapped execution data!
[DEBUG] 08:46:17,153 key1=mapped-date1
[DEBUG] 08:46:17,154 key2=mapped-date2
...
[INFO] 08:46:43,309 Rolling back sample step for project: org.example:test-project:0.0.1
[INFO] 08:46:43,310 Internal state is: 42
[INFO] 08:46:43,312 This step has unmapped rollback data!
[DEBUG] 08:46:43,313 rollback-data
[INFO] 08:46:43,315 This step has mapped rollback data!
[DEBUG] 08:46:43,316 rb-key1=rollback-map-data1
...
© 2024 mavenplugins, © 2016 itemis AG
- unleash:perform 🚀 by 3.3.0
- unleash:perform-tycho 🚀 by 3.3.0
- unleash:releaseVersion 🆕 since 3.1.0
- unleash:nextSnapshotVersion 🆕 since 3.1.0
3. Usage
4. The Workflow
5. Examples
- A Simple Release Build
- Perform An Eclipse Tycho Release Build
- Overriding The Workflow
- Implementing A Custom SCM Provider
- Implementing Custom Processing Steps