Java CI/CD Workflows
Generated by java-ci-library, which is composed by all three Java service archetypes:
java-rest-service-archetypejava-grpc-service-archetypejava-graphql-service-archetype
The protocol has no effect on the pipeline - all three render the same two workflow files.
Build Workflow
.github/workflows/build.yaml, shown as rendered for a project named billing-service:
name: Build
on:
push:
branches: ["**"]
pull_request:
permissions:
contents: write
id-token: write
env:
IMAGE_NAME: billing-service
APPLICATION_NAME: billing-service
jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: p6m-actions/java-maven-setup@v1
- name: Cut Patch Version
if: github.ref_name == 'main'
id: cut-patch
uses: p6m-actions/java-maven-cut-tag@v1
with:
version-level: patch
- name: Build
uses: p6m-actions/java-maven-build@v1
with:
run-test: "false"
build-command: "mvn verify --no-transfer-progress"
# ... shared container build, release and dispatch steps
Step Chain
| # | Step | Scope | Runs on |
|---|---|---|---|
| 1 | Checkout | Shared | Always |
| 2 | Maven setup | Java | Always |
| 3 | Cut Patch Version | Java | main |
| 4 | Build | Java | Always |
| 5 | Login to Artifactory Container Registry | Shared | main |
| 6 | Set up Docker Buildx | Shared | Always |
| 7 | Build and Publish Docker Image | Shared | Always |
| 8 | Make Artifacts | Shared | main |
| 9 | Create Github release | Shared | main |
| 10 | Update Application Manifest | Shared | main |
Java is the only language that disables the build action's separate test phase, folding tests into a single mvn verify instead.
Language-Specific Steps
Maven Setup
- uses: p6m-actions/java-maven-setup@v1
p6m-actions/java-maven-setup installs a JDK and warms the Maven dependency cache.
| Input | Default | Passed by the workflow |
|---|---|---|
java-version | 21 | (default) |
java-distribution | temurin | (default) |
maven-version | (unset) | (default) - uses the Maven wrapper or the preinstalled Maven |
cache | true | (default) - caches ~/.m2 |
install-dependencies | true | (default) - resolves dependencies after setup |
maven-cache-key-suffix | (unset) | (default) |
| Output | Description |
|---|---|
java-version | The installed JDK version |
maven-version | The installed Maven version |
cache-hit | Whether the Maven cache was restored |
maven-cache-dir | Path to the Maven cache directory |
Cut Patch Version
- name: Cut Patch Version
if: github.ref_name == 'main'
id: cut-patch
uses: p6m-actions/java-maven-cut-tag@v1
with:
version-level: patch
p6m-actions/java-maven-cut-tag bumps the version with mvn versions:set, commits every pom.xml it touched, and creates an annotated tag.
| Input | Required | Value |
|---|---|---|
version-level | No | patch in build.yaml; the dispatch input in cut-tag.yaml |
| Output | Description |
|---|---|
version | The new version, e.g. 1.4.2 |
tag | The created tag |
Internally the action:
- Runs
p6m-actions/token-exchange@v2for a P6M App installation token, git identity, and the[skip ci]commit hook. - Fails fast if the computed tag already exists.
- Runs
mvn versions:set -DnewVersion=<v> -DgenerateBackupPoms=false. - Stages the parent
pom.xmland every modulepom.xmloutsidetarget/, so a multi-module archetype project bumps as a unit. - Commits, tags, and pushes both.
The archetype renders a parent POM plus -bom, -core, -server, -integration-tests and, with persistence enabled, -persistence modules. The cut-tag action stages all of their POMs, so the whole reactor stays on one version.
Build
- name: Build
uses: p6m-actions/java-maven-build@v1
with:
run-test: "false"
build-command: "mvn verify --no-transfer-progress"
p6m-actions/java-maven-build runs lint, test, build, and package phases, each individually toggleable.
| Input | Default | Value in the workflow |
|---|---|---|
run-lint | true | (default) - mvn checkstyle:check |
run-test | true | "false" (explicit) |
test-command | mvn test | not used, tests are disabled |
run-build | true | (default) |
build-command | mvn compile | mvn verify --no-transfer-progress (explicit) |
run-package | false | (default) |
maven-options | -B -q | (default) |
archive-coverage | false | (default) - JaCoCo reports under target/site/jacoco are not uploaded |
Outputs: none.
The two overrides work together. Replacing mvn compile with mvn verify makes the build phase run the full lifecycle - compile, Surefire unit tests, package, and Failsafe integration tests - in one reactor pass. The separate test phase is then redundant, so run-test is turned off to avoid compiling and testing twice. --no-transfer-progress suppresses per-artifact download noise in the log.
run-lint defaults to true, but the action guards it: when lint-command mentions checkstyle it first greps pom.xml for maven-checkstyle-plugin. If the plugin is not configured - which is the case for a freshly generated project - it logs "Skipping linting" and moves on. Adding the plugin to your POM is what turns the gate on.
Cut Tag Workflow
.github/workflows/cut-tag.yaml:
name: Cut Tag
on:
workflow_dispatch:
inputs:
version-level:
description: "Version bump level"
required: true
default: "patch"
type: choice
options:
- patch
- minor
- major
permissions:
id-token: write
contents: write
jobs:
cut-tag:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
token: ${{ secrets.GITHUB_TOKEN }}
- uses: p6m-actions/java-maven-setup@v1
- uses: p6m-actions/java-maven-cut-tag@v1
with:
version-level: ${{ inputs.version-level }}
| Input | version-level - patch, minor, or major |
| Outputs | A [skip ci] version bump commit across the POMs and an annotated tag, both pushed |
Version File
The parent pom.xml is the source of truth:
<project>
<groupId>com.example.payments</groupId>
<artifactId>billing-service</artifactId>
<version>1.4.2</version>
</project>
Related
- CI/CD Workflows - the shared steps and the CD handoff
- Java Actions - the wider Maven action catalog
- Java Setup Guide - local development environment