Skip to content

Commit 3b5c477

Browse files
committed
Update to new Maven Central Portal Publisher API
Major improvements: - Use new Maven Central Portal API (central.sonatype.com) instead of legacy OSSRH - Add central-publishing-maven-plugin v0.7.0 for automated publishing - Enable auto-publish with waitUntil=published (no manual UI steps!) - Update pom.xml distribution management to use new API endpoint - Update GitHub Actions workflow: - Change secrets: MAVEN_USERNAME/PASSWORD → MAVEN_CENTRAL_USERNAME/PASSWORD - Use server-id: central (instead of ossrh) - Completely rewrite PUBLISHING.md with new process: - Account creation at central.sonatype.com (no JIRA ticket needed) - Namespace verification in minutes (vs days) - User token generation from Account page - Comparison table: Old vs New way Benefits: ✅ No more JIRA tickets (sign up instantly) ✅ Namespace verification in minutes (vs 1-2 days) ✅ Fully automated publishing (no manual close/release in UI) ✅ Simpler authentication (user token from web UI) ✅ Better developer experience overall
1 parent de6f65c commit 3b5c477

3 files changed

Lines changed: 156 additions & 75 deletions

File tree

.github/workflows/publish.yml

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,9 @@ jobs:
1818
with:
1919
java-version: '17'
2020
distribution: 'temurin'
21-
server-id: ossrh
22-
server-username: MAVEN_USERNAME
23-
server-password: MAVEN_PASSWORD
21+
server-id: central
22+
server-username: MAVEN_CENTRAL_USERNAME
23+
server-password: MAVEN_CENTRAL_PASSWORD
2424
gpg-private-key: ${{ secrets.GPG_PRIVATE_KEY }}
2525
gpg-passphrase: MAVEN_GPG_PASSPHRASE
2626
cache: 'maven'
@@ -31,8 +31,8 @@ jobs:
3131
- name: Publish to Maven Central
3232
run: mvn --batch-mode deploy -P sign-artifacts
3333
env:
34-
MAVEN_USERNAME: ${{ secrets.MAVEN_USERNAME }}
35-
MAVEN_PASSWORD: ${{ secrets.MAVEN_PASSWORD }}
34+
MAVEN_CENTRAL_USERNAME: ${{ secrets.MAVEN_CENTRAL_USERNAME }}
35+
MAVEN_CENTRAL_PASSWORD: ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
3636
MAVEN_GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
3737

3838
- name: Set up JDK for GitHub Packages

PUBLISHING.md

Lines changed: 138 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -1,108 +1,157 @@
11
# Publishing Guide
22

3-
This document describes how to publish the rootly-java SDK to Maven Central and GitHub Packages.
3+
This document describes how to publish the rootly-java SDK to Maven Central and GitHub Packages using the **new Maven Central Portal Publisher API**.
44

55
## Prerequisites
66

7-
### 1. Sonatype OSSRH Account
7+
### 1. Maven Central Portal Account
88

