Java and Maven Example

Build, Package and Deploy with Tomcat

This article lays the implementation foundations for Release Train delivery. The key principle is Autonomous Development, Authoritative Release, with this material describing an autonomous development pipeline. The following steps achieve this using the Continuous Delivery Automation Framework (CDAF).

alt text alt text

Subsections of Java and Maven Example

Continuous Integration (CI)

Build & Package Once

To provide a runtime verification of the build that has been deployed, the version is automatically incremented by placing a variable in the pom.xml file

<?xml version="1.0" encoding="UTF-8"?>

  ..

  <artifactId>springboot</artifactId>
  <groupId>io.cdaf</groupId>
  <name>Spring Boot Data REST Sample</name>
  <description>Spring Boot Data REST Sample</description>
  <version>0.2.${build.number}</version>

In the build task, the build number is supplied as a maven parameter

mvn --batch-mode --file springboot/pom.xml package -D"build.number=${BUILDNUMBER}"

alt text alt text

The resulting artefact is in a subdirectory, buy using the -flat parameter in storeForLocal the artefact will be placed in the root of release package.

springboot/target/springboot.war -flat

alt text alt text

Image Build

By setting the buildImage property in the CDAF.solution driver file, a docker image build and push is triggered. In this example the image is pushed to an on-premise container registry (Nexus).

productName=Springboot Sprint Zero
solutionName=spring

artifactPrefix=0.2

buildImage=registry.access.redhat.com/ubi9/openjdk-17-runtime
CDAF_REGISTRY_URL=https://${NEXUS_REGISTRY}
CDAF_REGISTRY_TAG=${NEXUS_REGISTRY}/${SOLUTION}:$BUILDNUMBER
CDAF_REGISTRY_USER=${NEXUS_REGISTRY_USER}
CDAF_REGISTRY_TOKEN=${NEXUS_REGISTRY_PASS}

registryTag=${NEXUS_REGISTRY}/${SOLUTION}:$BUILDNUMBER

alt text alt text alt text alt text

This image is consumed, along with other autonomous development components, in the Release Train.

Continuous Delivery (CD)

Deploy Many

While this example does not delivery the software component imperatively, i.e. it is release declaratively via the Release Train, a Continuous Delivery stage is still performed, however this is a closed loop process, where docker-compose is used to stand-up a container instance from the image, stand-up another container to perform a smoke test, and then tear down the stack.

services:
  target:
    image: "${TARGET_TAG}"
  test:
    image: "${TEST_TAG}"
    links:
      - target:target
    depends_on:
      - target

alt text alt text alt text alt text