Skip to content

Commit 5ba1b75

Browse files
committed
feat: Add versions-maven-plugin and convenient scripts
And use VERSION as generic to not have to update docs on each release.
1 parent 111d8c6 commit 5ba1b75

7 files changed

Lines changed: 145 additions & 8 deletions

File tree

README.adoc

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,10 @@ the archetype builds the full module tree and wires up all POMs.
1111
mvn archetype:generate \
1212
-DarchetypeGroupId=io.github.jeffjensen \
1313
-DarchetypeArtifactId=java-service-archetype \
14-
-DarchetypeVersion=1.0.0
14+
-DarchetypeVersion=VERSION
1515
----
1616

17+
Replace `VERSION` with the archetype release you want to use.
1718
See the https://jeffjensen.github.io/java-service-archetype/[project site] for the full prompts reference, module structure, examples, and build instructions.
1819

1920
== CI / CD

src/main/resources/META-INF/archetype-post-generate.groovy

Lines changed: 75 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,6 @@
11
import java.io.File
2+
import java.nio.file.Files
3+
import java.nio.file.attribute.PosixFilePermissions
24

35
// ─── Helpers ──────────────────────────────────────────────────────────────────
46

@@ -216,6 +218,7 @@ ${modulesXml}
216218
<maven-jar-plugin.version>3.4.2</maven-jar-plugin.version>
217219
<maven-surefire-plugin.version>3.5.5</maven-surefire-plugin.version>
218220
<modernizer-maven-plugin.version>3.4.0</modernizer-maven-plugin.version>
221+
<versions-maven-plugin.version>2.18.0</versions-maven-plugin.version>
219222
</properties>
220223
221224
<dependencyManagement>
@@ -289,6 +292,35 @@ ${dmXml}
289292
</execution>
290293
</executions>
291294
</plugin>
295+
<plugin>
296+
<groupId>org.codehaus.mojo</groupId>
297+
<artifactId>versions-maven-plugin</artifactId>
298+
<version>\${versions-maven-plugin.version}</version>
299+
<configuration>
300+
<ruleSet>
301+
<ignoreVersions>
302+
<ignoreVersion>
303+
<type>regex</type>
304+
<version>(?i).*-(alpha|beta|m|rc)([-.]?\\d+)?</version>
305+
</ignoreVersion>
306+
</ignoreVersions>
307+
<rules>
308+
<rule>
309+
<groupId>com.graphql-java</groupId>
310+
<artifactId>graphql-java-extended-scalars</artifactId>
311+
<ignoreVersions>
312+
<!-- ignore old versions starting with 2018, 2019, 2020, 2021, 2022, or 2023 that
313+
semantically are newer than current version scheme -->
314+
<ignoreVersion>
315+
<type>regex</type>
316+
<version>^20(1[8-9]|2[0-3]).*</version>
317+
</ignoreVersion>
318+
</ignoreVersions>
319+
</rule>
320+
</rules>
321+
</ruleSet>
322+
</configuration>
323+
</plugin>
292324
</plugins>
293325
</pluginManagement>
294326
<plugins>
@@ -306,6 +338,49 @@ writeFile(projectDir, 'parent/pom.xml', parentPom)
306338
// Remove the placeholder pom.xml that the archetype engine wrote at the project root
307339
new File(projectDir, 'pom.xml').delete()
308340

341+
// ─── Version-update helper scripts ────────────────────────────────────────────
342+
// Convenience wrappers around `mvn versions:update-properties` so all property
343+
// versions can be bumped to their latest in one command. Written into parent/
344+
// (alongside parent/pom.xml, where the version properties live) for both Linux
345+
// (LF, +x) and Windows (CRLF). Built from explicit line lists so the line
346+
// endings are correct regardless of this script's own endings.
347+
348+
writeFile(projectDir, 'parent/mvn-update-properties-versions.sh', [
349+
'#!/bin/bash',
350+
'# Updates property versions to the latest found',
351+
'FILE=target/version-updates-applied.log',
352+
'mkdir -p target',
353+
'rm -f $FILE',
354+
'echo "Writing output to file $FILE"',
355+
'echo "Applying version updates specified as properties..."',
356+
'echo "======================================== PROPERTIES" >> $FILE',
357+
'mvn versions:update-properties >> $FILE',
358+
'',
359+
].join('\n'))
360+
361+
writeFile(projectDir, 'parent/mvn-update-properties-versions.ps1', [
362+
'# Updates property versions to the latest found',
363+
'$FILE = "target/version-updates-applied.log"',
364+
'New-Item -ItemType Directory -Force -Path "target" | Out-Null',
365+
'if (Test-Path $FILE) { Remove-Item -Force $FILE }',
366+
'Write-Host "Writing output to file $FILE"',
367+
'Write-Host "Applying version updates specified as properties..."',
368+
'"======================================== PROPERTIES" | Out-File -FilePath $FILE -Append -Encoding utf8',
369+
'& mvn versions:update-properties | Out-File -FilePath $FILE -Append -Encoding utf8',
370+
'',
371+
].join('\r\n'))
372+
373+
// Set the exec bit on the Linux script. POSIX filesystems only; on Windows
374+
// (non-POSIX) this throws UnsupportedOperationException and we fall back to the
375+
// best-effort Java executable flag (a no-op on Windows, but harmless).
376+
def shFile = new File(projectDir, 'parent/mvn-update-properties-versions.sh')
377+
try {
378+
Files.setPosixFilePermissions(shFile.toPath(),
379+
PosixFilePermissions.fromString('rwxr-xr-x'))
380+
} catch (UnsupportedOperationException ignored) {
381+
shFile.setExecutable(true, false)
382+
}
383+
309384
// ─── common-domain ────────────────────────────────────────────────────────────
310385

