@@ -8,166 +8,178 @@ ext.publishingInfo.pomName = ext.publishingInfo.artifactId
88apply from : " gradle/project-info.gradle"
99apply plugin : ' signing'
1010
11- // -----------------------------------------------------------------------------
12- // Performs publishing
13- // -----------------------------------------------------------------------------
14-
15- task javadocJar (type : Jar , dependsOn : javadoc) {
16- archiveClassifier = ' javadoc'
17- from javadoc. destinationDir
18- }
19-
20- // create one jar for the source files
21- task sourcesJar (type : Jar , dependsOn : classes) {
22- archiveClassifier = ' sources'
23- from sourceSets. main. allSource
24- }
25-
26- artifacts {
27- archives jar
28- archives javadocJar
29- archives sourcesJar
11+ // This replaces the old manual `javadocJar` and `sourcesJar` tasks.
12+ java {
13+ withJavadocJar()
14+ withSourcesJar()
3015}
3116
32- Date buildTimeAndDate = new Date ()
33- ext {
34- buildDate = new java.text.SimpleDateFormat (' yyyy-MM-dd' ). format(buildTimeAndDate)
35- buildTime = new java.text.SimpleDateFormat (' HH:mm:ss.SSSZ' ). format(buildTimeAndDate)
36- }
17+ // REMOVED: The old manual tasks for javadocJar, sourcesJar, and the `artifacts {}`
18+ // block are no longer needed with the modern `java` component configuration above.
3719
38- jar {
39- manifest {
40- attributes(
41- ' Built-By' : System . properties[' user.name' ],
42- ' Created-By' : System . properties[' java.version' ] + " (" + System . properties[' java.vendor' ] + " " + System . properties[' java.vm.version' ] + " )" ,
43- ' Build-Date' : project. buildDate,
44- ' Build-Time' : project. buildTime,
45- ' Build-Revision' : versioning. info. commit,
46- ' Specification-Title' : project. name,
47- ' Specification-Version' : project. version,
48- ' Implementation-Title' : project. name,
49- ' Implementation-Version' : project. version
50- )
51- }
52- }
20+ publishing {
21+ publications {
22+ mavenJava(MavenPublication ) {
23+ // Read basic coordinates from your project-info.gradle
24+ groupId publishingInfo. groupId
25+ artifactId publishingInfo. artifactId
26+ version publishingInfo. versionId
5327
28+ // Tell Gradle to publish the components of the 'java' project.
29+ // This automatically includes the main JAR, sources JAR, and javadoc JAR.
30+ from components. java
5431
55- def pomConfig = {
56- name ext. publishingInfo. pomName
57- description ext. publishingInfo. desc
58- url ext. publishingInfo. websiteUrl
59- inceptionYear ext. publishingInfo. inceptionYear
60- licenses {
61- license([:]) {
62- name ext. publishingInfo. license
63- url ext. publishingInfo. licenseUrl
64- distribution ' repo'
65- }
66- }
67- scm {
68- url ext. publishingInfo. vcsUrl
69- connection ext. publishingInfo. vcsUrl
70- developerConnection ext. publishingInfo. vcsUrl
71- }
72- developers {
73- developer {
74- id ext. publishingInfo. developerNameAlias
75- name ext. publishingInfo. developerName
32+ // NEW: Modern POM configuration using the standard DSL.
33+ // This is much cleaner than the old `pom.withXml` and `pomConfig` closure.
34+ pom {
35+ name = publishingInfo. pomName
36+ description = publishingInfo. desc
37+ url = publishingInfo. websiteUrl
38+ inceptionYear = publishingInfo. inceptionYear
39+
40+ licenses {
41+ license {
42+ name = publishingInfo. license
43+ url = publishingInfo. licenseUrl
44+ distribution = ' repo'
45+ }
46+ }
47+ developers {
48+ developer {
49+ id = publishingInfo. developerAlias
50+ name = publishingInfo. developerName
51+ email = publishingInfo. developerEmail
52+ }
53+ }
54+ scm {
55+ url = publishingInfo. vcsUrl
56+ connection = publishingInfo. vcsUrl
57+ developerConnection = publishingInfo. vcsUrl
58+ }
59+ }
7660 }
7761 }
78- }
79-
80-
81-
82- publishing {
8362
8463 repositories {
85- // --------------------------------------------------------------------------------
86- // Destination Repository 'GitHubPackages'
87- // -> call task 'publishMavenJavaPublicationToGitHubPackagesRepository' to publish
88- // --------------------------------------------------------------------------------
64+ // Your GitHub Packages repository can remain as is
8965 maven {
9066 name = " GitHubPackages"
91- // see https://levelup.gitconnected.com/publish-a-maven-package-to-github-with-gradle-fabc6de24d6
92- // Replace OWNER and REPOSITORY with your GitHub username/repository
93- // (must be both lowercase according to the documenations)
94- // url = uri("https://maven.pkg.github.com/OWNER/REPOSITORY")
9567 url = uri(project. findProperty(' publishingInfo' ). gitHubMavenRepo)
9668 credentials {
97- // Make sure to generate a token with write-packages and read-packages permission:
98- // https://github.com/settings/tokens/new
99- // You can either store the username and token in
100- // ~/.gradle/gradle.properties (use the gpr.user and gpr.key keys)
101- // Or you can store them as environment variables e.g. in ~/.bash_profile or ~/.zsh
102- // depending on your shell (GITHUB_USERNAME and GITHUB_TOKEN keys)
103- // Or you pass them via CLI: gradle publish -Pgpr.user=username -Pgpr.key=token
104- // See at EOF for examples on how to store the credentials
10569 username = project. findProperty(" gpr.user" ) ?: System . getenv(" GITHUB_USERNAME" )
10670 password = project. findProperty(" gpr.key" ) ?: System . getenv(" GITHUB_TOKEN" )
10771 }
10872 }
10973
11074 // --------------------------------------------------------------------------------
111- // Destination Repository 'OSSRH'
112- // telling gradle to publish artifact to local directory
113- // -> call task 'publishMavenJavaPublicationToOSSRHRepository' to publish
114- // -> go to https://oss.sonatype.org/#stagingRepositories, click 'close', drink coffee and then click 'release'
115- // if closing was successful
75+ // Destination Repository 'MavenCentral'
76+ // Publishes artifacts to the new Sonatype Central Portal staging repository.
77+ // -> Call task 'publishMavenJavaPublicationToMavenCentralRepository' to publish.
78+ // -> Visit https://central.sonatype.com/staging, close the repository, then release it if closing was s
11679 // --------------------------------------------------------------------------------
80+ // maven {
81+ // name = "MavenCentral" // Renamed from "OSSRH" for clarity
82+ // // The new URL for the Central Portal Staging API
83+ // // Defines the URLs for both repositories (snapshot vs. regular)
84+ // def releasesRepoUrl = url = "https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/"
85+ // def snapshotsRepoUrl = url = "https://central.sonatype.com/repository/maven-snapshots/"
86+ //
87+ // // Select the URL based on the version
88+ // url = uri(publishingInfo.versionId.endsWith('-SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl)
89+ //
90+ // credentials {
91+ // // Use the new User Token credentials from central.sonatype.com
92+ // username = project.findProperty("mavenCentralUsername") ?: System.getenv("CENTRAL_PORTAL_USERNAME")
93+ // password = project.findProperty("mavenCentralPassword") ?: System.getenv("CENTRAL_PORTAL_PWD")
94+ // }
95+ //
96+ //
97+ // }
11798 maven {
118- name = " OSSRH"
119- url " https://oss.sonatype.org/service/local/staging/deploy/maven2"
99+ name = " MavenCentral"
100+ // FIX: don't assign to `url` when declaring the vars
101+ def releasesRepoUrl = " https://ossrh-staging-api.central.sonatype.com/service/local/staging/deploy/maven2/"
102+ def snapshotsRepoUrl = " https://central.sonatype.com/repository/maven-snapshots/"
103+
104+ url = uri(publishingInfo. versionId. endsWith(' -SNAPSHOT' ) ? snapshotsRepoUrl : releasesRepoUrl)
105+
120106 credentials {
121- username = project. findProperty(" oss.user " ) ?: System . getenv(" OSS_USERNAME " )
122- password = project. findProperty(" oss.pwd " ) ?: System . getenv(" OSS_PWD " )
107+ username = project. findProperty(" mavenCentralUsername " ) ?: System . getenv(" CENTRAL_PORTAL_USERNAME " )
108+ password = project. findProperty(" mavenCentralPassword " ) ?: System . getenv(" CENTRAL_PORTAL_PWD " )
123109 }
124110 }
125111
112+
126113 // --------------------------------------------------------------------------------
127114 // Destination Repository 'BuildDir'
128115 // telling gradle to publish artifact to local directory
129116 // -> call task 'publishMavenJavaPublicationToBuildDirRepository' to publish
130117 // --------------------------------------------------------------------------------
131118 maven {
132119 name = " BuildDir"
133- url " file:/ ${ buildDir} /artifacts"
120+ url = uri( " ${ buildDir} /artifacts" ) . toURL()
134121 }
135122 }
123+ }
136124
137125
138- publications {
139- mavenJava(MavenPublication ) {
140- groupId publishingInfo. groupId
141- artifactId publishingInfo. artifactId
142- version publishingInfo. versionId
143- from components. java
144- artifact sourcesJar
145- artifact javadocJar
146-
147- pom. withXml {
148- def root = asNode()
149- root. appendNode ' description' , publishingInfo. desc
150- root. children(). last() + pomConfig
151- }
152- }
126+ if (project. hasProperty(" signing.secretKeyRingFile" )) {
127+ signing {
128+ sign publishing. publications. mavenJava
153129 }
130+ } else {
131+ project. logger. warn(" > Signing is skipped. To activate it, provide 'signing.secretKeyRingFile', 'signing.password', and 'signing.keyId' in your gradle.properties." )
154132}
155133
134+ tasks. register(' releaseToCentralPortal' ) {
135+ group = ' publishing'
136+ description = ' Hands off the last non-SNAPSHOT upload to the Central Portal so it appears under Deployments.'
156137
157- if (
158- project . findProperty( " signing.secretKeyRingFile " )
159- && project . findProperty( " signing.password " )
160- && project . findProperty( " signing.keyId " )
161- ) {
138+ doLast {
139+ if (publishingInfo . versionId . endsWith( ' -SNAPSHOT ' )) {
140+ println " Version ' ${ publishingInfo.versionId } ' is a SNAPSHOT. Skipping Portal hand-off. "
141+ return
142+ }
162143
163- signing {
164- sign publishing. publications
165- }
144+ if (! project. hasProperty(' sonatypeNamespace' )) {
145+ throw new InvalidUserDataException (" Provide -PsonatypeNamespace=your.namespace" )
146+ }
147+ if (! project. hasProperty(' mavenCentralUsername' ) || ! project. hasProperty(' mavenCentralPassword' )) {
148+ throw new InvalidUserDataException (" Missing Central Portal token username/password." )
149+ }
166150
167- } else {
168- println " > skipping signing, provide\n " +
169- " - 'signing.secretKeyRingFile'\n " +
170- " - 'signing.password'\n " +
171- " - 'signing.keyId'\n " +
172- " to activate it\n "
151+ def sonatypeNamespace = project. property(' sonatypeNamespace' )
152+ def username = project. property(' mavenCentralUsername' )
153+ def token = project. property(' mavenCentralPassword' )
154+ def publishingType = (project. findProperty(' publishingType' ) ?: ' user_managed' ) as String
155+
156+ // Optional fallback: pass -PrepositoryKey=<key> to hand off a specific repo
157+ def repositoryKey = project. findProperty(' repositoryKey' ) as String
158+
159+ String apiUrl = repositoryKey ?
160+ " https://ossrh-staging-api.central.sonatype.com/manual/upload/repository/${ repositoryKey} ?publishing_type=${ publishingType} " :
161+ " https://ossrh-staging-api.central.sonatype.com/manual/upload/defaultRepository/${ sonatypeNamespace} ?publishing_type=${ publishingType} "
162+
163+ println " --> Handing off ${ repositoryKey ? "repositoryKey=${repositoryKey}" : "namespace=${sonatypeNamespace}"} to Central (publishing_type=${ publishingType} )..."
164+
165+ HttpURLConnection connection = (HttpURLConnection ) new URL (apiUrl). openConnection()
166+ try {
167+ def bearer = " ${ username} :${ token} " . bytes. encodeBase64(). toString()
168+ connection. setRequestProperty(' Authorization' , " Bearer ${ bearer} " ) // Bearer + base64(user:pass)
169+ connection. requestMethod = ' POST'
170+ connection. connectTimeout = 60_000
171+ connection. readTimeout = 300_000
172+
173+ def code = connection. responseCode
174+ def body = (code >= 400 ? connection. errorStream : connection. inputStream)?. getText(' UTF-8' )
175+ println " HTTP ${ code} ${ connection.responseMessage} "
176+ if (body) println " Response:\n ${ body} "
177+ if (code >= 400 ) throw new GradleException (" Portal hand-off failed with HTTP ${ code} " )
178+ } finally {
179+ connection. disconnect()
180+ }
181+
182+ println " \n Success. Check https://central.sonatype.com/publishing/deployments"
183+ }
173184}
185+
0 commit comments