Skip to content

Commit 4d66a1f

Browse files
committed
Update release scripts.
1 parent 99fc35a commit 4d66a1f

File tree

5 files changed

+88
-10
lines changed

5 files changed

+88
-10
lines changed

.github/workflows/deploy-snapshot.yml

Lines changed: 0 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -33,9 +33,3 @@ jobs:
3333

3434
- name: Build
3535
run: ./gradlew build
36-
37-
- name: Publish package
38-
run: ./gradlew publishAllPublicationsToSonatypeSnapshotRepository
39-
env:
40-
SONATYPE_USER: ${{ secrets.SONATYPE_USER }}
41-
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}

.github/workflows/publish-maven-central.yml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -19,10 +19,10 @@ jobs:
1919
- name: Build
2020
run: ./gradlew build
2121

22-
- name: Publish package
23-
run: ./gradlew publishAllPublicationsToMavenCentralRepository
22+
- name: Upload to Sonatype Central
23+
run: ./gradlew uploadToSonatypeCentral
2424
env:
25-
SONATYPE_USER: ${{ secrets.SONATYPE_USER }}
26-
SONATYPE_PASSWORD: ${{ secrets.SONATYPE_PASSWORD }}
25+
SONATYPE_USER: ${{ secrets.CENTRAL_SONATYPE_USERNAME }}
26+
SONATYPE_PASSWORD: ${{ secrets.CENTRAL_SONATYPE_PASSWORD }}
2727
DEXMAKER_GPG_PRIVATE_KEY: ${{ secrets.DEXMAKER_GPG_PRIVATE_KEY }}
2828
DEXMAKER_GPG_PRIVATE_KEY_PASSWORD: ${{ secrets.DEXMAKER_GPG_PRIVATE_KEY_PASSWORD }}

gradle/publishing.gradle

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,17 @@
11
apply plugin: 'maven-publish'
22
apply plugin: 'signing'
3+
apply from: "$rootDir/gradle/sonatype-central.gradle"
34

45
java {
56
withSourcesJar()
67
withJavadocJar()
78
}
89

10+
// Task to publish to local repository for bundle creation
11+
tasks.register("publishToLocalMaven", Task) {
12+
dependsOn "publishMavenPublicationToLocalRepository"
13+
}
14+
915
publishing {
1016
publications {
1117
maven(MavenPublication) {

gradle/publishing_aar.gradle

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
apply plugin: 'maven-publish'
22
apply plugin: 'signing'
3+
apply from: "$rootDir/gradle/sonatype-central.gradle"
34

45
android {
56
// Explicitly set the NDK release to ensure we use the latest stable, as
@@ -20,6 +21,12 @@ android {
2021
}
2122
}
2223

24+
// Task to publish to local repository for bundle creation
25+
tasks.register("publishToLocalMaven", Task) {
26+
dependsOn "publishMavenPublicationToLocalRepository"
27+
}
28+
29+
2330
// AGP creates the components in afterEvaluate, so we need to use it too
2431
// https://developer.android.com/studio/build/maven-publish-plugin
2532
afterEvaluate {

gradle/sonatype-central.gradle

Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
// Common Sonatype Central publishing functionality
2+
// This script can be applied by both publishing.gradle and publishing_aar.gradle
3+
4+
// Custom task to upload deployment bundle to Sonatype Central API
5+
tasks.register("uploadToSonatypeCentral") {
6+
dependsOn publishToLocalMaven
7+
doLast {
8+
def sonatypeUsername = System.getenv("SONATYPE_USER")
9+
def sonatypePassword = System.getenv("SONATYPE_PASSWORD")
10+
11+
if (!sonatypeUsername || !sonatypePassword) {
12+
throw new GradleException("SONATYPE_USER and SONATYPE_PASSWORD environment variables must be set")
13+
}
14+
15+
// Create deployment bundle (zip file containing all artifacts)
16+
def bundleFile = new File(project.buildDir, "distributions/deployment-bundle.zip")
17+
bundleFile.parentFile.mkdirs()
18+
19+
ant.zip(destfile: bundleFile) {
20+
fileset(dir: "${project.buildDir}/repo") {
21+
include(name: "**/*")
22+
}
23+
}
24+
25+
// Create base64 encoded credentials
26+
def credentials = "${sonatypeUsername}:${sonatypePassword}"
27+
def encodedCredentials = Base64.getEncoder().encodeToString(credentials.getBytes())
28+
29+
// Upload bundle to Sonatype Central API
30+
def connection = new URL("https://central.sonatype.com/api/v1/publisher/upload").openConnection()
31+
connection.setRequestMethod("POST")
32+
connection.setRequestProperty("Authorization", "Bearer ${encodedCredentials}")
33+
connection.setRequestProperty("Content-Type", "multipart/form-data")
34+
connection.setDoOutput(true)
35+
36+
// Set up multipart form data
37+
def boundary = "----WebKitFormBoundary" + System.currentTimeMillis()
38+
connection.setRequestProperty("Content-Type", "multipart/form-data; boundary=" + boundary)
39+
40+
def outputStream = connection.getOutputStream()
41+
def writer = new PrintWriter(new OutputStreamWriter(outputStream, "UTF-8"), true)
42+
43+
// Add file part
44+
writer.append("--" + boundary).append("\r\n")
45+
writer.append("Content-Disposition: form-data; name=\"bundle\"; filename=\"" + bundleFile.name + "\"").append("\r\n")
46+
writer.append("Content-Type: application/zip").append("\r\n")
47+
writer.append("\r\n")
48+
writer.flush()
49+
50+
// Write file content
51+
bundleFile.withInputStream { inputStream ->
52+
outputStream << inputStream
53+
}
54+
outputStream.flush()
55+
56+
writer.append("\r\n")
57+
writer.append("--" + boundary + "--").append("\r\n")
58+
writer.close()
59+
60+
// Get response
61+
def responseCode = connection.getResponseCode()
62+
if (responseCode == 200 || responseCode == 201) {
63+
println "Bundle uploaded successfully to Sonatype Central"
64+
def response = connection.getInputStream().getText()
65+
println "Response: ${response}"
66+
} else {
67+
def errorResponse = connection.getErrorStream()?.getText() ?: "No error details available"
68+
throw new GradleException("Failed to upload bundle. Response code: ${responseCode}, Error: ${errorResponse}")
69+
}
70+
}
71+
}

0 commit comments

Comments
 (0)