311386
writeFile(projectDir, 'common-domain/pom.xml',

src/site/asciidoc/index.adoc

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,9 +14,11 @@ the archetype builds the full module tree and wires up all POMs.
1414
mvn archetype:generate \
1515
-DarchetypeGroupId=io.github.jeffjensen \
1616
-DarchetypeArtifactId=java-service-archetype \
17-
-DarchetypeVersion=1.0.0
17+
-DarchetypeVersion=VERSION
1818
----
1919

20+
Replace `VERSION` with the archetype release you want to use.
21+
2022
Maven prompts for standard coordinates (`groupId`, `artifactId`, `version`, `package`)
2123
followed by three archetype-specific properties.
2224
See link:usage.html[Usage] for the full prompts reference.

src/site/asciidoc/modules.adoc

Lines changed: 30 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,9 @@ It contains:
9292
* `<dependencyManagement>` — all modules pinned to `${project.version}`, sorted alphabetically by `artifactId`
9393
* Common properties: Java 21 via `maven.compiler.release`; UTF-8 source encoding
9494
* `<pluginManagement>` — pinned versions for `maven-compiler-plugin`, `maven-failsafe-plugin`,
95-
`maven-jar-plugin` (with `skipIfEmpty=true`), `maven-surefire-plugin`, and
96-
`modernizer-maven-plugin` (bound to `verify`, `javaVersion` = `${java.version}`)
95+
`maven-jar-plugin` (with `skipIfEmpty=true`), `maven-surefire-plugin`,
96+
`modernizer-maven-plugin` (bound to `verify`, `javaVersion` = `${java.version}`), and
97+
`versions-maven-plugin` (rule set ignores alpha/beta/milestone/RC versions)
9798
* `<plugins>` — activates `modernizer-maven-plugin` so every module is checked for outdated API usage during `verify`
9899

99100
To build a generated project:
@@ -106,6 +107,33 @@ mvn verify
106107

107108
Use `mvn install` instead if other local projects need to consume the generated modules from your local Maven repository.
108109

110+
=== Updating dependency and plugin versions
111+
112+
`parent/` also contains two convenience scripts that wrap `mvn versions:update-properties`,
113+
bumping every dependency and plugin version property in `parent/pom.xml` to its latest stable
114+
release in a single command:
115+
116+
[cols="1,2"]
117+
|===
118+
|Script |Platform
119+
120+
|`mvn-update-properties-versions.sh` |Linux / macOS
121+
|`mvn-update-properties-versions.ps1` |Windows (PowerShell)
122+
|===
123+
124+
Run the applicable script from `parent/` immediately after generating the project to pick up
125+
the newest versions before your first build:
126+
127+
[source,bash]
128+
----
129+
cd my-service/parent
130+
./mvn-update-properties-versions.sh
131+
----
132+
133+
The full plugin output is written to `parent/target/version-updates-applied.log`.
134+
Pre-release versions (alpha, beta, milestone, RC) are skipped by the `versions-maven-plugin`
135+
rule set, so only stable releases are applied.
136+
109137
== Package Reference
110138

111139
All type and name segments in package names are lowercased.

src/site/asciidoc/requirements.adoc

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -59,10 +59,15 @@ Do not create a `pom.xml` at the project root.
5959
`project.build.sourceEncoding`.
6060
* `<pluginManagement>` — declare pinned versions for `maven-compiler-plugin`,
6161
`maven-failsafe-plugin`, `maven-jar-plugin` (configured with `skipIfEmpty=true`),
62-
`maven-surefire-plugin`, and `modernizer-maven-plugin` (bound to the `verify`
63-
phase with `javaVersion` set to `${java.version}`).
62+
`maven-surefire-plugin`, `modernizer-maven-plugin` (bound to the `verify`
63+
phase with `javaVersion` set to `${java.version}`), and `versions-maven-plugin`
64+
(rule set ignores alpha/beta/milestone/RC versions).
6465
* `<plugins>` — activate `modernizer-maven-plugin` so every module is checked for
6566
outdated API usage during `verify`.
67+
* Generate two convenience scripts in `parent/` — `mvn-update-properties-versions.sh`
68+
(Linux/macOS, LF line endings, executable bit set) and `mvn-update-properties-versions.ps1`
69+
(Windows, CRLF line endings) — that wrap `mvn versions:update-properties` to bump every
70+
dependency and plugin version property to its latest stable release.
6671

6772
=== Child module POMs
6873

src/site/asciidoc/usage.adoc

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,11 @@
1010
mvn archetype:generate \
1111
-DarchetypeGroupId=io.github.jeffjensen \
1212
-DarchetypeArtifactId=java-service-archetype \
13-
-DarchetypeVersion=1.0.0
13+
-DarchetypeVersion=VERSION
1414
----
1515

16+
Replace `VERSION` with the archetype release you want to use.
17+
1618
Maven first prompts for the standard Maven coordinates:
1719

1820
[cols="1,2"]
@@ -133,7 +135,7 @@ Uses the same values as the full multi-service example above.
133135
mvn archetype:generate -B \
134136
-DarchetypeGroupId=io.github.jeffjensen \
135137
-DarchetypeArtifactId=java-service-archetype \
136-
-DarchetypeVersion=1.0.0 \
138+
-DarchetypeVersion=VERSION \
137139
-DgroupId=com.example \
138140
-DartifactId=my-service \
139141
-Dversion=1.0.0-SNAPSHOT \

src/test/resources/projects/basic/verify.groovy

Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -76,6 +76,13 @@ assert pmBlock.contains('<version>${modernizer-maven-plugin.version}</version>')
7676
assert pmBlock.contains('<javaVersion>${java.version}</javaVersion>') : 'modernizer must configure javaVersion'
7777
assert pmBlock.contains('<goal>modernizer</goal>') : 'modernizer pluginManagement must bind the modernizer goal'
7878

79+
// versions-maven-plugin: pinned and managed in pluginManagement with the update ruleSet
80+
assert parentPom.contains('<versions-maven-plugin.version>2.18.0</versions-maven-plugin.version>') \
81+
: 'parent must pin versions-maven-plugin version'
82+
assert pmBlock.contains('<artifactId>versions-maven-plugin</artifactId>') : 'versions-maven-plugin must be declared in pluginManagement'
83+
assert pmBlock.contains('<version>${versions-maven-plugin.version}</version>') : 'versions-maven-plugin pluginManagement must reference the version property'
84+
assert pmBlock.contains('<artifactId>graphql-java-extended-scalars</artifactId>') : 'versions-maven-plugin must configure the graphql-java-extended-scalars rule'
85+
7986
// the active <plugins> section is what remains of <build> after removing <pluginManagement>
8087
def buildBlock = (parentPom =~ /(?s)<build>.*<\/build>/)[0]
8188
def activePlugins = buildBlock.replaceAll(/(?s)<pluginManagement>.*<\/pluginManagement>/, '')
@@ -215,5 +222,22 @@ modules.findAll { it.startsWith('integration-') }.each { m ->
215222
: "${m} must configure maven-failsafe-plugin"
216223
}
217224

225+
// ── Version-update helper scripts in parent/ ──────────────────────────────────
226+
// They live alongside parent/pom.xml, where the version properties are defined.
227+
// The .sh exec bit is POSIX-only and cannot be set when generating on Windows,
228+
// so it is intentionally not asserted here.
229+
230+
check('parent/mvn-update-properties-versions.sh')
231+
check('parent/mvn-update-properties-versions.ps1')
232+
233+
def shScript = text('parent/mvn-update-properties-versions.sh')
234+
assert shScript.startsWith('#!/bin/bash') : 'bash script must start with the bash shebang'
235+
assert shScript.contains('mvn versions:update-properties') : 'bash script must run mvn versions:update-properties'
236+
assert !shScript.contains('\r') : 'bash script must use LF line endings (no CR)'
237+
238+
def psScript = text('parent/mvn-update-properties-versions.ps1')
239+
assert psScript.contains('mvn versions:update-properties') : 'PowerShell script must run mvn versions:update-properties'
240+
assert psScript.contains('\r\n') : 'PowerShell script must use CRLF line endings'
241+
218242
_buildLog.append("\n=== PASSED ===\n")
219243
true

0 commit comments

Comments
 (0)