I inherited a Java application that is actually five applications — and the build pipeline had a lot of repetition. Tell maven to use this POM file, now use that one, and now the other one. It wasn’t great, but it got even more cumbersome when I needed to split the production and development builds to use a different pool (network rule: prod and dev servers may not communicate … so the dev agent talks to the dev image repo which is used by the dev deployment. The prod agent talks to the prod image repo which is used by the prod deployment). Instead of having five “hey, maven, do this build” blocks, I now have ten.
So I created a template for the build step — jdk-path and maven-path are pipeline variables. The rest is the Maven build task with parameters to supply the step display name, pom file to use, and environment flag.
Maven Build Template:
# maven-build-step.yml
parameters:
- name: pomFile
type: string
- name: dockerEnv
type: string
- name: displayName
type: string
steps:
- task: Maven@3
displayName: '${{ parameters.displayName }}'
inputs:
mavenPomFile: '${{ parameters.pomFile }}'
mavenOptions: '-Xmx3072m'
javaHomeOption: 'Path'
jdkDirectory: $(jdk-path)
mavenVersionOption: 'Path'
mavenDirectory: $(maven-path)
mavenSetM2Home: true
jdkArchitectureOption: 'x64'
publishJUnitResults: true
testResultsFiles: '**/surefire-reports/TEST-*.xml'
goals: 'package -Denv=${{ parameters.dockerEnv }} jib:build'
Then my build pipeline uses the template and supplies a few parameters
Pipeline:
# azure-pipelines.yml
trigger: none
variables:
appName: 'NPM'
stages:
- stage: Build
jobs:
- job: NonProdBuild
condition: ne(variables['Build.SourceBranchName'], 'production')
displayName: 'Build non-production branch'
variables:
DockerFlag: 'docker_dev'
pool:
name: 'Engineering NPM'
steps:
- template: maven-build-template.yml
parameters:
pomFile: 'JAVA/KafkaStreamsApp/npm/pom.xml'
dockerEnv: $(DockerFlag)
displayName: 'Building Kafka Streams App'
- template: maven-build-template.yml
parameters:
pomFile: 'JAVA/DataSync/npmInfo/pom.xml'
dockerEnv: $(DockerFlag)
displayName: 'Building Data Sync App'
- template: maven-build-template.yml
parameters:
pomFile: 'JAVA/GroupingRules/pom.xml'
dockerEnv: $(DockerFlag)
displayName: 'Building Grouping Rules App'
- template: maven-build-template.yml
parameters:
pomFile: 'JAVA/Errorhandler/pom.xml'
dockerEnv: $(DockerFlag)
displayName: 'Building Error Handler App'
- template: maven-build-template.yml
parameters:
pomFile: 'JAVA/Events/pom.xml'
dockerEnv: $(DockerFlag)
displayName: 'Building Events App'
- job: ProdBuild
condition: eq(variables['Build.SourceBranchName'], 'production')
displayName: 'Build production branch'
variables:
DockerFlag: 'docker_prod'
pool:
name: 'Engineering NPM Prod'
steps:
- template: maven-build-template.yml
parameters:
pomFile: 'JAVA/KafkaStreamsApp/npm/pom.xml'
dockerEnv: $(DockerFlag)
displayName: 'Building Kafka Streams App'
- template: maven-build-template.yml
parameters:
pomFile: 'JAVA/DataSync/npmInfo/pom.xml'
dockerEnv: $(DockerFlag)
displayName: 'Building Data Sync App'
- template: maven-build-template.yml
parameters:
pomFile: 'JAVA/GroupingRules/pom.xml'
dockerEnv: $(DockerFlag)
displayName: 'Building Grouping Rules App'
- template: maven-build-template.yml
parameters:
pomFile: 'JAVA/Errorhandler/pom.xml'
dockerEnv: $(DockerFlag)
displayName: 'Building Error Handler App'
- template: maven-build-template.yml
parameters:
pomFile: 'JAVA/Events/pom.xml'
dockerEnv: $(DockerFlag)
displayName: 'Building Events App'
I think this could be made more concise … but it will do for now!