Skip to content

Commit 54be566

Browse files
committed
Refactor publication to use vanniktech/maven-publish plugin
- Replaced `nexus-staging` plugin with `com.vanniktech:gradle-maven-publish-plugin`. - Updated the publication convention plugin to align with the new plugin's configuration. - Simplified secret handling by reading from `local.properties` or environment variables with sane defaults. - Updated the `build_publish.yml` workflow to use the new `publishAndReleaseToMavenCentral` task. - Added `/convention-plugins/bin/` to `.gitignore`.
1 parent cf74fab commit 54be566

File tree

8 files changed

+156
-84
lines changed

8 files changed

+156
-84
lines changed

.github/secrets/8257B447.gpg.gpg

0 Bytes
Binary file not shown.
-31 Bytes
Binary file not shown.

.github/workflows/build_publish.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,6 @@ jobs:
2727
LARGE_SECRET_PASSPHRASE: ${{ secrets.LARGE_SECRET_PASSPHRASE }}
2828
- name: Build
2929
run: ./gradlew build
30-
- name: Publish
30+
- name: Publish and Release to Maven Central
3131
continue-on-error: true
32-
run: ./gradlew publishAllPublicationsToSonatypeRepository --max-workers 1 closeAndReleaseRepository
32+
run: ./gradlew publishAndReleaseToMavenCentral --no-configuration-cache

.gitignore

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,4 +12,6 @@ build
1212
/local.properties
1313
/8257B447.gpg
1414

15-
.DS_Store
15+
.DS_Store
16+
17+
/convention-plugins/bin/

convention-plugins/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,5 +7,5 @@ repositories {
77
}
88

99
dependencies {
10-
implementation("io.codearte.gradle.nexus:gradle-nexus-staging-plugin:0.30.0")
10+
implementation("com.vanniktech:gradle-maven-publish-plugin:0.34.0")
1111
}

convention-plugins/src/main/kotlin/convention.publication.gradle.kts

Lines changed: 104 additions & 80 deletions
Original file line numberDiff line numberDiff line change
@@ -1,102 +1,126 @@
1-
import java.util.*
1+
import java.util.Properties
22

33
plugins {
4-
`maven-publish`
5-
signing
6-
id("io.codearte.nexus-staging")
4+
id("com.vanniktech.maven.publish")
75
}
86

9-
// Stub secrets to let the project sync and build without the publication values set up
10-
ext["signing.keyId"] = null
11-
ext["signing.password"] = null
12-
ext["signing.secretKeyRingFile"] = null
13-
ext["ossrhToken"] = null
14-
ext["ossrhTokenPassword"] = null
15-
ext["sonatypeStagingProfileId"] = null
16-
17-
// Grabbing secrets from local.properties file or from environment variables, which could be used on CI
7+
// Load properties from local.properties or set defaults
188
val secretPropsFile = project.rootProject.file("local.properties")
9+
val props = Properties()
10+
1911
if (secretPropsFile.exists()) {
20-
secretPropsFile.reader().use {
21-
Properties().apply {
22-
load(it)
23-
}
24-
}.onEach { (name, value) ->
25-
ext[name.toString()] = value
26-
}
27-
} else {
28-
ext["signing.keyId"] = System.getenv("SIGNING_KEY_ID")
29-
ext["signing.password"] = System.getenv("SIGNING_PASSWORD")
30-
ext["signing.secretKeyRingFile"] = System.getenv("SIGNING_SECRET_KEY_RING_FILE")
31-
ext["ossrhToken"] = System.getenv("OSSRH_TOKEN")
32-
ext["ossrhTokenPassword"] = System.getenv("OSSRH_TOKEN_PASSWORD")
33-
ext["sonatypeStagingProfileId"] = System.getenv("SONATYPE_STAGING_PROFILE_ID")
12+
secretPropsFile.reader().use(props::load)
3413
}
35-
ext["signing.secretKeyRingFile"] = "../../${ext["signing.secretKeyRingFile"]}" // path from module
14+
// Set all properties with defaults to avoid "property does not exist" errors
15+
val defaultProps = mapOf(
16+
"signing.keyId" to "",
17+
"signing.password" to "",
18+
"signing.secretKeyRingFile" to "",
19+
"ossrhUsername" to "",
20+
"ossrhPassword" to "",
21+
"mavenCentralUsername" to "",
22+
"mavenCentralPassword" to ""
23+
)
3624

