Skip to content

Commit

Permalink
Merge pull request #58 from egineering-llc/release/1.6.0
Browse files Browse the repository at this point in the history
Release/1.6.0
  • Loading branch information
bvarner authored Feb 14, 2017
2 parents 8a0b932 + d90f546 commit 0a54987
Show file tree
Hide file tree
Showing 7 changed files with 168 additions and 100 deletions.
54 changes: 25 additions & 29 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ It does so by:
* Enforcing [gitflow](http://nvie.com/posts/a-successful-git-branching-model/) version heuristics in [Maven](http://maven.apache.org/) projects.
* Coercing Maven to gracefully support the gitflow workflow without imposing complex CI job configurations or complex Maven setups.
* Setting distributionManagement repositories (for things like [maven-deploy-plugin](https://maven.apache.org/plugins/maven-deploy-plugin/)) based upon the current git branch.
* SCM tagging builds for the master branch, using the CI server's repository connection information. (Zero Maven scm configuration necessary)
* SCM tagging builds for the master branch. You can use the project SCM definition, or if you omit it, you can resolve the CI server's repository connection information. (Zero Maven scm configuration necessary)
* Promoting existing tested (staged) artifacts for release, rather than re-building the artifacts. Eliminates the risk of accidental master merges or commits resulting in untested code being released, and provides digest hash traceability for the history of artifacts.
* Enabling the decoupling of repository deployment and execution environment delivery based on the current git branch.
* Automated deployment, promotion, and delivery of projects without the [maven-release-plugin](http://maven.apache.org/maven-release/maven-release-plugin/) or some other [*almost there* solution](https://axelfontaine.com/blog/final-nail.html).
* Customizing maven project and system properties based upon the current branch being built. This allows test cases to target different execution environments without changing the artifact results.

# Why would I want to use this?

Expand All @@ -32,11 +33,16 @@ All of the solutions to these issues are implemented independently in different

# I want all of that. (Usage)

1. Make sure your build server sets environment variables for git branches and git URLs. The plugin defaults are configured out of the box for Jenkins & Hudson.
2. Configure the plugin goals and add the build extension to your Maven project. Here's an example that will get you going quickly...
1. Make sure you have a your Project SCM configured for your git repository, or that your build server sets environment variables for git branches and git URLs.
Out of the box, the plugin will try to resolve the git branch based upon the SCM definition on your maven project, or fall back to the environment variables set by Jenkins and Hudson.
2. Configure the plugin goals and add the build extension to your Maven project. Here's an example that will get you going quickly with all the features...

```
<project>
...
<scm>
<developerConnection>scm:git:ssh://git@server/project/path.git</developerConnection>
</scm>
...
<build>
<plugins>
Expand All @@ -52,8 +58,6 @@ All of the solutions to these issues are implemented independently in different
<releaseDeploymentRepository>${release.repository}</releaseDeploymentRepository>
<stageDeploymentRepository>${stage.repository}</stageDeploymentRepository>
<snapshotDeploymentRepository>${snapshot.repository}</snapshotDeploymentRepository>
<!-- The plugin will read the git branch ang git url by resolving these properties at run-time -->
<gitBranchProperty>
</configuration>
<executions>
<execution>
Expand Down Expand Up @@ -89,24 +93,24 @@ In practice, the Maven versions should:

* Be synchronized with release branch and hotfix branch names.
* Never be -SNAPSHOT in the master branch, release, or hotfix branches.
* Always be -SNAPSHOT in the development branch.
* Always be -SNAPSHOT in the develop branch.
* Be irrelevant if there's no git branch resolvable from your environment.

The `enforce-versions` goal asserts these semantics when it can resolve the `gitBranchExpression`.

The goal accomplishes this by checking the Maven pom.xml version value, and asserting the -SNAPSHOT status, as well as matching the current branch name
against regular expressions, extracting version numbers from the branch names where applicable. If a regex specifies a subgroup 1, the content of that
subgroup is asserted to equal the version defined in the pom.xml.
against regular expressions, extracting version numbers from the branch names where applicable. If a regex specifies subgroups, the content of the
last subgroup is asserted to equal the version defined in the pom.xml.

The following properties change the behavior of this goal:

| Property | Default Value | SNAPSHOT allowed? | Description |
| -------------------- | ------------- | --------------------------- | ----------- |
| gitBranchExpression | ${env.GIT_BRANCH} | n/a | Maven property expression to resolve in order to determine the current git branch |
| masterBranchPattern | origin/master | No | Regex. When matched, signals the master branch is being built. Note the lack of a subgroup. |
| releaseBranchPattern | origin/release/(.*) | No | Regex. When matched, signals a release branch being built. Subgroup 1, if present, must match the Maven project version. |
| hotfixBranchPattern | origin/hotfix/(.*) | No | Regex. When matched, signals a hotfix branch is being built. Subgroup 1, if present, must match the Maven project version. |
| developmentBranchPattern | origin/development | Yes | Regex. When matched, signals a development branch is being built. Note the lack of a subgroup. |
| gitBranchExpression | current git branch resolved from SCM or ${env.GIT_BRANCH} | n/a | Maven property expression to resolve in order to determine the current git branch |
| masterBranchPattern | (origin/)?master | No | Regex. When matched, signals the master branch is being built. |
| releaseBranchPattern | (origin/)?release/(.*) | No | Regex. When matched, signals a release branch being built. Last subgroup, if present, must match the Maven project version. |
| hotfixBranchPattern | (origin/)?hotfix/(.*) | No | Regex. When matched, signals a hotfix branch is being built. Last subgroup, if present, must match the Maven project version. |
| developmentBranchPattern | (origin/)?develop | Yes | Regex. When matched, signals a development branch is being built. Note the lack of a subgroup. |

## Goal: `retarget-deploy` (Branch Specific Deploy Targets & Staging)

Expand All @@ -122,7 +126,7 @@ plugins in the build process (deploy, site-deploy, etc.) will use the repositori

| Property | Default Value | Description |
| -------- | ------------- | ----------- |
| gitBranchExpression | ${env.GIT_BRANCH} | Maven property expression to resolve in order to determine the current git branch |
| gitBranchExpression | current git branch resolved from SCM or ${env.GIT_BRANCH} | Maven property expression to resolve in order to determine the current git branch |
| releaseDeploymentRepository | n/a | The repository to use for releases. (Builds with a GIT_BRANCH matching `masterBranchPattern`) |
| stageDeploymentRepository | n/a | The repository to use for staging. (Builds with a GIT_BRANCH matching `releaseBranchPattern` or `hotfixBranchPattern` |
| snapshotDeploymentRepository | n/a | The repository to use for snapshots. (Builds matching `developmentBranchPattern` |
Expand Down Expand Up @@ -179,26 +183,18 @@ Can be replaced with the following plugin configuration, which also introduces t
In a gitflow environment, a commit to a master branch should trigger a job to build on the master branch, which would result in the release being tagged if successful.

The `tag-master` goal executes the [maven-scm-plugin tag goal](https://maven.apache.org/scm/maven-scm-plugin/tag-mojo.html) when the
`gitBranchExpression` resolves to a value matching the `masterBranchPattern` regular expression. To determine the SCM URL to use, the `gitURLExpression`
is evaluated at run-time. The default expression, `${env.GIT_URL}`, is provided by Jenkins & Hudson.

To resolve the `<developerConnection>` in an `<scm>` block in your pom, you can specify the following in your plugin configuration:

```
<gitURLExpression>${project.scm.developerConnection}</gitURLExpression>
```
`gitBranchExpression` resolves to a value matching the `masterBranchPattern` regular expression. To determine the SCM URL to use, the plugin looks for a
`developerConnection` or `connection` information in an SCM block, and if not found the `gitURLExpression` is evaluated at run-time.
The default expression, `${env.GIT_URL}`, is one that is commonly provided by Jenkins & Hudson.

The following properties can be configured for this goal:

| Property | Default Value | Description |
| -------------------- | ------------- | ----------- |
| gitBranchExpression | ${env.GIT_BRANCH} | Maven property expression to resolve in order to determine the current git branch |
| gitURLExpression | ${env.GIT_URL} | Maven property expression to resolve for the GIT URL connection to use. |
| masterBranchPattern | origin/master | Regex. When matched against the resolved value of `gitBranchExpression` this plugin executes the scm:tag goal using the `gitURLExpression` to resolve the git URL to use. |
| gitBranchExpression | current git branch resolved from SCM or ${env.GIT_BRANCH} | Maven property expression to resolve in order to determine the current git branch |
| gitURLExpression | current git branch resolved from SCM or ${env.GIT_URL} | Maven property expression to resolve for the GIT URL connection to use. |
| masterBranchPattern | (origin/)?master | Regex. When matched against the resolved value of `gitBranchExpression` this plugin executes the scm:tag goal using the `gitURLExpression` to resolve the git URL to use. |
| tag | ${project.version} | An expression to use for the SCM tag. |
| tag.plugin.groupId | org.apache.maven.plugins | The groupId of the plugin to use for tagging. |
| tag.plugin.artifactId | maven-scm-plugin | The artifactId of the plugin to use for tagging. |
| tag.plugin.version | 1.9.4 | The version of the plugin to use for tagging. |


## Goal: `promote-master` and the Build Extension. (Copy Staged Artifacts to Releases)
Expand Down Expand Up @@ -271,7 +267,7 @@ that the first build deployed into. Once they're attached to the project, the `j
the artifacts built by the first job into a jboss application server.


## Goal: `set-properties` (Dynamically Set a Maven Project / System Properties)
## Goal: `set-properties` (Dynamically Set Maven Project / System Properties)

Some situations with automated testing (and integration testing in particular) demand changing configuration properties
based upon the branch type being built. This is a common necessity when configuring automated DB refactorings as part of
Expand Down
28 changes: 16 additions & 12 deletions pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
<groupId>com.e-gineering</groupId>
<artifactId>gitflow-helper-maven-plugin</artifactId>

<version>1.5.2</version>
<version>1.6.0</version>
<packaging>maven-plugin</packaging>

<name>gitflow-helper-maven-plugin</name>
Expand Down Expand Up @@ -64,17 +64,6 @@
</distributionManagement>

<dependencies>
<dependency>
<groupId>org.twdata.maven</groupId>
<artifactId>mojo-executor</artifactId>
<version>2.2.0</version>
<exclusions>
<exclusion>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
</exclusion>
</exclusions>
</dependency>
<dependency>
<groupId>org.apache.maven</groupId>
<artifactId>maven-core</artifactId>
Expand All @@ -92,6 +81,21 @@
<artifactId>maven-plugin-api</artifactId>
<version>3.1.0</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-api</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-manager-plexus</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.9.5</version>
</dependency>
<dependency>
<groupId>org.apache.maven.plugin-tools</groupId>
<artifactId>maven-plugin-annotations</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@
import org.apache.maven.plugins.annotations.Component;
import org.apache.maven.plugins.annotations.Parameter;
import org.apache.maven.project.MavenProject;
import org.apache.maven.scm.manager.ScmManager;
import org.codehaus.plexus.util.cli.CommandLineUtils;

import java.io.IOException;
Expand All @@ -26,16 +27,19 @@ public abstract class AbstractGitflowBranchMojo extends AbstractMojo {
@Component
protected MavenProject project;

@Parameter(defaultValue = "origin/master", property = "masterBranchPattern", required = true)
@Component
protected ScmManager scmManager;

@Parameter(defaultValue = "(origin/)?master", property = "masterBranchPattern", required = true)
private String masterBranchPattern;

@Parameter(defaultValue = "origin/release/(.*)", property = "releaseBranchPattern", required = true)
@Parameter(defaultValue = "(origin/)?release/(.*)", property = "releaseBranchPattern", required = true)
private String releaseBranchPattern;

@Parameter(defaultValue = "origin/hotfix/(.*)", property = "hotfixBranchPattern", required = true)
@Parameter(defaultValue = "(origin/)?hotfix/(.*)", property = "hotfixBranchPattern", required = true)
private String hotfixBranchPattern;

@Parameter(defaultValue = "origin/development", property = "developmentBranchPattern", required = true)
@Parameter(defaultValue = "(origin/)?develop", property = "developmentBranchPattern", required = true)
private String developmentBranchPattern;

// @Parameter tag causes property resolution to fail for patterns containing ${env.}. Default provided in execute();
Expand All @@ -61,7 +65,7 @@ private void logExecute(final GitBranchType type, final String gitBranch, final

public void execute() throws MojoExecutionException, MojoFailureException {
if (gitBranchExpression == null) {
gitBranchExpression = "${env.GIT_BRANCH}";
gitBranchExpression = ScmUtils.resolveBranchOrExpression(scmManager, project, getLog());
}

try {
Expand All @@ -80,9 +84,9 @@ public void execute() throws MojoExecutionException, MojoFailureException {

if (!eb.hasMoreLegalPlaceholders()) {
/*
* /origin/master goes to the maven 'release' repo.
* /origin/release/.* , /origin/hotfix/.* , and /origin/bugfix/.* go to the maven 'stage' repo.
* /origin/development goes to the 'snapshot' repo.
* (/origin/)?master goes to the maven 'release' repo.
* (/origin/)?release/(.*) , (/origin/)?hotfix/(.*) , and (/origin/)?bugfix/(.*) go to the maven 'stage' repo.
* (/origin/)?develop goes to the 'snapshot' repo.
* All other builds will use the default semantics for 'deploy'.
*/
if (gitBranch.matches(masterBranchPattern)) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,13 +28,15 @@ protected void execute(final GitBranchType type, final String gitBranch, final S
throw new MojoFailureException("The current git branch: [" + gitBranch + "] is defined as a release branch. The maven project version: [" + project.getVersion() + "] is currently a snapshot version.");
}

// If there is a group 1, expect it to match (exactly) the current projectVersion.
if (gitMatcher.groupCount() >= 1) {
if (!gitMatcher.group(1).trim().equals(project.getVersion().trim())) {
throw new MojoFailureException("The current git branch: [" + gitBranch + "] expected the maven project version to be: [" + gitMatcher.group(1).trim() + "], but the maven project version is: [" + project.getVersion() + "]");
// Expect the last group on non-master branches to match (exactly) the current projectVersion. (only release / hotfix branches)
if (gitMatcher.groupCount() > 0 && !GitBranchType.MASTER.equals(type)) {
if (!gitMatcher.group(gitMatcher.groupCount()).trim().equals(project.getVersion().trim())) {
throw new MojoFailureException("The current git branch: [" + gitBranch + "] expected the maven project version to be: [" + gitMatcher.group(gitMatcher.groupCount()).trim() + "], but the maven project version is: [" + project.getVersion() + "]");
}
}
}
} else if (GitBranchType.DEVELOPMENT.equals(type) && !ArtifactUtils.isSnapshot(project.getVersion())) {
throw new MojoFailureException("The current git branch: [" + gitBranch + "] is detected as the gitflow development branch, and expects a maven project version ending with -SNAPSHOT. The maven project version found was: [" + project.getVersion() + "]");
}
}
}
Loading

0 comments on commit 0a54987

Please sign in to comment.