skip to content

How do build-helper:parse-version and build-helper:regex-property work, and what are realistic uses for the properties they produce?

level: middleimportance: nice to knowfreq 18%

answer

  1. parsedVersion.major/minor/incremental/qualifier
  2. bind at initialize/validate
  3. regex-property = name/value/regex/replacement
  4. sanitize branch into docker tag
  5. declarative vs scripting

basics

~10 s

parse-version splits the project version (e.g. 2.4.1-SNAPSHOT) into properties like parsedVersion.majorVersion/minorVersion/incrementalVersion/qualifier. regex-property creates a property by applying a regex find/replace to a value. Both feed naming, filtering, and conditional config.

solid answer

~40 s

build-helper:parse-version reads the project (or a given) version string and decomposes it into discrete Maven properties — `parsedVersion.majorVersion`, `minorVersion`, `incrementalVersion`, `buildNumber`, `qualifier`, plus zero-padded and 'next' variants. You use those to build a Docker tag, compute an OSGi version, set a feature flag for a major line, or do resource filtering. build-helper:regex-property sets one property by running a `<regex>` against a `<value>` with a `<replacement>` (Java regex semantics); typical uses are sanitizing a Git branch name into a valid image tag, stripping `-SNAPSHOT`, or extracting a substring. Both run early (validate/initialize) so the derived properties exist before later plugins. They keep version/string logic declarative in the pom instead of forcing antrun or exec scripting.

code

xml · 6 lines
xml
<execution>
  <id>parse</id>
  <phase>initialize</phase>
  <goals><goal>parse-version</goal></goals>
</execution>
<!-- later: <image>app:${parsedVersion.majorVersion}.${parsedVersion.minorVersion}</image> -->

go deeper

for a junior

Know parse-version yields major/minor/etc. properties and regex-property derives a string.

for a middle

Bind early and consume the properties in tags/filtering; use group refs in regex replacement.

for a senior

Choose these declarative goals over antrun/exec for simple transforms; know their phase-ordering requirements.

for a principal

Standardize version/tag derivation across modules to keep CI naming consistent and reproducible.

## parse-version A version like `2.4.1-SNAPSHOT` is just a string to most of Maven. `build-helper:parse-version` parses it (default source is `${project.version}`) and publishes components as properties under a configurable prefix (default `parsedVersion`): - `parsedVersion.majorVersion` → `2` - `parsedVersion.minorVersion` → `4` - `parsedVersion.incrementalVersion` → `1` - `parsedVersion.qualifier` → `SNAPSHOT` - `parsedVersion.buildNumber`, plus formatted variants like `osgiVersion` and zero-padded / `nextMajorVersion` etc. Bind it to an early phase (`validate` or `initialize`) so the properties are ready before resource filtering, the docker/jib plugin, or the assembly runs. ```xml <execution> <id>parse</id> <phase>initialize</phase> <goals><goal>parse-version</goal></goals> </execution> ``` Then, for example, a Docker tag: `myapp:${parsedVersion.majorVersion}.${parsedVersion.minorVersion}`. ## regex-property `build-helper:regex-property` computes a *new* property from an input value using Java-regex find/replace: - `<name>` — the property to set. - `<value>` — the input (often another property like `${env.GIT_BRANCH}` or `${project.version}`). - `<regex>` — the Java regular expression to match. - `<replacement>` — what to substitute (supports `$1` group refs). - `<failIfNoMatch>` — whether to fail when nothing matches. ```xml <execution> <id>safe-branch</id> <phase>initialize</phase> <goals><goal>regex-property</goal></goals> <configuration> <name>docker.tag</name> <value>${env.GIT_BRANCH}</value> <regex>[^a-zA-Z0-9._-]</regex> <replacement>-</replacement> <failIfNoMatch>false</failIfNoMatch> </configuration> </execution> ``` That turns `feature/login fix` into `feature-login-fix`, a valid Docker tag. ## Realistic uses - **parse-version**: container image tags from major.minor; gating behavior by major line; generating an OSGi-compatible version; writing version components into a generated `build-info` resource via filtering. - **regex-property**: sanitizing branch/CI variables into valid identifiers; stripping `-SNAPSHOT` to compute a release tag; extracting a ticket number from a branch name. ## Why prefer these over scripting They keep the transformation **declarative and portable** in the pom, runnable identically on any OS, instead of shelling out via exec or embedding antrun `<replaceregexp>`. For anything more complex than a single transform, though, the logic may belong in a small plugin or a dedicated CI step.

  • What phase should these be bound to and why?
    Early phases like validate or initialize, so the derived properties are available before any later plugin (resource filtering, docker/jib, assembly) needs them.
  • What property does parse-version produce for the major number of 3.2.5-SNAPSHOT?
    parsedVersion.majorVersion = 3 (with minorVersion 2, incrementalVersion 5, qualifier SNAPSHOT), under the default 'parsedVersion' prefix.

saying these in an interview costs you the question

  • Thinking parse-version changes the project version (it only reads and exposes parts)
  • Assuming regex-property uses shell/glob rather than Java regex
  • Binding them late so the properties are empty when consumed

context