37-
val javadocJar by tasks.registering(Jar::class) {
38-
archiveClassifier.set("javadoc")
25+
defaultProps.forEach { (key, defaultValue) ->
26+
val value = props.getProperty(key) ?: System.getenv(key.uppercase().replace(".", "_")) ?: defaultValue
27+
ext[key] = value
28+
project.rootProject.ext.set(key, value)
29+
// Set system properties for Maven Central and OSSRH credentials
30+
if (key in listOf("mavenCentralUsername", "mavenCentralPassword", "ossrhUsername", "ossrhPassword") && value.isNotEmpty()) {
31+
System.setProperty(key, value)
32+
}
3933
}
4034

41-
fun getExtraString(name: String) = ext[name]?.toString()
35+
fun getExtraString(name: String) = ext[name]?.toString()?.takeIf(String::isNotEmpty)
4236

43-
publishing {
44-
// Configure maven central repository
45-
repositories {
46-
maven {
47-
name = "sonatype"
48-
setUrl("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
49-
credentials {
50-
username = getExtraString("ossrhToken")
51-
password = getExtraString("ossrhTokenPassword")
37+
// Workaround for vanniktech plugin build service cleanup issue
38+
fun ensureGlobalGradleProperties() {
39+
val globalGradleDir = File(System.getProperty("user.home"), ".gradle")
40+
val globalGradleProps = File(globalGradleDir, "gradle.properties")
41+
42+
val mavenCentralUsername = getExtraString("mavenCentralUsername")
43+
val mavenCentralPassword = getExtraString("mavenCentralPassword")
44+
45+
if (mavenCentralUsername != null && mavenCentralPassword != null) {
46+
if (!globalGradleDir.exists()) {
47+
globalGradleDir.mkdirs()
48+
}
49+
val existingProps = Properties()
50+
if (globalGradleProps.exists()) {
51+
globalGradleProps.reader().use(existingProps::load)
52+
}
53+
var needsUpdate = false
54+
if (existingProps.getProperty("mavenCentralUsername") != mavenCentralUsername) {
55+
existingProps.setProperty("mavenCentralUsername", mavenCentralUsername)
56+
needsUpdate = true
57+
}
58+
if (existingProps.getProperty("mavenCentralPassword") != mavenCentralPassword) {
59+
existingProps.setProperty("mavenCentralPassword", mavenCentralPassword)
60+
needsUpdate = true
61+
}
62+
if (needsUpdate) {
63+
globalGradleProps.writer().use { writer ->
64+
existingProps.store(writer, "Updated by MaterialThemePrefs build script")
5265
}
66+
println("Updated global gradle.properties with Maven Central credentials")
5367
}
5468
}
69+
}
5570

56-
// Configure all publications
57-
publications.withType<MavenPublication> {
58-
59-
// Stub javadoc.jar artifact
60-
artifact(javadocJar.get())
71+
ensureGlobalGradleProperties() // FIXME https://github.com/vanniktech/gradle-maven-publish-plugin/issues/1116
6172

62-
// Provide artifacts information requited by Maven Central
63-
pom {
64-
name.set("Material Theme Preferences")
65-
description.set("Kotlin Multiplatform library for easy switching Dark/Light Material themes on Compose.")
66-
url.set("https://github.com/softartdev/MaterialThemePrefs")
73+
mavenPublishing {
74+
// Configure Maven Central publication
75+
publishToMavenCentral()
6776

68-
licenses {
69-
license {
70-
name.set("MIT")
71-
url.set("https://opensource.org/licenses/MIT")
72-
}
73-
}
74-
developers {
75-
developer {
76-
id.set("softartdev")
77-
name.set("Artur Babichev")
78-
email.set("[email protected]")
79-
}
77+
// Only sign publications when not publishing to Maven Local and signing credentials are available
78+
val isLocalPublication = gradle.startParameter.taskNames.any { taskName ->
79+
taskName.contains("publishToMavenLocal") || taskName.contains("ToMavenLocal")
80+
}
81+
if (!isLocalPublication) {
82+
val keyId = getExtraString("signing.keyId")
83+
val password = getExtraString("signing.password")
84+
val keyRingFile = getExtraString("signing.secretKeyRingFile")?.let(rootProject::file)
85+
86+
if (keyId != null && password != null && keyRingFile?.exists() == true) {
87+
// Set signing properties for vanniktech plugin
88+
project.ext.set("signing.keyId", keyId)
89+
project.ext.set("signing.password", password)
90+
project.ext.set("signing.secretKeyRingFile", keyRingFile.absolutePath)
91+
// Also set system properties as backup
92+
System.setProperty("signing.keyId", keyId)
93+
System.setProperty("signing.password", password)
94+
System.setProperty("signing.secretKeyRingFile", keyRingFile.absolutePath)
95+
96+
signAllPublications()
97+
}
98+
}
99+
// Configure POM metadata for all publications
100+
pom {
101+
name.set("Material Theme Preferences")
102+
description.set("Kotlin Multiplatform library for easy switching Dark/Light Material themes on Compose.")
103+
inceptionYear.set("2024")
104+
url.set("https://github.com/softartdev/MaterialThemePrefs")
105+
licenses {
106+
license {
107+
name.set("MIT")
108+
url.set("https://opensource.org/licenses/MIT")
109+
distribution.set("repo")
80110
}
81-
scm {
82-
url.set("https://github.com/softartdev/MaterialThemePrefs")
111+
}
112+
developers {
113+
developer {
114+
id.set("softartdev")
115+
name.set("Artur Babichev")
116+
email.set("[email protected]")
117+
url.set("https://github.com/softartdev")
83118
}
84-
119+
}
120+
scm {
121+
url.set("https://github.com/softartdev/MaterialThemePrefs")
122+
connection.set("scm:git:git://github.com/softartdev/MaterialThemePrefs.git")
123+
developerConnection.set("scm:git:ssh://[email protected]/softartdev/MaterialThemePrefs.git")
85124
}
86125
}
87126
}
88-
89-
signing {
90-
val isLocalPublication = gradle.startParameter.taskNames.any { taskName ->
91-
taskName.contains("publishToMavenLocal")
92-
}
93-
if (!isLocalPublication) sign(publishing.publications)
94-
}
95-
96-
nexusStaging {
97-
serverUrl = "https://s01.oss.sonatype.org/service/local/"
98-
packageGroup = project.property("GROUP").toString()
99-
stagingProfileId = getExtraString("sonatypeStagingProfileId")
100-
username = getExtraString("ossrhToken")
101-
password = getExtraString("ossrhTokenPassword")
102-
}
Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<Scheme
3+
version = "1.3">
4+
<BuildAction>
5+
<BuildActionEntries>
6+
<BuildActionEntry
7+
buildForRunning = "YES">
8+
<BuildableReference
9+
BuildableIdentifier = "primary"
10+
BlueprintIdentifier = "7555FF7A242A565900829871"
11+
BuildableName = "MaterialThemePrefs.app"
12+
BlueprintName = "iosApp"
13+
ReferencedContainer = "container:iosApp.xcodeproj">
14+
</BuildableReference>
15+
</BuildActionEntry>
16+
</BuildActionEntries>
17+
</BuildAction>
18+
<LaunchAction
19+
useCustomWorkingDirectory = "NO"
20+
buildConfiguration = "Debug"
21+
allowLocationSimulation = "YES">
22+
<BuildableProductRunnable>
23+
<BuildableReference
24+
BuildableIdentifier = "primary"
25+
BlueprintIdentifier = "7555FF7A242A565900829871"
26+
BuildableName = "MaterialThemePrefs.app"
27+
BlueprintName = "iosApp"
28+
ReferencedContainer = "container:iosApp.xcodeproj">
29+
</BuildableReference>
30+
</BuildableProductRunnable>
31+
</LaunchAction>
32+
</Scheme>
Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
3+
<plist version="1.0">
4+
<dict>
5+
<key>SchemeUserState</key>
6+
<dict>
7+
<key>iosApp.xcscheme</key>
8+
<dict>
9+
<key>orderHint</key>
10+
<integer>0</integer>
11+
</dict>
12+
</dict>
13+
</dict>
14+
</plist>

0 commit comments

Comments
 (0)