Maven


We are using a LetsEncrypt certificate for the build tools and the cert isn't trusted by older JVMs. You will need to update to the latest Java8 build to avoid connection issues.


Settings.xml

Replace your ~/.m2/settings.xml with this (or merge if you have existing settings).

<?xml version="1.0"?>
<settings>
	<activeProfiles>
		<activeProfile>hee</activeProfile>
	</activeProfiles>
	<profiles>
		<profile>
			<id>hee</id>
			<repositories>
				<repository>
					<id>hee-ssh-repository</id>
					<url>https://build.tis.nhs.uk/maven/repository/</url>
					<releases>
						<enabled>true</enabled>
					</releases>
					<snapshots>
						<enabled>true</enabled>
					</snapshots>
				</repository>
			</repositories>
		</profile>
	</profiles>
	<servers>
		<server>
			<id>hee-ssh-repository</id>
			<username>[your username]</username>
            <password>[your password]</password>
		</server>
	</servers>
</settings>

Parent POM

Have SSH set up as described in Updated SSH Documentation.

To bootstrap your environment, pull the tis-parent pom from the remote repository

$ rsync -ave 'ssh' 10.140.0.132:/datadrive/.m2/repository/com/transformuk/hee/tis-parent/ ~/.m2/repository/com/transformuk/hee/tis-parent/

Profiles

We try to avoid using profiles where ever we can but the Spring Boot apps require two profiles; default and nonexec. The Spring Boot plugin repackages standard jar files as part of the build process which means that the jar can no longer be used as a dependency in other projects. Whilst this is normally acceptable for service code, we do need to depend on the jars in the normal way as part of the microservice design project so we've had to use profiles to fix the issue.

The solution we came up with was to move the spring-boot-maven-plugin into a profile called default which is active by default 

<profile>
    <id>default</id>
    <activation>
        <activeByDefault>true</activeByDefault>
    </activation>
    <build>
        <plugins>
            <plugin>
                <groupId>org.springframework.boot</groupId>
                <artifactId>spring-boot-maven-plugin</artifactId>
            </plugin>
        </plugins>
    </build>
</profile>

We then created a second profile called nonexec which doesn't run the spring-boot-maven-plugin so the code isn't repackaged. 

<profile>
    <id>nonexec</id>
    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-jar-plugin</artifactId>
                <version>3.0.2</version>
                <configuration>
                    <classifier>nonexec</classifier>
                </configuration>
            </plugin>
        </plugins>
    </build>
</profile>

This creates an artifact with a classifier called nonexec which we can depend on in the normal manner. 

<dependency>
    <groupId>com.transformuk</groupId>
    <artifactId>gmc-sync</artifactId>
    <version>0.0.6-SNAPSHOT</version>
    <classifier>nonexec</classifier>
</dependency>

When we build microservices, we run the Maven build with the default profile first before creating the Docker image. When that completes we run another post build step which invokes a top-level Maven target like this; 

install -P nonexec -DskipTests

This recreates the original jar file and installs it in the local Maven repository. The original jar is very small compared to the microservice version which includes all of the project's dependencies so it doesn't add much overhead to the build and has little impact on the storage used. Spring recommend adding a classifier using their plugin called exec so the original artifact and the executable versions are both uploaded but we didn't want to change the Docker image creation scripts so this was less intrusive.

Release Plugin

The project should already have the maven-release-plugin present, if it does not, here is how to add it: 

In the pom.xml add in the plugin along with the proper scm link (make sure that the scm link matches the project's github repo). The example below is from revalidation: 

<scm>
<developerConnection>scm:git:git@github.com:Health-Education-England/TIS-REVALIDATION.git</developerConnection>
<tag>HEAD</tag>
</scm>

...

<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-release-plugin</artifactId>
<version>2.5.2</version>
<dependencies>
<dependency>
<groupId>org.apache.maven.scm</groupId>
<artifactId>maven-scm-provider-gitexe</artifactId>
<version>1.9.4</version>
</dependency>
</dependencies>
</plugin>

You should start with common projects that are required for others to compile (such as TIS-SHARED-MODULES). 

Check that your current project version in the POM is a "snapshot" version, the release prep will fail if it is not. 

Check that your public ssh key is uploaded to your github account, the release prep needs to talk to github and will use your account. If it is not add it, instructions here:

https://help.github.com/articles/adding-a-new-ssh-key-to-your-github-account/

If all the above are OK then Run:

mvn release:prepare 

You will be prompted to name the realease version, the release tag, and the new dev version. As an example, for the beta-001 release these are: 

release version name: beta-001

release tag: beta-001

new development version: beta-002-snapshot

If it all went well you should notice two new commits in your local git repo. The first one is the release (it has the tag you specified), the second one is the new development snapshot.

Finally for a: 

git push

The release is now on github.

If something went wrong you can do the following: 

mvn release:rollback

git tag -d beta-001
git push origin :refs/tags/beta-001

The above rolls back your attempt to release and deletes the tag you set (of course change the code to the tag you need).