Skip to content

Commit 36a6f9a

Browse files
committed
Migrate using maven central (#800)
Motivation: OSSRH is deprecated and will be shut down soon. Let's switch to using maven central Modifications: - Replace old plugin with central-publishing-maven-plugin for release - Adjust workflow to setup the right token / password - Add scripts Result: Snapshot deployments and release works again
1 parent 405f3a4 commit 36a6f9a

9 files changed

+172
-52
lines changed

.github/scripts/bundle_create.sh

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
#!/bin/bash
2+
# ----------------------------------------------------------------------------
3+
# Copyright 2025 The Netty Project
4+
#
5+
# The Netty Project licenses this file to you under the Apache License,
6+
# version 2.0 (the "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at:
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
# ----------------------------------------------------------------------------
17+
set -e
18+
19+
if [ "$#" -ne 2 ]; then
20+
echo "Expected bundle name and directory"
21+
exit 1
22+
fi
23+
24+
# Create a bundle zip that contains all jars.
25+
# See https://central.sonatype.org/publish/publish-portal-upload/
26+
pushd $2
27+
zip -r $1 * -x maven-metadata-central-staging.xml
28+
popd

.github/scripts/bundle_upload.sh

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#!/bin/bash
2+
# ----------------------------------------------------------------------------
3+
# Copyright 2025 The Netty Project
4+
#
5+
# The Netty Project licenses this file to you under the Apache License,
6+
# version 2.0 (the "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at:
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
# ----------------------------------------------------------------------------
17+
set -e
18+
19+
if [ "$#" -ne 3 ]; then
20+
echo "Expected bundle-name, username, password"
21+
exit 1
22+
fi
23+
24+
# Generate the correct Bearer.
25+
# See https://central.sonatype.org/publish/publish-portal-api/
26+
BEARER=`printf "$2:$3" | base64`
27+
28+
# Upload a previous build bundle.
29+
# See https://central.sonatype.org/publish/publish-portal-api/
30+
curl --request POST \
31+
--header "Authorization: Bearer $BEARER" \
32+
--form bundle=@$1 \
33+
https://central.sonatype.com/api/v1/publisher/upload
Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,34 @@
1+
#!/bin/bash
2+
# ----------------------------------------------------------------------------
3+
# Copyright 2025 The Netty Project
4+
#
5+
# The Netty Project licenses this file to you under the Apache License,
6+
# version 2.0 (the "License"); you may not use this file except in compliance
7+
# with the License. You may obtain a copy of the License at:
8+
#
9+
# https://www.apache.org/licenses/LICENSE-2.0
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
13+
# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
14+
# License for the specific language governing permissions and limitations
15+
# under the License.
16+
# ----------------------------------------------------------------------------
17+
18+
set -e
19+
if [ "$#" -lt 2 ]; then
20+
echo "Expected target directory and at least one local staging directory"
21+
exit 1
22+
fi
23+
TARGET=$1
24+
25+
for ((i=2; i<=$#; i++))
26+
do
27+
DIR="${!i}"
28+
29+
if [ ! -d "${TARGET}" ]
30+
then
31+
mkdir -p "${TARGET}"
32+
fi
33+
cp -r "${DIR}"/"${SUB_DIR}"/* "${TARGET}/${SUB_DIR}"/
34+
done

.github/workflows/ci-deploy.yml

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -58,9 +58,9 @@ jobs:
5858
with:
5959
servers: |
6060
[{
61-
"id": "sonatype-nexus-staging",
62-
"username": "${{ secrets.SONATYPE_USERNAME }}",
63-
"password": "${{ secrets.SONATYPE_PASSWORD }}"
61+
"id": "central-portal-snapshots",
62+
"username": "${{ secrets.MAVEN_CENTRAL_USERNAME }}",
63+
"password": "${{ secrets.MAVEN_CENTRAL_PASSWORD }}"
6464
}]
6565
6666
- name: Create local staging directory
@@ -127,13 +127,13 @@ jobs:
127127
with:
128128
servers: |
129129
[{
130-
"id": "sonatype-nexus-staging",
131-
"username": "${{ secrets.SONATYPE_USERNAME }}",
132-
"password": "${{ secrets.SONATYPE_PASSWORD }}"
130+
"id": "central-portal-snapshots",
131+
"username": "${{ secrets.MAVEN_CENTRAL_USERNAME }}",
132+
"password": "${{ secrets.MAVEN_CENTRAL_PASSWORD }}"
133133
}]
134134
135135
- name: Stage snapshots to local staging directory
136-
run: ./mvnw.cmd -B -ntp --file pom.xml clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=/local-staging -DskipRemoteStaging=true -DskipTests=true
136+
run: ./mvnw.cmd -B -ntp --file pom.xml -Pstage-snapshot clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=/local-staging
137137

138138
- name: Upload local staging directory
139139
uses: actions/upload-artifact@v4
@@ -175,14 +175,23 @@ jobs:
175175
restore-keys: |
176176
pr-${{ matrix.setup }}-maven-cache-
177177
178+
- uses: s4u/[email protected]
179+
with:
180+
servers: |
181+
[{
182+
"id": "central-portal-snapshots",
183+
"username": "${{ secrets.MAVEN_CENTRAL_USERNAME }}",
184+
"password": "${{ secrets.MAVEN_CENTRAL_PASSWORD }}"
185+
}]
186+
178187
- name: Install tools via brew
179188
run: brew bundle
180189

181190
- name: Create local staging directory
182191
run: mkdir -p ~/local-staging
183192

184193
- name: Stage snapshots to local staging directory
185-
run: ./mvnw -B -ntp clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=$HOME/local-staging -DskipRemoteStaging=true -DskipTests=true
194+
run: ./mvnw -B -ntp -Pstage-snapshot clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=$HOME/local-staging
186195

187196
- name: Upload local staging directory
188197
uses: actions/upload-artifact@v4
@@ -214,11 +223,6 @@ jobs:
214223
restore-keys: |
215224
deploy-staged-snapshots-maven-cache-
216225
217-
# Setup some env to re-use later.
218-
- name: Prepare enviroment variables
219-
run: |
220-
echo "LOCAL_STAGING_DIR=$HOME/local-staging" >> $GITHUB_ENV
221-
222226
# Hardcode the staging artifacts that need to be downloaded.
223227
# These must match the matrix setups and windows build. There is currently no way to pull this out of the config.
224228
- name: Download windows_x86_64 staging directory
@@ -252,16 +256,16 @@ jobs:
252256
path: ~/linux-x86_64-local-staging
253257

254258
- name: Merge staging repositories
255-
run: bash ./.github/scripts/merge_local_staging.sh ~/local-staging ~/windows-x86_64-local-staging ~/macos-x86_64-local-staging ~/macos-aarch64-local-staging ~/linux-aarch64-local-staging ~/linux-x86_64-local-staging
259+
run: bash ./.github/scripts/local_staging_merge_snapshot.sh ~/local-staging ~/windows-x86_64-local-staging ~/macos-x86_64-local-staging ~/macos-aarch64-local-staging ~/linux-aarch64-local-staging ~/linux-x86_64-local-staging
256260

257261
- uses: s4u/[email protected]
258262
with:
259263
servers: |
260264
[{
261-
"id": "sonatype-nexus-snapshots",
262-
"username": "${{ secrets.SONATYPE_USERNAME }}",
263-
"password": "${{ secrets.SONATYPE_PASSWORD }}"
265+
"id": "central-portal-snapshots",
266+
"username": "${{ secrets.MAVEN_CENTRAL_USERNAME }}",
267+
"password": "${{ secrets.MAVEN_CENTRAL_PASSWORD }}"
264268
}]
265269
266270
- name: Deploy local staged artifacts
267-
run: ./mvnw -B -ntp --file pom.xml org.sonatype.plugins:nexus-staging-maven-plugin:deploy-staged -DaltStagingDirectory=$LOCAL_STAGING_DIR
271+
run: ./mvnw -B -ntp --file pom.xml -Pstage-snapshot org.sonatype.plugins:nexus-staging-maven-plugin:deploy-staged -DaltStagingDirectory=$HOME/local-staging

.github/workflows/ci-release.yml

Lines changed: 20 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -128,9 +128,9 @@ jobs:
128128
with:
129129
servers: |
130130
[{
131-
"id": "sonatype-nexus-staging",
132-
"username": "${{ secrets.SONATYPE_USERNAME }}",
133-
"password": "${{ secrets.SONATYPE_PASSWORD }}"
131+
"id": "central",
132+
"username": "${{ secrets.MAVEN_CENTRAL_USERNAME }}",
133+
"password": "${{ secrets.MAVEN_CENTRAL_PASSWORD }}"
134134
}]
135135
136136
- name: Create local staging directory
@@ -152,7 +152,7 @@ jobs:
152152
uses: actions/upload-artifact@v4
153153
with:
154154
name: ${{ matrix.setup }}-local-staging
155-
path: ~/local-staging
155+
path: ./prepare-release-workspace/target/central-staging
156156
if-no-files-found: error
157157
include-hidden-files: true
158158

@@ -232,22 +232,20 @@ jobs:
232232
with:
233233
servers: |
234234
[{
235-
"id": "sonatype-nexus-staging",
236-
"username": "${{ secrets.SONATYPE_USERNAME }}",
237-
"password": "${{ secrets.SONATYPE_PASSWORD }}"
235+
"id": "central",
236+
"username": "${{ secrets.MAVEN_CENTRAL_USERNAME }}",
237+
"password": "${{ secrets.MAVEN_CENTRAL_PASSWORD }}"
238238
}]
239239
240240
- name: Stage release to local staging directory
241241
working-directory: ${{ github.workspace }}/prepare-release-workspace
242-
env:
243-
LOCAL_STAGING_DIR: ${{ github.workspace }}/prepare-release-workspace/local-staging
244-
run: ./mvnw.cmd -B -ntp --file pom.xml clean javadoc:jar package gpg:sign org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DnexusUrl=https://oss.sonatype.org -DserverId=sonatype-nexus-staging -DaltStagingDirectory=/local-staging -DskipRemoteStaging=true -DskipTests=true -D'checkstyle.skip=true'
242+
run: ./mvnw.cmd -B -ntp clean package javadoc:jar gpg:sign org.sonatype.central:central-publishing-maven-plugin:publish -DskipTests=true -D'checkstyle.skip=true'
245243

246244
- name: Upload local staging directory
247245
uses: actions/upload-artifact@v4
248246
with:
249247
name: windows-x86_64-local-staging
250-
path: /local-staging
248+
path: ./prepare-release-workspace/target/central-staging
251249
if-no-files-found: error
252250
include-hidden-files: true
253251

@@ -308,9 +306,9 @@ jobs:
308306
with:
309307
servers: |
310308
[{
311-
"id": "sonatype-nexus-staging",
312-
"username": "${{ secrets.SONATYPE_USERNAME }}",
313-
"password": "${{ secrets.SONATYPE_PASSWORD }}"
309+
"id": "central",
310+
"username": "${{ secrets.MAVEN_CENTRAL_USERNAME }}",
311+
"password": "${{ secrets.MAVEN_CENTRAL_PASSWORD }}"
314312
}]
315313
316314
# Cache .m2/repository
@@ -332,13 +330,13 @@ jobs:
332330

333331
- name: Stage snapshots to local staging directory
334332
working-directory: ./prepare-release-workspace/
335-
run: ./mvnw -B -ntp clean javadoc:jar package gpg:sign org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DnexusUrl=https://oss.sonatype.org -DserverId=sonatype-nexus-staging -DaltStagingDirectory=$HOME/local-staging -DskipRemoteStaging=true -DskipTests=true -Dgpg.passphrase=${{ secrets.GPG_PASSPHRASE }} -Dgpg.keyname=${{ secrets.GPG_KEYNAME }}
333+
run: ./mvnw -B -ntp clean package javadoc:jar gpg:sign org.sonatype.central:central-publishing-maven-plugin:publish -DskipTests=true
336334

337335
- name: Upload local staging directory
338336
uses: actions/upload-artifact@v4
339337
with:
340338
name: ${{ matrix.setup }}-local-staging
341-
path: ~/local-staging
339+
path: ./prepare-release-workspace/target/central-staging
342340
if-no-files-found: error
343341
include-hidden-files: true
344342

@@ -415,7 +413,7 @@ jobs:
415413
# all together with one maven command.
416414
- name: Merge staging repositories
417415
working-directory: ./prepare-release-workspace/
418-
run: bash ./.github/scripts/merge_local_staging.sh ~/local-staging/staging ~/windows-x86_64-local-staging/staging ~/macos-x86_64-local-staging/staging ~/macos-aarch64-local-staging/staging ~/linux-aarch64-local-staging/staging ~/linux-x86_64-local-staging/staging
416+
run: bash ./.github/scripts/local_staging_merge_release.sh ~/local-staging ~/windows-x86_64-local-staging ~/macos-x86_64-local-staging ~/macos-aarch64-local-staging ~/linux-aarch64-local-staging ~/linux-x86_64-local-staging
419417

420418
# Caching of maven dependencies
421419
- uses: actions/cache@v4
@@ -426,19 +424,13 @@ jobs:
426424
restore-keys: |
427425
deploy-staged-release-maven-cache-
428426
429-
- uses: s4u/[email protected]
430-
with:
431-
servers: |
432-
[{
433-
"id": "sonatype-nexus-staging",
434-
"username": "${{ secrets.SONATYPE_USERNAME }}",
435-
"password": "${{ secrets.SONATYPE_PASSWORD }}"
436-
}]
427+
- name: Create bundle
428+
working-directory: ./prepare-release-workspace/
429+
run: bash ./.github/scripts/bundle_create.sh ~/central-bundle.zip ~/local-staging/
437430

438-
- name: Deploy local staged artifacts
431+
- name: Upload bundle to maven central
439432
working-directory: ./prepare-release-workspace/
440-
# If we don't want to close the repository we can add -DskipStagingRepositoryClose=true
441-
run: ./mvnw -B -ntp --file pom.xml org.sonatype.plugins:nexus-staging-maven-plugin:deploy-staged -DnexusUrl=https://oss.sonatype.org -DserverId=sonatype-nexus-staging -DaltStagingDirectory=/home/runner/local-staging -DskipStagingRepositoryClose=true
433+
run: bash ./.github/scripts/bundle_upload.sh ~/central-bundle.zip ${{ secrets.MAVEN_CENTRAL_USERNAME }} ${{ secrets.MAVEN_CENTRAL_PASSWORD }}
442434

443435
- name: Rollback release on failure
444436
working-directory: ./prepare-release-workspace/

docker/docker-compose.centos-7-cross.yaml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ services:
5858
- ~/.m2/settings.xml:/root/.m2/settings.xml
5959
- ~/local-staging:/root/local-staging
6060
- ..:/code
61-
command: /bin/bash -cl "./mvnw -B -ntp -Plinux-aarch64 clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true"
61+
command: /bin/bash -cl "./mvnw -B -ntp -Plinux-aarch64,stage-snapshot clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=/root/local-staging"
6262

6363
cross-compile-aarch64-stage-release:
6464
<<: *cross-compile-aarch64-common
@@ -68,7 +68,7 @@ services:
6868
- ~/.m2/repository:/root/.m2/repository
6969
- ~/local-staging:/root/local-staging
7070
- ..:/code
71-
command: /bin/bash -cl "cat <(echo -e \"${GPG_PRIVATE_KEY}\") | gpg --batch --import && ./mvnw -B -ntp -Plinux-aarch64 clean javadoc:jar package gpg:sign org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DnexusUrl=https://oss.sonatype.org -DserverId=sonatype-nexus-staging -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true -Dgpg.passphrase=${GPG_PASSPHRASE} -Dgpg.keyname=${GPG_KEYNAME}"
71+
command: /bin/bash -cl "cat <(echo -e \"${GPG_PRIVATE_KEY}\") | gpg --batch --import && ./mvnw -B -ntp -Plinux-aarch64 clean package javadoc:jar gpg:sign org.sonatype.central:central-publishing-maven-plugin:publish -DskipTests=true -Dgpg.passphrase=${GPG_PASSPHRASE} -Dgpg.keyname=${GPG_KEYNAME}"
7272

7373
cross-compile-aarch64-install:
7474
<<: *cross-compile-aarch64-common

docker/docker-compose.centos-7.yaml

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ services:
7272
- ~/.m2/repository:/root/.m2/repository
7373
- ~/local-staging:/root/local-staging
7474
- ..:/code
75-
command: /bin/bash -cl "./mvnw -B -ntp clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true"
75+
command: /bin/bash -cl "./mvnw -B -ntp -Pstage-snapshot clean package org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DaltStagingDirectory=/root/local-staging"
7676

7777
stage-release:
7878
<<: *common
@@ -82,8 +82,7 @@ services:
8282
- ~/.m2/repository:/root/.m2/repository
8383
- ~/local-staging:/root/local-staging
8484
- ..:/code
85-
command: /bin/bash -cl "cat <(echo -e \"${GPG_PRIVATE_KEY}\") | gpg --batch --import && ./mvnw -B -ntp clean javadoc:jar package gpg:sign org.sonatype.plugins:nexus-staging-maven-plugin:deploy -DnexusUrl=https://oss.sonatype.org -DserverId=sonatype-nexus-staging -DaltStagingDirectory=/root/local-staging -DskipRemoteStaging=true -DskipTests=true -Dgpg.passphrase=${GPG_PASSPHRASE} -Dgpg.keyname=${GPG_KEYNAME}"
86-
85+
command: /bin/bash -cl "cat <(echo -e \"${GPG_PRIVATE_KEY}\") | gpg --batch --import && ./mvnw -B -ntp clean package javadoc:jar gpg:sign org.sonatype.central:central-publishing-maven-plugin:publish -DskipTests=true -Dgpg.passphrase=${GPG_PASSPHRASE} -Dgpg.keyname=${GPG_KEYNAME}"
8786
shell:
8887
<<: *common
8988
volumes:

pom.xml

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,6 +65,14 @@
6565
</developer>
6666
</developers>
6767

68+
<distributionManagement>
69+
<snapshotRepository>
70+
<name>Central Portal Snapshots</name>
71+
<id>central-portal-snapshots</id>
72+
<url>https://central.sonatype.com/repository/maven-snapshots/</url>
73+
</snapshotRepository>
74+
</distributionManagement>
75+
6876
<modules>
6977
<module>codec-classes-quic</module>
7078
<module>codec-native-quic</module>
@@ -464,6 +472,28 @@
464472
<scope>provided</scope>
465473
</dependency>
466474
</dependencies>
467-
468475
</dependencyManagement>
476+
477+
<profiles>
478+
<profile>
479+
<id>stage-snapshot</id>
480+
<properties>
481+
<skipTests>true</skipTests>
482+
</properties>
483+
<build>
484+
<plugins>
485+
<plugin>
486+
<groupId>org.sonatype.plugins</groupId>
487+
<artifactId>nexus-staging-maven-plugin</artifactId>
488+
<version>1.7.0</version>
489+
<configuration>
490+
<serverId>central-portal-snapshots</serverId>
491+
<nexusUrl>https://central.sonatype.com/repository/maven-snapshots</nexusUrl>
492+
<skipRemoteStaging>true</skipRemoteStaging>
493+
</configuration>
494+
</plugin>
495+
</plugins>
496+
</build>
497+
</profile>
498+
</profiles>
469499
</project>

0 commit comments

Comments
 (0)