Skip to content

Commit 893fd68

Browse files
committed
Migrate from OSSRH to Sonatype Central publishing
- Switch to gradleup/nmcp plugin for automatic publication - Update GitHub Actions to use SONATYPE_USERNAME/SONATYPE_PASSWORD - Remove manual repository configuration and staging steps - Configure modern GPG signing using global iterable secrets
1 parent ebb029c commit 893fd68

File tree

5 files changed

+69
-94
lines changed

5 files changed

+69
-94
lines changed

.github/workflows/publish.yml

Lines changed: 38 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -1,44 +1,46 @@
1-
name: Publish to Maven Central
1+
name: Publish to Sonatype Central
22

33
on:
4-
push:
5-
tags:
6-
- 'v*' # Trigger on version tags
7-
workflow_dispatch: # Allow manual trigger
4+
push:
5+
branches:
6+
- sonatype-publish
7+
tags:
8+
- "[0-9]+.[0-9]+.[0-9]+*" # Match version tags like 3.5.13, 3.6.0-beta1, etc.
9+
workflow_dispatch: # Allow manual trigger
810

911
jobs:
10-
publish:
11-
runs-on: ubuntu-latest
12-
steps:
13-
- uses: actions/checkout@v4
12+
publish:
13+
runs-on: ubuntu-latest
14+
steps:
15+
- uses: actions/checkout@v4
1416

15-
- name: Set up JDK
16-
uses: actions/setup-java@v4
17-
with:
18-
java-version: '17'
19-
distribution: 'temurin'
20-
cache: gradle
17+
- name: Set up JDK
18+
uses: actions/setup-java@v4
19+
with:
20+
java-version: "17"
21+
distribution: "temurin"
22+
cache: gradle
2123

22-
- name: Import GPG Key
23-
run: |
24-
echo "${{ secrets.GPG_PRIVATE_KEY }}" | base64 -d > private.gpg
25-
gpg --batch --import private.gpg
26-
rm private.gpg
24+
- name: Import GPG Key and Create Secring
25+
run: |
26+
echo "${{ secrets.GPG_SECRET_KEY }}" | base64 -d > private.gpg
27+
gpg --batch --import private.gpg
28+
rm private.gpg
29+
# Create secring.gpg for Gradle signing plugin compatibility
30+
gpg --batch --pinentry-mode loopback --passphrase "${{ secrets.GPG_PASSPHRASE }}" --export-secret-keys > ~/.gnupg/secring.gpg
2731
28-
- name: Build
29-
run: ./gradlew clean build
30-
env:
31-
ORG_GRADLE_PROJECT_SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }}
32-
ORG_GRADLE_PROJECT_SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
33-
ORG_GRADLE_PROJECT_SIGNING_SECRET_KEY_RING_FILE: ~/.gnupg/secring.gpg
34-
ORG_GRADLE_PROJECT_NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }}
35-
ORG_GRADLE_PROJECT_NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }}
32+
- name: Convert GPG Key ID to short format
33+
run: |
34+
# Extract last 8 characters for short format (Gradle compatibility)
35+
SHORT_KEY_ID="${{ secrets.GPG_KEY_ID }}"
36+
SHORT_KEY_ID="${SHORT_KEY_ID: -8}"
37+
echo "SHORT_GPG_KEY_ID=$SHORT_KEY_ID" >> $GITHUB_ENV
3638
37-
- name: Publish to Maven Central
38-
run: ./gradlew uploadArchives
39-
env:
40-
ORG_GRADLE_PROJECT_SIGNING_KEY_ID: ${{ secrets.SIGNING_KEY_ID }}
41-
ORG_GRADLE_PROJECT_SIGNING_PASSWORD: ${{ secrets.SIGNING_PASSWORD }}
42-
ORG_GRADLE_PROJECT_SIGNING_SECRET_KEY_RING_FILE: ~/.gnupg/secring.gpg
43-
ORG_GRADLE_PROJECT_NEXUS_USERNAME: ${{ secrets.NEXUS_USERNAME }}
44-
ORG_GRADLE_PROJECT_NEXUS_PASSWORD: ${{ secrets.NEXUS_PASSWORD }}
39+
- name: Build and Publish to Sonatype Central
40+
run: ./gradlew clean assemble publishAllPublicationsToCentralPortal
41+
env:
42+
ORG_GRADLE_PROJECT_SIGNING_KEY_ID: ${{ env.SHORT_GPG_KEY_ID }}
43+
ORG_GRADLE_PROJECT_SIGNING_PASSWORD: ${{ secrets.GPG_PASSPHRASE }}
44+
ORG_GRADLE_PROJECT_SIGNING_SECRET_KEY_RING_FILE: /home/runner/.gnupg/secring.gpg
45+
ORG_GRADLE_PROJECT_SONATYPE_USERNAME: ${{ secrets.SONATYPE_USERNAME }}
46+
ORG_GRADLE_PROJECT_SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}

