From fd2d235f3a1cce34b22669f6918f916f291c91ab Mon Sep 17 00:00:00 2001 From: 40handz Date: Fri, 17 Jul 2026 16:27:19 -0400 Subject: [PATCH 1/2] Migrate Maven Central publishing to Sonatype Central Portal Sonatype shut down OSSRH (oss.sonatype.org) on 2025-06-30. The release workflow still published through it, so v1.3.5's publish job failed silently after tag/release (issue #84) and the library has been stuck at 1.3.4 on Maven Central since Dec 2024. Replaces the manual OSSRH staging config, custom get_staging_repository_id.py script, and nexus-actions third-party action with the gradle-nexus/publish-plugin, which talks to the Central Portal's compatibility endpoint and does stage/close/release in one Gradle command. Bumps version to 1.3.6 so the fixed pipeline runs end-to-end on merge. --- .github/workflows/release.yml | 25 +++--------------------- CHANGELOG.md | 4 ++++ build.gradle | 19 +++++++++--------- scripts/get_staging_repository_id.py | 29 ---------------------------- 4 files changed, 17 insertions(+), 60 deletions(-) delete mode 100644 scripts/get_staging_repository_id.py diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c7699b8..8d212ff 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -72,8 +72,8 @@ jobs: cat < _gradle_user_home/gradle.properties github.username=${{ secrets.PUSHER_CI_GITHUB_PRIVATE_TOKEN }} github.password="" - maven.username=${{ secrets.MAVEN_USERNAME }} - maven.password=${{ secrets.MAVEN_PASSWORD }} + sonatypeUsername=${{ secrets.MAVEN_USERNAME }} + sonatypePassword=${{ secrets.MAVEN_PASSWORD }} signing.keyId=${{ secrets.SIGNING_KEY_ID }} signing.password=${{ secrets.SIGNING_PASSWORD }} signing.secretKeyRingFile=_gradle_user_home/pusher-maven-gpg-signing-key.gpg @@ -81,23 +81,4 @@ jobs: echo "${{ secrets.PUSHER_MAVEN_GPG_SIGNING_KEY }}" | base64 --decode > _gradle_user_home/pusher-maven-gpg-signing-key.gpg - name: Publish run: | - ./gradlew publish - - finish-release: - runs-on: ubuntu-latest - needs: publish - env: - NEXUS_USERNAME: ${{ secrets.MAVEN_USERNAME }} - NEXUS_PASSWORD: ${{ secrets.MAVEN_PASSWORD }} - steps: - - uses: actions/checkout@v4 - - id: get_staging_repository_id - name: Get staging repository id - run: | - echo "staging_repository_id=$(python3 scripts/get_staging_repository_id.py)" >> $GITHUB_OUTPUT - - name: Release - uses: nexus-actions/release-nexus-staging-repo@main - with: - username: ${{ secrets.MAVEN_USERNAME }} - password: ${{ secrets.MAVEN_PASSWORD }} - staging_repository_id: ${{ steps.get_staging_repository_id.outputs.staging_repository_id }} + ./gradlew publishToSonatype closeAndReleaseSonatypeStagingRepository diff --git a/CHANGELOG.md b/CHANGELOG.md index 2463689..4f635bc 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,9 @@ # Changelog +## 1.3.6 + +- [CHANGED] Migrate Maven Central publishing from the retired Sonatype OSSRH service to the Sonatype Central Portal, via the gradle-nexus/publish-plugin. 1.3.5 was tagged and released on GitHub but never reached Maven Central because OSSRH had already shut down; this release re-publishes the same code through the working pipeline. + ## 1.3.5 - [CHANGED] Update async-http-client to 3.0.6. diff --git a/build.gradle b/build.gradle index 1d96b01..000d185 100644 --- a/build.gradle +++ b/build.gradle @@ -10,6 +10,7 @@ plugins { id 'java-library' id 'maven-publish' id "signing" + id 'io.github.gradle-nexus.publish-plugin' version '2.0.0' } def getProperty = { property -> @@ -24,7 +25,7 @@ repositories { } group = "com.pusher" -version = "1.3.5" +version = "1.3.6" description = "Pusher HTTP Client" // Netty version override to address CVE-2025-24970, CVE-2025-25193, CVE-2025-55163, @@ -129,15 +130,15 @@ publishing { } } } +} + +nexusPublishing { repositories { - maven { - def releaseRepositoryUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2/" - def snapshotRepositoryUrl = "https://oss.sonatype.org/content/repositories/snapshots/" - url = version.endsWith("SNAPSHOT") ? snapshotRepositoryUrl : releaseRepositoryUrl - credentials { - username = findProperty("maven.username") ?: "" - password = findProperty("maven.password") ?: "" - } + sonatype { + nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/")) + snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/")) + username = findProperty("sonatypeUsername") ?: "" + password = findProperty("sonatypePassword") ?: "" } } } diff --git a/scripts/get_staging_repository_id.py b/scripts/get_staging_repository_id.py deleted file mode 100644 index 4d73556..0000000 --- a/scripts/get_staging_repository_id.py +++ /dev/null @@ -1,29 +0,0 @@ -import base64 -import json -import os -import sys -import urllib.request - -username = os.environ.get('NEXUS_USERNAME') -password = os.environ.get('NEXUS_PASSWORD') - -def get(url, username, password): - req = urllib.request.Request(url) - base64_auth = base64.b64encode(bytes('{}:{}'.format(username, password),'ascii')) - req.add_header("Authorization", "Basic {}".format(base64_auth.decode('utf-8'))) - req.add_header('Accept', 'application/json') - with urllib.request.urlopen(req) as response: - return response.read() - -def getRepositories(username, password): - return json.loads(get("https://oss.sonatype.org/service/local/staging/profile_repositories", username, password)) - -repositories = getRepositories(username, password).get("data") -if len(repositories) != 1: - sys.stderr.write("Zero or more than one staging repository. Exiting. Please execute the process manually.") - exit(1) - -repositoryId = repositories[0].get("repositoryId") -print(repositoryId) - - From 14b1f9f0f3e11a0d2bf2a900eb07f45a6f29deff Mon Sep 17 00:00:00 2001 From: Keith Date: Mon, 5 Oct 2026 19:23:25 -0400 Subject: [PATCH 2/2] Restore staging repository script Keep the file for now so CodeQL's Python analysis has code to scan. It is no longer used by the release workflow and can be removed once Python is removed from the CodeQL configuration. --- scripts/get_staging_repository_id.py | 29 ++++++++++++++++++++++++++++ 1 file changed, 29 insertions(+) create mode 100644 scripts/get_staging_repository_id.py diff --git a/scripts/get_staging_repository_id.py b/scripts/get_staging_repository_id.py new file mode 100644 index 0000000..4d73556 --- /dev/null +++ b/scripts/get_staging_repository_id.py @@ -0,0 +1,29 @@ +import base64 +import json +import os +import sys +import urllib.request + +username = os.environ.get('NEXUS_USERNAME') +password = os.environ.get('NEXUS_PASSWORD') + +def get(url, username, password): + req = urllib.request.Request(url) + base64_auth = base64.b64encode(bytes('{}:{}'.format(username, password),'ascii')) + req.add_header("Authorization", "Basic {}".format(base64_auth.decode('utf-8'))) + req.add_header('Accept', 'application/json') + with urllib.request.urlopen(req) as response: + return response.read() + +def getRepositories(username, password): + return json.loads(get("https://oss.sonatype.org/service/local/staging/profile_repositories", username, password)) + +repositories = getRepositories(username, password).get("data") +if len(repositories) != 1: + sys.stderr.write("Zero or more than one staging repository. Exiting. Please execute the process manually.") + exit(1) + +repositoryId = repositories[0].get("repositoryId") +print(repositoryId) + +