diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..dc5d011
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,69 @@
+name: Release
+
+on:
+ workflow_dispatch:
+ inputs:
+ version:
+ description: Release version without the leading v
+ required: true
+ type: string
+ push:
+ tags:
+ - 'v*'
+
+permissions:
+ contents: write
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+ environment: jreleaser
+ steps:
+ - name: Check out source
+ uses: actions/checkout@v7
+ with:
+ fetch-depth: 0
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@v6
+ with:
+ java-version: '21'
+ distribution: temurin
+ cache: maven
+
+ - name: Set release version
+ env:
+ TAG_VERSION: ${{ github.ref_type == 'tag' && github.ref_name || '' }}
+ INPUT_VERSION: ${{ inputs.version }}
+ run: |
+ VERSION="${INPUT_VERSION:-${TAG_VERSION#v}}"
+ if [[ -z "$VERSION" || "$VERSION" == "$TAG_VERSION" && "$TAG_VERSION" != v* ]]; then
+ echo "A release tag or workflow version is required"
+ exit 1
+ fi
+ ./mvnw -B versions:set -DnewVersion="$VERSION" -DgenerateBackupPoms=false
+
+ - name: Stage Maven Central artifacts
+ run: >-
+ ./mvnw -B -Prelease deploy
+ -DaltDeploymentRepository=staging::default::file:${{ github.workspace }}/target/staging-deploy
+
+ - name: Release with JReleaser
+ uses: jreleaser/release-action@v2
+ env:
+ JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ JRELEASER_GPG_PUBLIC_KEY: ${{ secrets.GPG_PUBLIC_KEY }}
+ JRELEASER_GPG_SECRET_KEY: ${{ secrets.GPG_SECRET_KEY }}
+ JRELEASER_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
+ JRELEASER_MAVENCENTRAL_USERNAME: ${{ secrets.MAVENCENTRAL_USERNAME }}
+ JRELEASER_MAVENCENTRAL_PASSWORD: ${{ secrets.MAVENCENTRAL_PASSWORD }}
+
+ - name: JReleaser release output
+ if: always()
+ uses: actions/upload-artifact@v7
+ with:
+ name: jreleaser-release-output
+ path: |
+ target/surefire-reports
+ target/jreleaser/trace.log
+ target/jreleaser/output.properties
diff --git a/RELEASE.md b/RELEASE.md
index a1fabc2..9dc576b 100644
--- a/RELEASE.md
+++ b/RELEASE.md
@@ -1,25 +1,61 @@
-Use the following to test an incremental release + deploy:
+# Release Process
+
+Releases are published to GitHub and Maven Central by JReleaser from a version tag.
+
+## Prerequisites
+
+- Push access to the `codejive/java-properties` repository.
+- A Maven Central publisher account and namespace for `org.codejive`.
+- An armored GPG key configured in the repository's `jreleaser` environment:
+ `JRELEASER_GPG_PUBLIC_KEY`, `JRELEASER_GPG_SECRET_KEY`, and
+ `JRELEASER_GPG_PASSPHRASE`.
+- The `MAVENCENTRAL_USERNAME` and `MAVENCENTRAL_PASSWORD` secrets.
+- The workflow-provided `GITHUB_TOKEN` permission to create releases.
+
+## Creating a Release
+
+1. Ensure the changes are committed and the CI workflow is green.
+2. Create and push an annotated tag whose name is the release version, for example:
+
+ ```shell
+ git tag -a v0.0.8 -m "Release v0.0.8"
+ git push origin v0.0.8
+ ```
+
+3. The `Release` workflow sets the Maven version from the tag, builds the sources and
+ Javadoc artifacts, and runs JReleaser.
+4. Verify the GitHub release and the published component on Maven Central.
+
+The workflow can also be started manually from GitHub Actions. In that case, provide
+the version without the leading `v`.
+
+## Local Configuration Check
+
+This validates the JReleaser configuration without publishing anything:
```
-mvn -B release:clean release:prepare -DdryRun=true
+./mvnw jreleaser:config
```
-If everything seems successful the following will actual perform a deploy:
+To build the artifacts that a release would stage locally:
```
-mvn -B release:clean release:prepare release:perform
+./mvnw -B -Prelease clean package
```
-_WARNING: Make sure **JAVA_HOME** is set or the release will fail!_
+Publishing should be performed by the GitHub Actions workflow so that credentials and
+signing keys remain outside the local environment.
-If something went wrong you can roll back the release using:
+## Recovery
```
-mvn release:rollback
+./mvnw jreleaser:full-release
```
-Use this command to set a specific version:
+Re-running the workflow for the same tag is safe because the JReleaser GitHub release
+configuration allows overwriting an existing release. If a release must be corrected,
+fix the source, create a new patch version, and push a new tag.
```
mvn -B release:update-versions -DdevelopmentVersion=1.2.3-SNAPSHOT
diff --git a/jreleaser.yml b/jreleaser.yml
new file mode 100644
index 0000000..b0e4421
--- /dev/null
+++ b/jreleaser.yml
@@ -0,0 +1,40 @@
+project:
+ name: java-properties
+ description: A Java Properties parser that preserves comments and formatting
+ longDescription: |
+ A drop-in replacement for java.util.Properties that preserves comments and
+ formatting when properties files are read, changed, and written.
+ authors:
+ - Tako Schotanus
+ license: Apache-2.0
+ links:
+ homepage: https://github.com/codejive/java-properties
+ stereotype: NONE
+
+release:
+ github:
+ owner: codejive
+ name: java-properties
+ overwrite: true
+ draft: false
+ changelog:
+ formatted: ALWAYS
+ preset: conventional-commits
+ contributors:
+ format: '- {{contributorName}}{{#contributorUsernameAsLink}} ({{.}}){{/contributorUsernameAsLink}}'
+
+signing:
+ active: ALWAYS
+ armored: true
+
+checksum:
+ individual: true
+
+deploy:
+ maven:
+ mavenCentral:
+ java-properties:
+ active: RELEASE
+ url: https://central.sonatype.com/api/v1/publisher
+ stagingRepositories:
+ - target/staging-deploy
\ No newline at end of file
diff --git a/pom.xml b/pom.xml
index 7c0e68e..3a675dd 100644
--- a/pom.xml
+++ b/pom.xml
@@ -103,24 +103,11 @@
3.6.0
- org.sonatype.plugins
- nexus-staging-maven-plugin
- 1.7.0
- true
+ org.jreleaser
+ jreleaser-maven-plugin
+ 1.14.0
- ossrh
- https://s01.oss.sonatype.org/
- true
-
-
-
- org.apache.maven.plugins
- maven-release-plugin
- 3.3.1
-
- release
- v@{project.version}
- deploy
+ ${project.basedir}/jreleaser.yml
@@ -158,20 +145,6 @@
-
- org.apache.maven.plugins
- maven-gpg-plugin
- 3.2.8
-
-
- sign-artifacts
- verify
-
- sign
-
-
-
-
@@ -184,14 +157,4 @@
HEAD
-
-
- ossrh
- https://s01.oss.sonatype.org/content/repositories/snapshots
-
-
- ossrh
- https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/
-
-