Skip to content

Commit 2a414e5

Browse files
committed
Convert to JReleaser
1 parent 821e78d commit 2a414e5

6 files changed

Lines changed: 366 additions & 82 deletions

File tree

CONTRIBUTING.md

Lines changed: 27 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -34,53 +34,43 @@ Ensure you add `mavenLocal()` to your consuming project and the dependency veris
3434
folder
3535

3636
# Uploading to maven central
37-
see `.github/workflows/release.yml`
3837

39-
# Uploading to maven central (manually)
38+
The project now uses [JReleaser](https://jreleaser.org/) to automate releases to Maven Central.
4039

41-
Gradle release plugin is not currently working so this is a manual process at the moment.
40+
See [JRELEASER_SETUP.md](JRELEASER_SETUP.md) for complete setup and release instructions.
4241

43-
# Setup GPG on your machine
42+
### Quick Release Steps
4443

45-
1. copy the GPG Private key into a file `private.key`
46-
1. run
44+
1. Ensure you have Maven Central Portal API credentials:
45+
- `JRELEASER_MAVENCENTRAL_USERNAME`
46+
- `JRELEASER_MAVENCENTRAL_PASSWORD`
4747

48-
```
49-
gpg --import private.key
50-
gpg -k
51-
```
48+
2. Setup GPG signing (see JRELEASER_SETUP.md)
5249

53-
## Preparing
50+
3. Update version in `gradle.properties` (remove `-SNAPSHOT`)
5451

55-
1. Create a tag `X.X.X`
56-
1. Update `gradle.properties` and remove `-SNAPSHOT` from the version number
57-
1. Check this file into version control and push the branch to the remote
58-
1. run
52+
4. Run full release:
53+
```bash
54+
./gradlew jreleaserFullRelease
55+
```
5956

60-
```
61-
export SONAR_USERNAME=?
62-
export SONAR_PASSWORD=?
63-
export ORG_GRADLE_PROJECT_signingKey="$(cat private.key)"
64-
export ORG_GRADLE_PROJECT_signingPassword=?
65-
66-
# I found shadowed classes are not included if you don't separate the gradle operations
67-
./gradlew clean shadowJar
68-
./gradlew publish -PossrhUsername=${SONAR_USERNAME} -PossrhPassword=${SONAR_PASSWORD} -Psign=true
57+
Or use step-by-step approach:
58+
```bash
59+
./gradlew clean build publishToMavenLocal -Psign
60+
./gradlew jreleaserPublish
6961
```
7062

71-
## Releasing [Full Tutorial](https://central.sonatype.org/pages/ossrh-guide.html)
63+
JReleaser will automatically:
64+
- Sign all artifacts with GPG
65+
- Publish to Maven Central via Portal API
66+
- Close and release the staging repository
67+
- Create a GitHub release
7268

73-
1. Login to SONAR (https://oss.sonatype.org)
74-
1. Click 'Staging Repositories' and locate the 'iogithubcodedabble-dev' bundle
75-
1. Review artifacts are correct in the 'Content' tab
76-
1. Press the 'Close' and give a reason such as "Jack Matthews - Confirmed artifacts are OK"
77-
1. Wait for about 1 min and press the 'Refresh button', if all sanity checks have passed the 'Release' button will be
78-
visible
79-
1. Press the 'Release' button and give a reason for releasing
80-
1. Objects should be available in about 10 min (Longer for search.maven.org)
69+
### Previous Manual Process (No Longer Needed)
8170

82-
## Cleanup
71+
The old process involved:
72+
1. Manual staging repository management via Sonatype UI
73+
2. Direct OSSRH publishing
74+
3. Manual close/release steps
8375

84-
1. Checkout master branch
85-
1. Increment version number in `gradle.properties`
86-
1. Create pull request for merge
76+
All of this is now automated by JReleaser.

JRELEASER_MIGRATION.md

Lines changed: 127 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,127 @@
1+
# JReleaser Migration Summary
2+
3+
This document summarizes the conversion from manual Maven Central publishing via OSSRH to automated publishing using JReleaser.
4+
5+
## Changes Made
6+
7+
### 1. **build.gradle**
8+
- Added JReleaser Gradle plugin: `id 'org.jreleaser' version '1.13.1'`
9+
- Applied jreleaser plugin to root project
10+
11+
### 2. **gradle/publishing.gradle**
12+
- **Removed**: Direct Sonatype OSSRH repository configuration
13+
- **Removed**: nexus-staging plugin configuration and usage
14+
- **Added**: Local repository configuration (`build/repos/release`)
15+
- **Updated**: Signing configuration to detect JReleaser environment variables
16+
- `JRELEASER_GPG_SECRET_KEY`
17+
- `JRELEASER_GPG_SECRET_KEY_FILE`
18+
- `JRELEASER_GPG_PASSPHRASE`
19+
20+
### 3. **New File: jreleaser.yml**
21+
Complete JReleaser configuration including:
22+
- Project metadata (name, description, URL, license, authors)
23+
- GPG signing configuration with verification
24+
- Maven Central Portal Publisher API configuration
25+
- Automatic repository closing and release
26+
27+
### 4. **New File: JRELEASER_SETUP.md**
28+
Comprehensive guide covering:
29+
- Prerequisites and credential setup
30+
- Step-by-step release process
31+
- Environment variable reference
32+
- Troubleshooting tips
33+
- JReleaser task reference
34+
35+
### 5. **CONTRIBUTING.md**
36+
- Replaced old manual release instructions
37+
- Added link to JRELEASER_SETUP.md
38+
- Documented new quick release steps
39+
40+
## Key Improvements
41+
42+
| Aspect | Before | After |
43+
|--------|--------|-------|
44+
| **Repository Management** | Manual via Sonatype UI | Automated by JReleaser |
45+
| **Staging** | Manual close/release steps | Auto close/release |
46+
| **Publishing** | Direct OSSRH API | Maven Central Portal API |
47+
| **GPG Signing** | Manual gradle parameters | Environment variables |
48+
| **Release Workflow** | Multi-step manual process | Single `jreleaserFullRelease` command |
49+
| **GitHub Releases** | Manual creation | Automated by JReleaser |
50+
51+
## Migration Path
52+
53+
### Old Workflow
54+
```bash
55+
# Manual staging
56+
./gradlew publish -PossrhUsername=... -PossrhPassword=... -Psign=true
57+
58+
# Manual login to Sonatype UI
59+
# - Locate staging repo
60+
# - Close repo
61+
# - Release repo
62+
# - Wait for sync
63+
```
64+
65+
### New Workflow
66+
```bash
67+
# Automated full release
68+
./gradlew jreleaserFullRelease
69+
```
70+
71+
## Backward Compatibility
72+
73+
- Old gradle properties can still be used if needed
74+
- The `net.researchgate.release` plugin is retained for version management
75+
- Manual publishing with `-PossrhUsername/-PossrhPassword` still works but not recommended
76+
77+
## Environment Setup for Releases
78+
79+
To perform releases, configure these environment variables:
80+
81+
```bash
82+
export JRELEASER_MAVENCENTRAL_USERNAME="your-sonatype-token-username"
83+
export JRELEASER_MAVENCENTRAL_PASSWORD="your-sonatype-token-password"
84+
export JRELEASER_GPG_SECRET_KEY="base64-encoded-gpg-key"
85+
export JRELEASER_GPG_PASSPHRASE="your-gpg-passphrase"
86+
export JRELEASER_GITHUB_TOKEN="github-token-if-creating-releases" # optional
87+
```
88+
89+
Or use GPG key file:
90+
```bash
91+
export JRELEASER_GPG_SECRET_KEY_FILE="/path/to/gpg/key.gpg"
92+
```
93+
94+
## Testing Before Production Release
95+
96+
1. **Dry Run**:
97+
```bash
98+
./gradlew jreleaserFullReleaseDryRun
99+
```
100+
101+
2. **Validate Config**:
102+
```bash
103+
./gradlew jreleaserValidate
104+
```
105+
106+
3. **View Config**:
107+
```bash
108+
./gradlew jreleaserConfig
109+
```
110+
111+
## Resources
112+
113+
- [JReleaser Official Documentation](https://jreleaser.org/)
114+
- [JReleaser Gradle Plugin Guide](https://jreleaser.org/guide/latest/reference/gradle.html)
115+
- [Maven Central Portal API](https://central.sonatype.org/publishing/publish-maven/)
116+
- [JRELEASER_SETUP.md](./JRELEASER_SETUP.md) - Detailed setup guide
117+
118+
## Next Steps
119+
120+
1. Store Maven Central Portal API credentials securely (e.g., GitHub Secrets)
121+
2. Optionally update CI/CD workflows to use jreleaser
122+
3. Test with a dry-run release: `./gradlew jreleaserFullReleaseDryRun`
123+
4. Perform first production release when ready
124+
125+
## Questions?
126+
127+
See [JRELEASER_SETUP.md](./JRELEASER_SETUP.md) for detailed troubleshooting and additional information.

JRELEASER_SETUP.md

Lines changed: 163 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,163 @@
1+
# JReleaser Maven Central Setup
2+
3+
This project has been converted to use [JReleaser](https://jreleaser.org/) for automated releases to Maven Central via the Portal Publisher API.
4+
5+
## Overview
6+
7+
JReleaser simplifies the release process by:
8+
- Automating version bumping and git tagging
9+
- Building and signing artifacts
10+
- Publishing to Maven Central using the new Portal API
11+
- Creating GitHub releases with changelog
12+
13+
## Prerequisites
14+
15+
Before performing a release, ensure you have:
16+
17+
1. **Maven Central Portal API Credentials**
18+
- Set environment variable: `JRELEASER_MAVENCENTRAL_USERNAME` (your Sonatype token username)
19+
- Set environment variable: `JRELEASER_MAVENCENTRAL_PASSWORD` (your Sonatype token password)
20+
- Get these from: https://central.sonatype.com/account
21+
22+
2. **GPG Signing Setup**
23+
- Export your GPG secret key in base64:
24+
```bash
25+
gpg --export-secret-keys <key-id> | base64
26+
```
27+
- Set environment variable: `JRELEASER_GPG_SECRET_KEY` with the base64-encoded key
28+
- Set environment variable: `JRELEASER_GPG_PASSPHRASE` with your GPG passphrase
29+
30+
OR use a key file:
31+
```bash
32+
export JRELEASER_GPG_SECRET_KEY_FILE=~/.gnupg/secring.gpg
33+
export JRELEASER_GPG_PASSPHRASE=<your-passphrase>
34+
```
35+
36+
3. **GitHub Token** (optional, for creating releases)
37+
- Set environment variable: `JRELEASER_GITHUB_TOKEN` with a GitHub personal access token
38+
39+
## Release Process
40+
41+
### 1. Prepare for Release
42+
Update version in `gradle.properties`:
43+
```properties
44+
version=X.Y.Z
45+
```
46+
47+
### 2. Build Artifacts
48+
```bash
49+
./gradlew clean build publishToMavenLocal -x test
50+
```
51+
52+
### 3. Full Release Workflow
53+
```bash
54+
# Dry run (recommended first)
55+
./gradlew jreleaserConfig
56+
./gradlew jreleaserFullReleaseDryRun
57+
58+
# Perform actual release
59+
./gradlew jreleaserFullRelease
60+
```
61+
62+
### 4. Manual Step-by-Step Release
63+
If you prefer to control each step:
64+
65+
```bash
66+
# 1. Build and sign artifacts
67+
./gradlew clean build publishToMavenLocal -Psign -PsigningKey="$JRELEASER_GPG_SECRET_KEY" -PsigningPassword="$JRELEASER_GPG_PASSPHRASE"
68+
69+
# 2. Copy artifacts to staging directory
70+
./gradlew :java-snapshot-testing-core:publishToMavenLocal
71+
./gradlew :java-snapshot-testing-junit4:publishToMavenLocal
72+
./gradlew :java-snapshot-testing-junit5:publishToMavenLocal
73+
./gradlew :java-snapshot-testing-plugin-jackson:publishToMavenLocal
74+
./gradlew :java-snapshot-testing-plugin-jackson3:publishToMavenLocal
75+
./gradlew :java-snapshot-testing-spock:publishToMavenLocal
76+
77+
# 3. Upload to Maven Central Portal
78+
./gradlew jreleaserPublish
79+
```
80+
81+
## JReleaser Configuration
82+
83+
The main configuration is in `jreleaser.yml`:
84+
85+
- **project**: Project metadata (name, description, URL, etc.)
86+
- **signing**: GPG signing configuration
87+
- **deploy.maven.mavenCentral**: Maven Central Portal API settings
88+
- `url`: Portal API endpoint
89+
- `closeRepository`: Auto-close staging repository
90+
- `releaseRepository`: Auto-release after publishing
91+
92+
## Environment Variables Reference
93+
94+
| Variable | Description |
95+
|----------|-------------|
96+
| `JRELEASER_MAVENCENTRAL_USERNAME` | Maven Central Portal API username |
97+
| `JRELEASER_MAVENCENTRAL_PASSWORD` | Maven Central Portal API password |
98+
| `JRELEASER_GPG_SECRET_KEY` | Base64-encoded GPG secret key |
99+
| `JRELEASER_GPG_SECRET_KEY_FILE` | Path to GPG secret key file |
100+
| `JRELEASER_GPG_PASSPHRASE` | GPG key passphrase |
101+
| `JRELEASER_GITHUB_TOKEN` | GitHub token for creating releases |
102+
| `JRELEASER_DRY_RUN` | Set to `true` to perform dry run |
103+
104+
## Useful JReleaser Tasks
105+
106+
```bash
107+
# Show current configuration
108+
./gradlew jreleaserConfig
109+
110+
# Validate configuration
111+
./gradlew jreleaserValidate
112+
113+
# Full release (dry run)
114+
./gradlew jreleaserFullReleaseDryRun
115+
116+
# Full release (execute)
117+
./gradlew jreleaserFullRelease
118+
119+
# Just publish to Maven Central
120+
./gradlew jreleaserPublish
121+
122+
# Create GitHub release
123+
./gradlew jreleaserRelease
124+
125+
# Generate changelogs
126+
./gradlew jreleaserChangelog
127+
```
128+
129+
## Troubleshooting
130+
131+
### Publication Fails
132+
- Ensure version in `gradle.properties` is not a SNAPSHOT
133+
- Verify Maven Central credentials are correct
134+
- Check that artifacts are properly signed
135+
136+
### GPG Signing Issues
137+
- Verify GPG secret key is correctly base64 encoded
138+
- Ensure passphrase is correct
139+
- Test GPG locally: `gpg --list-secret-keys`
140+
141+
### Maven Central Portal Issues
142+
- Login to https://central.sonatype.com and verify credentials
143+
- Check portal API documentation: https://central.sonatype.com/publishing/publish-maven/
144+
145+
## Migration from Previous Setup
146+
147+
The previous setup used:
148+
- `net.researchgate.release` for version management
149+
- Direct OSSRH/Sonatype publishing
150+
- Manual staging repository management with `nexus-staging`
151+
152+
The new JReleaser setup:
153+
- Still supports version management (can integrate with `net.researchgate.release`)
154+
- Automates the entire publish-to-Maven-Central flow
155+
- Uses the modern Portal Publisher API
156+
- Simplifies artifact signing and deployment
157+
158+
## Additional Resources
159+
160+
- [JReleaser Documentation](https://jreleaser.org/)
161+
- [Maven Central Portal Publisher API](https://central.sonatype.org/publishing/publish-maven/)
162+
- [JReleaser Gradle Plugin](https://jreleaser.org/guide/latest/reference/gradle.html)
163+
- [Maven Central Requirements](https://central.sonatype.org/publish/requirements/)

build.gradle

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,8 +8,11 @@ plugins {
88
id 'com.gradleup.shadow' version '9.3.2' apply false
99
id 'io.codearte.nexus-staging' version '0.22.0'
1010
id 'com.diffplug.spotless' version '8.4.0' apply false
11+
id 'org.jreleaser' version '1.13.1' apply false
1112
}
1213

14+
apply plugin: 'org.jreleaser'
15+
1316
ext {
1417
junit5Version = '5.10.2'
1518
lombokVersion = '1.18.20'

0 commit comments

Comments
 (0)