@@ -53,16 +53,6 @@ publishing {
5353 }
5454 }
5555 }
56- repositories {
57- maven {
58- name = " central"
59- url = uri(" https://central.sonatype.com/api/v1/publisher/upload" )
60- credentials {
61- username = System . getenv(" SONATYPE_USERNAME" )
62- password = System . getenv(" SONATYPE_PASSWORD" )
63- }
64- }
65- }
6656}
6757
6858signing {
@@ -80,3 +70,71 @@ javadoc {
8070test {
8171 useJUnitPlatform()
8272}
73+
74+ tasks. register(' uploadToCentral' ) {
75+ dependsOn ' signMavenJavaPublication'
76+
77+ doLast {
78+ def v = project. version
79+ def a = publishing. publications. mavenJava. artifactId
80+ def bd = layout. buildDirectory. get(). asFile
81+
82+ def entries = []
83+ // build/libs/ — files already have correct Maven names
84+ entries << [file : new File (bd, " libs/${ a} -${ v} .jar" ), name : " ${ a} -${ v} .jar" ]
85+ entries << [file : new File (bd, " libs/${ a} -${ v} .jar.asc" ), name : " ${ a} -${ v} .jar.asc" ]
86+ entries << [file : new File (bd, " libs/${ a} -${ v} -sources.jar" ), name : " ${ a} -${ v} -sources.jar" ]
87+ entries << [file : new File (bd, " libs/${ a} -${ v} -sources.jar.asc" ), name : " ${ a} -${ v} -sources.jar.asc" ]
88+ entries << [file : new File (bd, " libs/${ a} -${ v} -javadoc.jar" ), name : " ${ a} -${ v} -javadoc.jar" ]
89+ entries << [file : new File (bd, " libs/${ a} -${ v} -javadoc.jar.asc" ), name : " ${ a} -${ v} -javadoc.jar.asc" ]
90+ // build/publications/ — files have Gradle internal names, rename to Maven names
91+ entries << [file : new File (bd, " publications/mavenJava/pom-default.xml" ), name : " ${ a} -${ v} .pom" ]
92+ entries << [file : new File (bd, " publications/mavenJava/pom-default.xml.asc" ), name : " ${ a} -${ v} .pom.asc" ]
93+ entries << [file : new File (bd, " publications/mavenJava/module.json" ), name : " ${ a} -${ v} .module" ]
94+ entries << [file : new File (bd, " publications/mavenJava/module.json.asc" ), name : " ${ a} -${ v} .module.asc" ]
95+
96+ def boundary = UUID . randomUUID(). toString()
97+ def baos = new ByteArrayOutputStream ()
98+ def nl = " \r\n "
99+ def missing = []
100+
101+ entries. each { e ->
102+ if (! e. file. exists()) {
103+ missing << e. file. path
104+ return
105+ }
106+ baos. write(" --$boundary ${ nl} " . bytes)
107+ baos. write(" Content-Disposition: form-data; name=\" file\" ; filename=\" ${ e.name} \" ${ nl} " . bytes)
108+ baos. write(" Content-Type: application/octet-stream${ nl}${ nl} " . bytes)
109+ baos. write(e. file. bytes)
110+ baos. write(nl. bytes)
111+ }
112+ baos. write(" --${ boundary} --${ nl} " . bytes)
113+
114+ if (missing. size() == entries. size()) {
115+ throw new GradleException (" No artifacts found to upload. Missing: ${ missing[0]} " )
116+ }
117+
118+ def url = URI . create(" https://central.sonatype.com/api/v1/publisher/upload" )
119+ def user = System . getenv(" SONATYPE_USERNAME" )
120+ def pass = System . getenv(" SONATYPE_PASSWORD" )
121+
122+ if (! user || ! pass) throw new GradleException (" SONATYPE_USERNAME/PASSWORD not set" )
123+
124+ def auth = Base64 . getEncoder(). encodeToString(" $user :$pass " . bytes)
125+ def client = java.net.http.HttpClient . newHttpClient()
126+ def request = java.net.http.HttpRequest . newBuilder()
127+ .uri(url)
128+ .header(" Content-Type" , " multipart/form-data; boundary=$boundary " )
129+ .header(" Authorization" , " Basic $auth " )
130+ .POST (java.net.http.HttpRequest.BodyPublishers . ofByteArray(baos. toByteArray()))
131+ .build()
132+
133+ def response = client. send(request, java.net.http.HttpResponse.BodyHandlers . ofString())
134+ if (response. statusCode() in [200 , 201 , 202 , 204 ]) {
135+ println " Upload successful: HTTP ${ response.statusCode()} "
136+ } else {
137+ throw new GradleException (" Upload failed: HTTP ${ response.statusCode()} - ${ response.body()} " )
138+ }
139+ }
140+ }
0 commit comments