build.gradle

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,6 @@
11
// Top-level build file where you can add configuration options common to all sub-projects/modules.
22
buildscript {
33
ext.kotlin_version = '1.9.0'
4-
ext.mavenPublishEnabled = true
54
repositories {
65
google()
76
jcenter()
@@ -17,6 +16,7 @@ buildscript {
1716
exclude group: 'org.codehaus.groovy', module: 'groovy-all'
1817
}
1918
classpath "com.github.dcendents:android-maven-gradle-plugin:2.1"
19+
classpath "com.gradleup.nmcp:nmcp:0.0.8"
2020
// NOTE: Do not place your application dependencies here; they belong
2121
// in the individual module build.gradle files
2222
}
@@ -32,4 +32,4 @@ allprojects {
3232

3333
task clean(type: Delete) {
3434
delete rootProject.buildDir
35-
}
35+
}

iterableapi-ui/build.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -64,9 +64,7 @@ ext {
6464
libraryVersion = '3.5.13'
6565
}
6666

67-
if (hasProperty("mavenPublishEnabled")) {
68-
apply from: '../maven-push.gradle'
69-
}
67+
apply from: '../maven-push.gradle'
7068

7169
task javadoc(type: Javadoc) {
7270
source = android.sourceSets.main.java.srcDirs

iterableapi/build.gradle

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -91,9 +91,7 @@ ext {
9191
libraryVersion = '3.5.13'
9292
}
9393

94-
if (hasProperty("mavenPublishEnabled")) {
95-
apply from: '../maven-push.gradle'
96-
}
94+
apply from: '../maven-push.gradle'
9795

9896
task javadoc(type: Javadoc) {
9997
source = android.sourceSets.main.java.srcDirs

maven-push.gradle

Lines changed: 27 additions & 50 deletions
Original file line numberDiff line numberDiff line change
@@ -16,50 +16,42 @@
1616

1717
apply plugin: 'maven-publish'
1818
apply plugin: 'signing'
19+
apply plugin: 'com.gradleup.nmcp'
1920

2021
Properties properties = new Properties()
21-
properties.load(project.rootProject.file('local.properties').newDataInputStream())
22+
if (project.rootProject.file('local.properties').exists()) {
23+
properties.load(project.rootProject.file('local.properties').newDataInputStream())
24+
}
2225

2326
def isReleaseBuild() {
2427
return libraryVersion.contains("SNAPSHOT") == false
2528
}
2629

27-
def getReleaseRepositoryUrl() {
28-
return hasProperty('RELEASE_REPOSITORY_URL') ? RELEASE_REPOSITORY_URL
29-
: "https://oss.sonatype.org/service/local/staging/deploy/maven2/"
30-
}
30+
// Set the project version
31+
project.version = libraryVersion
3132

32-
def getSnapshotRepositoryUrl() {
33-
return hasProperty('SNAPSHOT_REPOSITORY_URL') ? SNAPSHOT_REPOSITORY_URL
34-
: "https://oss.sonatype.org/content/repositories/snapshots/"
35-
}
36-
37-
def getRepositoryUsername() {
38-
return hasProperty('NEXUS_USERNAME') ? NEXUS_USERNAME : ""
39-
}
40-
41-
def getRepositoryPassword() {
42-
return hasProperty('NEXUS_PASSWORD') ? NEXUS_PASSWORD : ""
43-
}
44-
45-
def keyID = properties.getProperty("signing.keyId")
46-
def signing_password = properties.getProperty("signing.password")
47-
def keyRingLocation = properties.getProperty("signing.secretKeyRingFile")
48-
def nexus_username = properties.getProperty("NEXUS_USERNAME")
49-
def nexus_password = properties.getProperty("NEXUS_PASSWORD")
33+
// Simple property lookup: local.properties first, then project properties (from ORG_GRADLE_PROJECT_* env vars)
34+
def keyID = properties.getProperty("signing.keyId") ?: findProperty('SIGNING_KEY_ID')
35+
def signing_password = properties.getProperty("signing.password") ?: findProperty('SIGNING_PASSWORD')
36+
def keyRingLocation = properties.getProperty("signing.secretKeyRingFile") ?: findProperty('SIGNING_SECRET_KEY_RING_FILE')
37+
def sonatype_username = properties.getProperty("SONATYPE_USERNAME") ?: findProperty('SONATYPE_USERNAME')
38+
def sonatype_password = properties.getProperty("SONATYPE_PASSWORD") ?: findProperty('SONATYPE_PASSWORD')
5039

5140
ext."signing.keyId" = keyID
52-
ext."signing.secretKeyRingFile" = keyRingLocation
5341
ext."signing.password" = signing_password
5442

43+
// Set secretKeyRingFile if provided
44+
if (keyRingLocation) {
45+
ext."signing.secretKeyRingFile" = keyRingLocation
46+
}
47+
5548
publishing {
5649
publications {
5750
release(MavenPublication) {
58-
groupId = GROUP
59-
artifactId = libraryName
60-
version = libraryVersion
61-
6251
afterEvaluate {
52+
groupId = GROUP
53+
artifactId = libraryName
54+
version = libraryVersion
6355
from components.release
6456
}
6557

@@ -92,32 +84,17 @@ publishing {
9284
}
9385
}
9486
}
95-
repositories {
96-
maven {
97-
name = "OSSRH"
98-
url = isReleaseBuild() ? getReleaseRepositoryUrl() : getSnapshotRepositoryUrl()
99-
credentials {
100-
username = nexus_username
101-
password = nexus_password
102-
}
103-
}
104-
}
10587
}
10688

10789
signing {
108-
required { isReleaseBuild() }
90+
required { isReleaseBuild() && keyID }
10991
sign publishing.publications.release
11092
}
11193

112-
tasks.register('uploadArchives') {
113-
dependsOn publishReleasePublicationToOSSRHRepository
114-
}
115-
116-
tasks.register('androidSourcesJar', Jar) {
117-
archiveClassifier = 'sources'
118-
from android.sourceSets.main.java.sourceFiles
94+
nmcp {
95+
publishAllPublications {
96+
username = sonatype_username
97+
password = sonatype_password
98+
publicationType = "AUTOMATIC"
99+
}
119100
}
120-
121-
artifacts {
122-
archives androidSourcesJar
123-
}

0 commit comments

Comments
 (0)