9-
Create an account and request access to publish under the `com.rootly.client` groupId:
10-
1. Create a [Sonatype JIRA account](https://issues.sonatype.org/secure/Signup!default.jspa)
11-
2. Create a ticket requesting access to `com.rootly.client` groupId
12-
3. Follow the verification process (may require domain ownership proof)
9+
The new publishing process uses the Maven Central Portal (not the legacy Sonatype OSSRH):
1310

14-
### 2. GPG Key for Signing
11+
1. **Create account**: Go to https://central.sonatype.com/
12+
2. **Sign up** using GitHub, Google, or email
13+
3. **Verify namespace**:
14+
- Click "Add Namespace" button
15+
- Enter `com.rootly.client`
16+
- Verify ownership via:
17+
- **GitHub verification** (recommended): Add verification code to repository description or create a verification file
18+
- **DNS verification**: Add TXT record to `rootly.com` domain
19+
- **Publish verification key**: Create a public verification file
1520

16-
Maven Central requires all artifacts to be signed with GPG:
21+
**Namespace verification typically completes within minutes for GitHub verification.**
1722

18-
```bash
19-
# Generate a GPG key
20-
gpg --gen-key
23+
### 2. Generate User Token
24+
25+
Once your namespace is verified:
26+
27+
1. Go to https://central.sonatype.com/account
28+
2. Click **"Generate User Token"**
29+
3. Copy both the **Username** and **Password** (you'll need both)
30+
4. Store these securely - they're your `MAVEN_CENTRAL_USERNAME` and `MAVEN_CENTRAL_PASSWORD`
2131

22-
# List your keys
23-
gpg --list-keys
32+
**Note**: This is much simpler than the old OSSRH JIRA ticket process!
2433

25-
# Export your public key (submit to key server)
26-
gpg --keyserver keyserver.ubuntu.com --send-keys YOUR_KEY_ID
34+
### 3. GPG Key for Signing
2735

28-
# Export your private key (for GitHub Secrets)
29-
gpg --export-secret-keys YOUR_KEY_ID | base64
36+
Maven Central requires all artifacts to be signed with GPG:
37+
38+
```bash
39+
# Generate a GPG key (if you don't have one)
40+
gpg --gen-key
41+
# Follow prompts:
42+
# - Real name: Rootly (or your name)
43+
# - Email: support@rootly.com
44+
# - Set a passphrase (save this for later)
45+
46+
# List your keys to find the KEY_ID
47+
gpg --list-secret-keys --keyid-format=long
48+
# Output shows: sec rsa3072/ABCD1234EFGH5678
49+
# The part after / is your KEY_ID
50+
51+
# Upload public key to key servers (required)
52+
gpg --keyserver keyserver.ubuntu.com --send-keys ABCD1234EFGH5678
53+
gpg --keyserver keys.openpgp.org --send-keys ABCD1234EFGH5678
54+
gpg --keyserver pgp.mit.edu --send-keys ABCD1234EFGH5678
55+
56+
# Export private key in base64 for GitHub Secrets
57+
gpg --export-secret-keys ABCD1234EFGH5678 | base64
58+
# Copy the entire base64 output
3059
```
3160

32-
### 3. Configure GitHub Secrets
61+
### 4. Configure GitHub Secrets
3362

34-
Add the following secrets to your GitHub repository (Settings → Secrets and variables → Actions):
63+
Add these secrets to your GitHub repository (Settings → Secrets and variables → Actions):
3564

3665
| Secret Name | Description | How to Get |
3766
|-------------|-------------|------------|
38-
| `MAVEN_USERNAME` | Sonatype OSSRH username | Your JIRA username |
39-
| `MAVEN_PASSWORD` | Sonatype OSSRH password or token | Your JIRA password or [generated token](https://oss.sonatype.org/#profile;User%20Token) |
67+
| `MAVEN_CENTRAL_USERNAME` | Maven Central Portal username | From token generation at central.sonatype.com/account |
68+
| `MAVEN_CENTRAL_PASSWORD` | Maven Central Portal password | From token generation at central.sonatype.com/account |
4069
| `GPG_PRIVATE_KEY` | GPG private key in base64 | Run: `gpg --export-secret-keys YOUR_KEY_ID \| base64` |
4170
| `GPG_PASSPHRASE` | Passphrase for GPG key | The passphrase you set when creating the GPG key |
4271

43-
**Note**: GitHub Packages publishing uses the automatic `GITHUB_TOKEN` and requires no manual setup.
72+
```bash
73+
# Add secrets using GitHub CLI
74+
gh secret set MAVEN_CENTRAL_USERNAME --body "your-token-username"
75+
gh secret set MAVEN_CENTRAL_PASSWORD --body "your-token-password"
76+
gh secret set GPG_PASSPHRASE --body "your-gpg-passphrase"
77+
78+
# For GPG_PRIVATE_KEY (multiline):
79+
gpg --export-secret-keys ABCD1234EFGH5678 | base64 > gpg-key.txt
80+
gh secret set GPG_PRIVATE_KEY < gpg-key.txt
81+
rm gpg-key.txt
82+
```
4483

4584
## Publishing Process
4685

4786
The publish workflow runs automatically when you create a GitHub release.
4887

4988
### Step 1: Update Version
5089

51-
Update the version in both build files:
52-
5390
```bash
54-
# Update version in pom.xml
55-
sed -i '' 's/<version>0.0.1<\/version>/<version>0.0.2<\/version>/' pom.xml
56-
57-
# Update version in build.gradle
58-
sed -i '' "s/version = '0.0.1'/version = '0.0.2'/" build.gradle
59-
60-
# Or use the Makefile
91+
# Using Makefile (recommended)
6192
make bump-patch # 0.0.1 -> 0.0.2
6293
make bump-minor # 0.0.1 -> 0.1.0
6394
make bump-major # 0.0.1 -> 1.0.0
95+
96+
# Manual update
97+
sed -i '' 's/<version>0.0.1<\/version>/<version>0.0.2<\/version>/' pom.xml
98+
sed -i '' "s/version = '0.0.1'/version = '0.0.2'/" build.gradle
99+
git add pom.xml build.gradle
100+
git commit -m "Bump version to 0.0.2"
64101
```
65102

66-
### Step 2: Commit and Push
103+
### Step 2: Push Changes
67104

68105
```bash
69-
git add pom.xml build.gradle
70-
git commit -m "Bump version to 0.0.2"
71106
git push origin master
72107
```
73108

74-
### Step 3: Create a Release
75-
76-
Create a release via GitHub UI or CLI:
109+
### Step 3: Create a GitHub Release
77110

78111
```bash
79-
# Using GitHub CLI
80-
gh release create v0.0.2 --title "Release 0.0.2" --notes "Release notes here"
112+
# Using GitHub CLI (recommended)
113+
gh release create v0.0.2 \
114+
--title "Release 0.0.2" \
115+
--notes "Release notes here"
81116

82-
# Or push the tag created by make
83-
make push-tag
117+
# Or via GitHub UI:
118+
# Go to https://github.com/rootlyhq/rootly-java/releases/new
84119
```
85120

86121
### Step 4: Monitor the Workflow
87122

88-
The publish workflow will:
89-
1. Run all tests
90-
2. Deploy to Maven Central (with GPG signing)
91-
3. Deploy to GitHub Packages
123+
The publish workflow will automatically:
124+
125+
1. ✅ Run all tests
126+
2. ✅ Sign artifacts with GPG
127+
3. ✅ Deploy to Maven Central Portal
128+
4. ✅ Auto-publish to Maven Central (no manual UI steps needed!)
129+
5. ✅ Deploy to GitHub Packages
130+
131+
Check the Actions tab: https://github.com/rootlyhq/rootly-java/actions
132+
133+
### Step 5: Verify Publication
134+
135+
**Maven Central** (available within 30 minutes):
136+
- Search: https://central.sonatype.com/artifact/com.rootly.client/rootly
137+
- Check deployments: https://central.sonatype.com/publishing
138+
139+
**GitHub Packages** (available immediately):
140+
- View: https://github.com/rootlyhq/rootly-java/packages
92141

93-
Check the Actions tab in GitHub for progress.
142+
## What's Different from Legacy OSSRH?
94143

95-
### Step 5: Release on Maven Central
144+
The new Maven Central Portal is **much simpler**:
96145

97-
After the workflow completes:
98-
1. Go to [Sonatype OSSRH](https://oss.sonatype.org/)
99-
2. Log in with your credentials
100-
3. Click "Staging Repositories" in the left sidebar
101-
4. Find your repository (com.rootly.client)
102-
5. Click "Close" to validate the artifacts
103-
6. Once validation passes, click "Release" to publish
146+
| Old Way (OSSRH) | New Way (Portal) |
147+
|-----------------|------------------|
148+
| Create Sonatype JIRA ticket | Sign up at central.sonatype.com |
149+
| Wait 1-2 days for approval | Verify namespace in minutes |
150+
| Manually close/release in UI | Auto-publish with `autoPublish=true` |
151+
| Complex Nexus repository URL | Simple API endpoint |
152+
| Token from JIRA profile | Token from Account page |
104153

105-
Artifacts will be available on Maven Central within 2 hours and synchronized to Maven Central search within 4 hours.
154+
**No more manual UI steps after deployment!** The new process is fully automated.
106155

107156
## Verification
108157

@@ -137,24 +186,49 @@ Artifacts will be available on Maven Central within 2 hours and synchronized to
137186

138187
### GPG Signing Fails
139188

189+
**Error**: "gpg: signing failed: No secret key"
140190
- Verify `GPG_PRIVATE_KEY` is base64 encoded correctly
141191
- Ensure `GPG_PASSPHRASE` matches your key's passphrase
142-
- Check that the key hasn't expired: `gpg --list-keys`
192+
- Check key hasn't expired: `gpg --list-keys`
143193

144194
### Maven Central Deployment Fails
145195

146-
- Verify `MAVEN_USERNAME` and `MAVEN_PASSWORD` are correct
147-
- Check that you have permission for the `com.rootly.client` groupId
148-
- Review Sonatype JIRA ticket status
196+
**Error**: "401 Unauthorized"
197+
- Verify `MAVEN_CENTRAL_USERNAME` and `MAVEN_CENTRAL_PASSWORD` are from the token (not your login credentials)
198+
- Regenerate token at: https://central.sonatype.com/account
199+
200+
**Error**: "403 Forbidden - Namespace not verified"
201+
- Complete namespace verification at: https://central.sonatype.com/publishing
202+
- Choose GitHub verification for fastest approval
203+
204+
**Error**: "POM validation failed"
205+
- Ensure `pom.xml` has required fields: name, description, url, licenses, developers, scm
206+
- Check artifact includes -sources.jar and -javadoc.jar
149207

150208
### GitHub Packages Deployment Fails
151209

152-
- Verify the workflow has `packages: write` permission
153-
- Check that `GITHUB_TOKEN` is being passed correctly
154-
- Ensure the repository URL matches your GitHub repository
210+
**Error**: "401 Unauthorized"
211+
- Verify workflow has `packages: write` permission
212+
- Check `GITHUB_TOKEN` is being passed correctly
213+
214+
## Testing Locally
215+
216+
Before creating a release, test the publishing process locally:
217+
218+
```bash
219+
# Build and sign artifacts
220+
mvn clean verify -P sign-artifacts
221+
222+
# Check that artifacts are signed
223+
ls -la target/*.asc
224+
225+
# Test deployment (dry run)
226+
mvn deploy -P sign-artifacts -DskipTests
227+
```
155228

156229
## Resources
157230

158-
- [Maven Central Guide](https://central.sonatype.org/publish/publish-guide/)
231+
- [Maven Central Portal](https://central.sonatype.com/)
232+
- [Portal Documentation](https://central.sonatype.org/publish/publish-portal-maven/)
159233
- [GitHub Packages Maven](https://docs.github.com/en/packages/working-with-a-github-packages-registry/working-with-the-apache-maven-registry)
160-
- [GPG Key Generation](https://central.sonatype.org/publish/requirements/gpg/)
234+
- [GPG Signing Guide](https://central.sonatype.org/publish/requirements/gpg/)

pom.xml

Lines changed: 13 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,9 @@
3333

3434
<distributionManagement>
3535
<repository>
36-
<id>ossrh</id>
37-
<url>https://oss.sonatype.org/service/local/staging/deploy/maven2/</url>
36+
<id>central</id>
37+
<url>https://central.sonatype.com/api/v1/publisher</url>
3838
</repository>
39-
<snapshotRepository>
40-
<id>ossrh</id>
41-
<url>https://oss.sonatype.org/content/repositories/snapshots</url>
42-
</snapshotRepository>
4339
</distributionManagement>
4440

4541
<build>
@@ -241,6 +237,17 @@
241237
</java>
242238
</configuration>
243239
</plugin>
240+
<plugin>
241+
<groupId>org.sonatype.central</groupId>
242+
<artifactId>central-publishing-maven-plugin</artifactId>
243+
<version>0.7.0</version>
244+
<extensions>true</extensions>
245+
<configuration>
246+
<publishingServerId>central</publishingServerId>
247+
<autoPublish>true</autoPublish>
248+
<waitUntil>published</waitUntil>
249+
</configuration>
250+
</plugin>
244251
</plugins>
245252
</build>
246253

0 commit comments

Comments
 (0)