From 996ff07e125ed4d88e5a3ee8e90a3d49410f6ba7 Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Fri, 17 Jul 2026 15:08:23 -0400 Subject: [PATCH 01/14] [RUN-4638] Migrate publishing from Maven Central to PackageCloud Replace Sonatype Maven Central publication with PackageCloud (packagecloud.io/pagerduty/rundeckpro-test) in the release workflow. This plugin is bundled into the Rundeck distribution and does not need to be on Maven Central. Internal builds already resolve from PackageCloud. Part of RUN-4570: Maven Central publishing limits resolution. Co-authored-by: Cursor --- .github/workflows/release.yml | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b8810c3..0e476e0 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -35,10 +35,7 @@ jobs: build/libs/sshj-plugin-${{ steps.get_version.outputs.VERSION }}.jar env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - - name: Publish to Maven Central - run: ./gradlew -PsigningKey=${SIGNING_KEY_B64} -PsigningPassword=${SIGNING_PASSWORD} -PsonatypeUsername=${SONATYPE_USERNAME} -PsonatypePassword=${SONATYPE_PASSWORD} publishToSonatype closeAndReleaseSonatypeStagingRepository + - name: Publish to PackageCloud + run: ./gradlew publishAllPublicationsToPackageCloudTestRepository env: - SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }} - SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }} - SIGNING_KEY_B64: ${{ secrets.SIGNING_KEY_B64 }} - SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} + PKGCLD_WRITE_TOKEN: ${{ secrets.PKGCLD_WRITE_TOKEN }} From b25243156532b625a3775ef6d6a92f3cb42247c5 Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Fri, 17 Jul 2026 16:27:24 -0400 Subject: [PATCH 02/14] [RUN-4638] Use production PackageCloud repo with configurable URL - Rename repository from PackageCloudTest to PackageCloud - Default URL points to pagerduty/rundeckpro (production) - URL is configurable via PKGCLD_REPO_URL env var for flexibility Co-authored-by: Cursor --- .github/workflows/release.yml | 3 ++- build.gradle | 5 ++--- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 0e476e0..c564d9e 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,6 +36,7 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Publish to PackageCloud - run: ./gradlew publishAllPublicationsToPackageCloudTestRepository + run: ./gradlew publishAllPublicationsToPackageCloudRepository env: PKGCLD_WRITE_TOKEN: ${{ secrets.PKGCLD_WRITE_TOKEN }} + PKGCLD_REPO_URL: ${{ vars.PKGCLD_REPO_URL }} diff --git a/build.gradle b/build.gradle index dfa2edc..8cc2c75 100644 --- a/build.gradle +++ b/build.gradle @@ -136,12 +136,11 @@ nexusPublishing { apply from: "${rootDir}/gradle/publishing.gradle" -// Add PackageCloud repository publishing { repositories { maven { - name = "PackageCloudTest" - url = uri("https://packagecloud.io/pagerduty/rundeckpro-test/maven2") + name = "PackageCloud" + url = uri(System.getenv("PKGCLD_REPO_URL") ?: "https://packagecloud.io/pagerduty/rundeckpro/maven2") authentication { header(HttpHeaderAuthentication) } From dfb3e39b20f78693bfb447bcfa01f5736e2e7fc5 Mon Sep 17 00:00:00 2001 From: Jesus Osuna <87494173+Jesus-Osuna-M@users.noreply.github.com> Date: Fri, 17 Jul 2026 16:29:22 -0400 Subject: [PATCH 03/14] Fix formatting of PackageCloud repository URL --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index 8cc2c75..d405ad3 100644 --- a/build.gradle +++ b/build.gradle @@ -140,7 +140,7 @@ publishing { repositories { maven { name = "PackageCloud" - url = uri(System.getenv("PKGCLD_REPO_URL") ?: "https://packagecloud.io/pagerduty/rundeckpro/maven2") + url = uri(System.getenv("PKGCLD_REPO_URL") authentication { header(HttpHeaderAuthentication) } From 62195b5449822891340bb3e53d595addf38c7aac Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Fri, 17 Jul 2026 17:13:07 -0400 Subject: [PATCH 04/14] Fix syntax error breaking PackageCloud publish config Commit dfb3e39 dropped the closing paren and default URL fallback, which broke Groovy parsing of the publishing block (verified locally with the groovy CLI). Restore the closing paren and fallback URL. --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index d405ad3..8cc2c75 100644 --- a/build.gradle +++ b/build.gradle @@ -140,7 +140,7 @@ publishing { repositories { maven { name = "PackageCloud" - url = uri(System.getenv("PKGCLD_REPO_URL") + url = uri(System.getenv("PKGCLD_REPO_URL") ?: "https://packagecloud.io/pagerduty/rundeckpro/maven2") authentication { header(HttpHeaderAuthentication) } From f804a2355d34d0c70aba58acee0889f505bacaf0 Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Fri, 17 Jul 2026 18:04:44 -0400 Subject: [PATCH 05/14] Remove Sonatype config, keep GPG signing for PackageCloud publish nexusPublish/nexusPublishing was only used for the Sonatype staging repo flow and is now dead since release.yml publishes to PackageCloud. GPG signing is unrelated to Sonatype though (Gradle's signing plugin signs all configured MavenPublications, not just Sonatype's), so keep it and pass the same signing key/password to the PackageCloud publish step to produce .jar.asc/.pom.asc alongside the artifacts, consistent with how RPM/DEB packages in this org are already signed before upload. --- .github/workflows/release.yml | 4 +++- build.gradle | 11 ----------- gradle/libs.versions.toml | 2 -- gradle/publishing.gradle | 6 ++---- 4 files changed, 5 insertions(+), 18 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index c564d9e..4347e89 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -36,7 +36,9 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Publish to PackageCloud - run: ./gradlew publishAllPublicationsToPackageCloudRepository + run: ./gradlew -PsigningKey=${SIGNING_KEY_B64} -PsigningPassword=${SIGNING_PASSWORD} publishAllPublicationsToPackageCloudRepository env: PKGCLD_WRITE_TOKEN: ${{ secrets.PKGCLD_WRITE_TOKEN }} PKGCLD_REPO_URL: ${{ vars.PKGCLD_REPO_URL }} + SIGNING_KEY_B64: ${{ secrets.SIGNING_KEY_B64 }} + SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} diff --git a/build.gradle b/build.gradle index 8cc2c75..f28189c 100644 --- a/build.gradle +++ b/build.gradle @@ -3,7 +3,6 @@ plugins { id 'groovy' id 'idea' alias(libs.plugins.axionRelease) - alias(libs.plugins.nexusPublish) } group = 'org.rundeck.plugins' @@ -124,16 +123,6 @@ test { //set jar task to depend on copyToLib jar.dependsOn(copyToLib) -nexusPublishing { - packageGroup = 'org.rundeck.plugins' - repositories { - sonatype { - nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/")) - snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/")) - } - } -} - apply from: "${rootDir}/gradle/publishing.gradle" publishing { diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 905c683..5046e48 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -13,7 +13,6 @@ spock = "2.4-groovy-4.0" cglib = "3.3.0" objenesis = "3.5" axionRelease = "1.21.2" -nexusPublish = "2.0.0" # Security overrides for transitive dependencies commonsLang3 = "3.20.0" @@ -40,4 +39,3 @@ testLibs = ["junit", "groovyAll", "spockCore", "cglibNodep", "objenesis"] [plugins] axionRelease = { id = "pl.allegro.tech.build.axion-release", version.ref = "axionRelease" } -nexusPublish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "nexusPublish" } diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle index 8dd1f0f..099bad5 100644 --- a/gradle/publishing.gradle +++ b/gradle/publishing.gradle @@ -6,14 +6,12 @@ * githubSlug = Github slug e.g. 'rundeck/rundeck-cli' * developers = [ [id:'id', name:'name', email: 'email' ] ] list of developers * - * Define project properties to sign and publish when invoking publish task: + * Define project properties to sign when invoking the publish task: * * ./gradlew \ * -PsigningKey="base64 encoded gpg key" \ * -PsigningPassword="password for key" \ - * -PsonatypeUsername="sonatype token user" \ - * -PsonatypePassword="sonatype token password" \ - * publishToSonatype closeAndReleaseSonatypeStagingRepository + * publishAllPublicationsToPackageCloudRepository */ apply plugin: 'maven-publish' apply plugin: 'signing' From 704292930ee951bb21ce1207b5f81fa683ddbd84 Mon Sep 17 00:00:00 2001 From: Jesus Osuna <87494173+Jesus-Osuna-M@users.noreply.github.com> Date: Fri, 17 Jul 2026 18:17:39 -0400 Subject: [PATCH 06/14] Update Maven repository URL configuration --- build.gradle | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/build.gradle b/build.gradle index f28189c..bbd92f3 100644 --- a/build.gradle +++ b/build.gradle @@ -129,7 +129,7 @@ publishing { repositories { maven { name = "PackageCloud" - url = uri(System.getenv("PKGCLD_REPO_URL") ?: "https://packagecloud.io/pagerduty/rundeckpro/maven2") + url = uri(System.getenv("PKGCLD_REPO_URL")) authentication { header(HttpHeaderAuthentication) } From 8149aa6c42da966c5c6dc447f780293d42706de4 Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Fri, 17 Jul 2026 18:34:54 -0400 Subject: [PATCH 07/14] Move PKGCLD_REPO_URL to job-level env build.gradle reads PKGCLD_REPO_URL eagerly at configuration time, so it must be present for every ./gradlew invocation in the job (build, currentVersion), not just the publish step. Setting it only on the "Publish to PackageCloud" step's env left earlier steps with a null value, crashing with "Cannot convert 'null' to URI." --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 4347e89..b9ed912 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -10,6 +10,8 @@ jobs: build: name: Publish Release runs-on: ubuntu-latest + env: + PKGCLD_REPO_URL: ${{ vars.PKGCLD_REPO_URL }} steps: - name: Checkout code uses: actions/checkout@v7 @@ -39,6 +41,5 @@ jobs: run: ./gradlew -PsigningKey=${SIGNING_KEY_B64} -PsigningPassword=${SIGNING_PASSWORD} publishAllPublicationsToPackageCloudRepository env: PKGCLD_WRITE_TOKEN: ${{ secrets.PKGCLD_WRITE_TOKEN }} - PKGCLD_REPO_URL: ${{ vars.PKGCLD_REPO_URL }} SIGNING_KEY_B64: ${{ secrets.SIGNING_KEY_B64 }} SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} From e40bf454de5fcf5bdd8e98f5190d81109bd89148 Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Fri, 17 Jul 2026 18:41:28 -0400 Subject: [PATCH 08/14] Only register PackageCloud repo when PKGCLD_REPO_URL is set .github/workflows/gradle.yml (Java CI) runs ./gradlew build on every push and never sets PKGCLD_REPO_URL, since it has nothing to do with publishing. Since the publishing.repositories block is evaluated eagerly at configuration time regardless of which task runs, it crashed every plain build with "Cannot convert 'null' to URI." Guard the repo registration so it's skipped unless the URL is actually configured. --- build.gradle | 22 +++++++++++++--------- 1 file changed, 13 insertions(+), 9 deletions(-) diff --git a/build.gradle b/build.gradle index bbd92f3..3d02b94 100644 --- a/build.gradle +++ b/build.gradle @@ -127,15 +127,19 @@ apply from: "${rootDir}/gradle/publishing.gradle" publishing { repositories { - maven { - name = "PackageCloud" - url = uri(System.getenv("PKGCLD_REPO_URL")) - authentication { - header(HttpHeaderAuthentication) - } - credentials(HttpHeaderCredentials) { - name = "Authorization" - value = "Bearer " + (System.getenv("PKGCLD_WRITE_TOKEN") ?: project.findProperty("pkgcldWriteToken")) + // Only register the PackageCloud repo when its URL is configured, so plain + // builds/tests (which don't set PKGCLD_REPO_URL) don't fail at configuration time. + if (System.getenv("PKGCLD_REPO_URL")) { + maven { + name = "PackageCloud" + url = uri(System.getenv("PKGCLD_REPO_URL")) + authentication { + header(HttpHeaderAuthentication) + } + credentials(HttpHeaderCredentials) { + name = "Authorization" + value = "Bearer " + (System.getenv("PKGCLD_WRITE_TOKEN") ?: project.findProperty("pkgcldWriteToken")) + } } } } From a15acc8069b0531abc104b70f3b85e2707ce98aa Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Fri, 17 Jul 2026 19:14:57 -0400 Subject: [PATCH 09/14] Trim PKGCLD_REPO_URL before parsing as a URI The GitHub org variable value has a trailing newline/whitespace (common when pasted into the Actions UI), which java.net.URI rejects outright: "Cannot convert '...maven2\n ' to a URI." Trim it once and reuse the trimmed value for both the guard check and the URL itself. --- build.gradle | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/build.gradle b/build.gradle index 3d02b94..ec0d12f 100644 --- a/build.gradle +++ b/build.gradle @@ -125,14 +125,16 @@ jar.dependsOn(copyToLib) apply from: "${rootDir}/gradle/publishing.gradle" +def pkgcldRepoUrl = System.getenv("PKGCLD_REPO_URL")?.trim() + publishing { repositories { // Only register the PackageCloud repo when its URL is configured, so plain // builds/tests (which don't set PKGCLD_REPO_URL) don't fail at configuration time. - if (System.getenv("PKGCLD_REPO_URL")) { + if (pkgcldRepoUrl) { maven { name = "PackageCloud" - url = uri(System.getenv("PKGCLD_REPO_URL")) + url = uri(pkgcldRepoUrl) authentication { header(HttpHeaderAuthentication) } From a3b16cd7111667431bb9f9bcff611a686ca6c02f Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Fri, 17 Jul 2026 20:04:32 -0400 Subject: [PATCH 10/14] Drop GPG signing for PackageCloud publish PackageCloud's Maven support rejects the checksum Gradle auto-generates for the .asc signature file (422 Unprocessable Entity on sshj-plugin-*.jar.asc.sha1), aborting the whole publish task. Gradle has no public option to skip checksums for specific artifacts. Verified this isn't a regression: neither the OSS rundeck WAR nor the rundeckpro-enterprise WAR carry .asc signatures on PackageCloud either - only the RPM/DEB packages are signed there (natively, via the BUILD-GPG-KEY published on docs.rundeck.com), which was never wired through this Gradle/Maven publish path to begin with. --- .github/workflows/release.yml | 4 +--- gradle/publishing.gradle | 20 -------------------- 2 files changed, 1 insertion(+), 23 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index b9ed912..bd7d3fc 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,8 +38,6 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Publish to PackageCloud - run: ./gradlew -PsigningKey=${SIGNING_KEY_B64} -PsigningPassword=${SIGNING_PASSWORD} publishAllPublicationsToPackageCloudRepository + run: ./gradlew publishAllPublicationsToPackageCloudRepository env: PKGCLD_WRITE_TOKEN: ${{ secrets.PKGCLD_WRITE_TOKEN }} - SIGNING_KEY_B64: ${{ secrets.SIGNING_KEY_B64 }} - SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} diff --git a/gradle/publishing.gradle b/gradle/publishing.gradle index 099bad5..80005c1 100644 --- a/gradle/publishing.gradle +++ b/gradle/publishing.gradle @@ -5,16 +5,8 @@ * publishDescription = 'description' (optional) * githubSlug = Github slug e.g. 'rundeck/rundeck-cli' * developers = [ [id:'id', name:'name', email: 'email' ] ] list of developers - * - * Define project properties to sign when invoking the publish task: - * - * ./gradlew \ - * -PsigningKey="base64 encoded gpg key" \ - * -PsigningPassword="password for key" \ - * publishAllPublicationsToPackageCloudRepository */ apply plugin: 'maven-publish' -apply plugin: 'signing' publishing { publications { @@ -53,16 +45,4 @@ publishing { } } -} -def base64Decode = { String prop -> - project.findProperty(prop) ? - new String(Base64.getDecoder().decode(project.findProperty(prop).toString())).trim() : - null -} - -if (project.hasProperty('signingKey') && project.hasProperty('signingPassword')) { - signing { - useInMemoryPgpKeys(base64Decode("signingKey"), project.signingPassword) - sign(publishing.publications) - } } \ No newline at end of file From fdf71058a15c0631549e675d2b5f7891185c35c9 Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Fri, 17 Jul 2026 21:40:37 -0400 Subject: [PATCH 11/14] Fail fast in release.yml if PackageCloud env vars are missing Addresses GitHub Copilot review feedback on the PackageCloud migration PRs: without this, a missing PKGCLD_REPO_URL makes the publish task not exist at all (confusing "task not found"), and a missing PKGCLD_WRITE_TOKEN with the URL present produces a "Bearer null" Authorization header that PackageCloud rejects with a non-obvious 401/422. Validate both upfront in the one step that actually needs them, instead of leaving the Gradle-side guard (which exists to keep unrelated CI like gradle.yml working without these vars) to surface the failure indirectly. --- .github/workflows/release.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index bd7d3fc..29468f4 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -38,6 +38,11 @@ jobs: env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Publish to PackageCloud - run: ./gradlew publishAllPublicationsToPackageCloudRepository + run: | + if [ -z "$PKGCLD_REPO_URL" ] || [ -z "$PKGCLD_WRITE_TOKEN" ]; then + echo "::error::PKGCLD_REPO_URL and PKGCLD_WRITE_TOKEN must both be set to publish to PackageCloud" + exit 1 + fi + ./gradlew publishAllPublicationsToPackageCloudRepository env: PKGCLD_WRITE_TOKEN: ${{ secrets.PKGCLD_WRITE_TOKEN }} From 7d64c97129d8f28f33cd04565f2365a22a78c3e7 Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Mon, 20 Jul 2026 13:20:16 -0400 Subject: [PATCH 12/14] Fall back to rundeck-plugins PackageCloud URL, simplify token check Addresses the remaining GitHub Copilot review feedback: default pkgcldRepoUrl to the real, canonical rundeck-plugins PackageCloud URL instead of relying on PKGCLD_REPO_URL always being set. This removes the need for the "only register if URL present" guard entirely, since uri() never receives null - registering a Maven repository doesn't make any network call until something actually resolves/publishes through it, so there's no cost to always registering it. With the URL guaranteed non-null, release.yml's fail-fast check only needs to validate PKGCLD_WRITE_TOKEN (which still has no safe public default, since it's a secret). --- .github/workflows/release.yml | 4 ++-- build.gradle | 24 ++++++++++-------------- 2 files changed, 12 insertions(+), 16 deletions(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 29468f4..9cb2be7 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -39,8 +39,8 @@ jobs: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - name: Publish to PackageCloud run: | - if [ -z "$PKGCLD_REPO_URL" ] || [ -z "$PKGCLD_WRITE_TOKEN" ]; then - echo "::error::PKGCLD_REPO_URL and PKGCLD_WRITE_TOKEN must both be set to publish to PackageCloud" + if [ -z "$PKGCLD_WRITE_TOKEN" ]; then + echo "::error::PKGCLD_WRITE_TOKEN must be set to publish to PackageCloud" exit 1 fi ./gradlew publishAllPublicationsToPackageCloudRepository diff --git a/build.gradle b/build.gradle index ec0d12f..6447e59 100644 --- a/build.gradle +++ b/build.gradle @@ -125,23 +125,19 @@ jar.dependsOn(copyToLib) apply from: "${rootDir}/gradle/publishing.gradle" -def pkgcldRepoUrl = System.getenv("PKGCLD_REPO_URL")?.trim() +def pkgcldRepoUrl = (System.getenv("PKGCLD_REPO_URL") ?: "https://packagecloud.io/pagerduty/rundeck-plugins/maven2").trim() publishing { repositories { - // Only register the PackageCloud repo when its URL is configured, so plain - // builds/tests (which don't set PKGCLD_REPO_URL) don't fail at configuration time. - if (pkgcldRepoUrl) { - maven { - name = "PackageCloud" - url = uri(pkgcldRepoUrl) - authentication { - header(HttpHeaderAuthentication) - } - credentials(HttpHeaderCredentials) { - name = "Authorization" - value = "Bearer " + (System.getenv("PKGCLD_WRITE_TOKEN") ?: project.findProperty("pkgcldWriteToken")) - } + maven { + name = "PackageCloud" + url = uri(pkgcldRepoUrl) + authentication { + header(HttpHeaderAuthentication) + } + credentials(HttpHeaderCredentials) { + name = "Authorization" + value = "Bearer " + (System.getenv("PKGCLD_WRITE_TOKEN") ?: project.findProperty("pkgcldWriteToken")) } } } From b81042ab51f05e108892bf3d9009bdd1dc0c7bc7 Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Mon, 20 Jul 2026 13:59:50 -0400 Subject: [PATCH 13/14] Sign and upload GPG signatures to PackageCloud manually Gradle's signing plugin can't be used directly for this: attaching signatures via sign(publishing.publications) makes Gradle auto-generate a checksum for every artifact in the publication, including the .asc files themselves, and PackageCloud's Maven endpoint rejects the checksum-of-a-signature-file with 422 Unprocessable Entity (confirmed earlier - jar.asc uploads fine, jar.asc.sha1 does not). Sidestep this by signing the already-built artifacts with the gpg CLI directly and uploading just the .asc files via curl, bypassing Gradle's publish/checksum machinery entirely for this part. Reuses the existing SIGNING_KEY_B64/SIGNING_PASSWORD secrets from the old Sonatype flow. --- .github/workflows/release.yml | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 9cb2be7..6085931 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -46,3 +46,28 @@ jobs: ./gradlew publishAllPublicationsToPackageCloudRepository env: PKGCLD_WRITE_TOKEN: ${{ secrets.PKGCLD_WRITE_TOKEN }} + - name: Sign and upload GPG signatures to PackageCloud + run: | + set -e + VERSION="${{ steps.get_version.outputs.VERSION }}" + BASE_URL="${PKGCLD_REPO_URL:-https://packagecloud.io/pagerduty/rundeck-plugins/maven2}/org/rundeck/plugins/sshj-plugin/${VERSION}" + + echo "$SIGNING_KEY_B64" | base64 -d | gpg --batch --yes --import + + sign_and_upload() { + local FILE="$1" + local REMOTE_NAME="$2" + gpg --batch --yes --pinentry-mode loopback --passphrase "$SIGNING_PASSWORD" --detach-sign --armor "$FILE" + curl -sf -H "Authorization: Bearer ${PKGCLD_WRITE_TOKEN}" \ + -X PUT --data-binary "@${FILE}.asc" \ + "${BASE_URL}/${REMOTE_NAME}.asc" + } + + sign_and_upload "build/libs/sshj-plugin-${VERSION}.jar" "sshj-plugin-${VERSION}.jar" + sign_and_upload "build/libs/sshj-plugin-${VERSION}-sources.jar" "sshj-plugin-${VERSION}-sources.jar" + sign_and_upload "build/libs/sshj-plugin-${VERSION}-javadoc.jar" "sshj-plugin-${VERSION}-javadoc.jar" + sign_and_upload "build/publications/sshj-plugin/pom-default.xml" "sshj-plugin-${VERSION}.pom" + env: + SIGNING_KEY_B64: ${{ secrets.SIGNING_KEY_B64 }} + SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }} + PKGCLD_WRITE_TOKEN: ${{ secrets.PKGCLD_WRITE_TOKEN }} From addbb35de5d23af2cbc372e306fe98ca41d1c855 Mon Sep 17 00:00:00 2001 From: Jesus Osuna Date: Mon, 20 Jul 2026 14:03:57 -0400 Subject: [PATCH 14/14] Pass --default-key explicitly to gpg --detach-sign gpg imported the secret key fine but had no default signing identity configured, so --detach-sign failed with "no default secret key: No secret key" in batch/non-interactive mode. Extract the imported key's ID and pass it explicitly. --- .github/workflows/release.yml | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 6085931..939c187 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -53,11 +53,12 @@ jobs: BASE_URL="${PKGCLD_REPO_URL:-https://packagecloud.io/pagerduty/rundeck-plugins/maven2}/org/rundeck/plugins/sshj-plugin/${VERSION}" echo "$SIGNING_KEY_B64" | base64 -d | gpg --batch --yes --import + KEY_ID=$(gpg --list-secret-keys --with-colons | awk -F: '/^sec/ {print $5; exit}') sign_and_upload() { local FILE="$1" local REMOTE_NAME="$2" - gpg --batch --yes --pinentry-mode loopback --passphrase "$SIGNING_PASSWORD" --detach-sign --armor "$FILE" + gpg --batch --yes --pinentry-mode loopback --passphrase "$SIGNING_PASSWORD" --default-key "$KEY_ID" --detach-sign --armor "$FILE" curl -sf -H "Authorization: Bearer ${PKGCLD_WRITE_TOKEN}" \ -X PUT --data-binary "@${FILE}.asc" \ "${BASE_URL}/${REMOTE_NAME}.asc"