Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
59 changes: 59 additions & 0 deletions .github/scripts/configure_publishing_secrets.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env python3
import base64
import os
import re
import uuid


def decode_secret(env_var_name: str) -> str:
raw = os.environ.get(env_var_name, "")
if not raw:
return ""
# MIME Base64: ignore non-base64 chars (newlines, carriage returns, spaces, etc.)
cleaned = re.sub(r"[^A-Za-z0-9+/=]", "", raw)
if not cleaned:
return ""
return base64.b64decode(cleaned).decode("utf-8").strip()


def main():
github_env = os.environ.get("GITHUB_ENV")
if not github_env:
return

env_updates = {}

# 1. Maven Central Password
maven_central_password = decode_secret("NEXUS_PASS64")
if maven_central_password:
env_updates["ORG_GRADLE_PROJECT_mavenCentralPassword"] = maven_central_password

# 2. GPG Signing Key
gpg_key = decode_secret("GPG_KEY64")
if gpg_key:
env_updates["ORG_GRADLE_PROJECT_signingInMemoryKey"] = gpg_key
env_updates["ORG_GRADLE_PROJECT_signingInMemoryKeyId"] = "0x4272C851"

# 3. GPG Passphrase
gpg_passphrase = os.environ.get("GPG_PASSPHRASE", "")
if gpg_passphrase:
env_updates["ORG_GRADLE_PROJECT_signingInMemoryKeyPassword"] = gpg_passphrase

with open(github_env, "a", encoding="utf-8") as f:
for key, value in env_updates.items():
if "\n" in value or "\r" in value:
delimiter = f"EOF_{uuid.uuid4().hex}"
f.write(f"{key}<<{delimiter}\n{value}\n{delimiter}\n")
else:
f.write(f"{key}={value}\n")

if "ORG_GRADLE_PROJECT_mavenCentralPassword" in env_updates:
print("Configured ORG_GRADLE_PROJECT_mavenCentralPassword=***")
if "ORG_GRADLE_PROJECT_signingInMemoryKey" in env_updates:
print("Configured ORG_GRADLE_PROJECT_signingInMemoryKey=***")
if "ORG_GRADLE_PROJECT_signingInMemoryKeyPassword" in env_updates:
print("Configured ORG_GRADLE_PROJECT_signingInMemoryKeyPassword=***")


if __name__ == "__main__":
main()
15 changes: 9 additions & 6 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -189,11 +189,6 @@ jobs:
needs: final-status
if: github.event.repository.fork == false && github.ref == 'refs/heads/main'
runs-on: ubuntu-latest
env:
ORG_GRADLE_PROJECT_nexus_user: ${{ secrets.NEXUS_USER }}
ORG_GRADLE_PROJECT_nexus_pass64: ${{ secrets.NEXUS_PASS64 }}
ORG_GRADLE_PROJECT_gpg_passphrase: ${{ secrets.GPG_PASSPHRASE }}
ORG_GRADLE_PROJECT_gpg_key64: ${{ secrets.GPG_KEY64 }}
steps:
- uses: actions/checkout@v7
with:
Expand All @@ -205,4 +200,12 @@ jobs:
- uses: gradle/actions/setup-gradle@v6
with:
cache-read-only: true
- run: ./gradlew publishToMavenCentral --no-configuration-cache
- name: Configure publishing secrets
env:
NEXUS_PASS64: ${{ secrets.NEXUS_PASS64 }}
GPG_KEY64: ${{ secrets.GPG_KEY64 }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: python3 .github/scripts/configure_publishing_secrets.py
- run: ./gradlew publishToMavenCentral
env:
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.NEXUS_USER }}
11 changes: 7 additions & 4 deletions .github/workflows/deploy.yml
Original file line number Diff line number Diff line change
Expand Up @@ -32,14 +32,17 @@ jobs:
contents: write
env:
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
ORG_GRADLE_PROJECT_nexus_user: ${{ secrets.NEXUS_USER }}
ORG_GRADLE_PROJECT_nexus_pass64: ${{ secrets.NEXUS_PASS64 }}
ORG_GRADLE_PROJECT_gpg_passphrase: ${{ secrets.GPG_PASSPHRASE }}
ORG_GRADLE_PROJECT_gpg_key64: ${{ secrets.GPG_KEY64 }}
ORG_GRADLE_PROJECT_mavenCentralUsername: ${{ secrets.NEXUS_USER }}
steps:
- uses: actions/checkout@v7
with:
persist-credentials: false
- name: Configure publishing secrets
env:
NEXUS_PASS64: ${{ secrets.NEXUS_PASS64 }}
GPG_KEY64: ${{ secrets.GPG_KEY64 }}
GPG_PASSPHRASE: ${{ secrets.GPG_PASSPHRASE }}
run: python3 .github/scripts/configure_publishing_secrets.py
- name: Configure git credentials for JGit
run: |
git config --local http.https://github.com/.extraheader "AUTHORIZATION: basic $(echo -n x-access-token:${{ secrets.GITHUB_TOKEN }} | base64 -w0)"
Expand Down
12 changes: 0 additions & 12 deletions build-logic/src/main/kotlin/Ext.kt
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import com.diffplug.spotless.changelog.gradle.ChangelogExtension
import java.util.Base64
import org.gradle.accessors.dm.LibrariesForLibs
import org.gradle.api.Project
import org.gradle.kotlin.dsl.findByType
Expand All @@ -18,17 +17,6 @@ fun Project.requiredProperty(name: String): String =
findProperty(name)?.toString()
?: error("$path is missing the '$name' property, which is required")

// getMimeDecoder, not getDecoder: the basic decoder rejects the newlines that `base64`/`openssl
// base64` leave in a wrapped secret, whereas Groovy's String.decodeBase64 (used before the Kotlin
// DSL migration) skipped whitespace.
fun decode64(varName: String): String {
val envValue = System.getenv(varName) ?: return ""
return String(Base64.getMimeDecoder().decode(envValue), Charsets.UTF_8)
}

// Groovy's String.toBoolean() -- what this used before the Kotlin DSL migration -- accepts "true",
// "y" and "1", ignoring case. Kotlin's toBoolean() only accepts "true", so the short forms would
// silently become no-ops.
fun String.toBooleanGroovy(): Boolean = trim().lowercase() in setOf("true", "y", "1")

val isCiServer: Boolean
Expand Down
15 changes: 0 additions & 15 deletions build-logic/src/main/kotlin/spotless.java-publish.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
plugins {
`java-library`
id("com.vanniktech.maven.publish")
signing
}

tasks.withType<Javadoc>().configureEach {
Expand Down Expand Up @@ -34,20 +33,6 @@ tasks.withType<Javadoc>().configureEach {
}
}

signing {
if (
!project.providers.gradleProperty("signingInMemoryKey").isPresent &&
System.getenv("ORG_GRADLE_PROJECT_gpg_key64") != null
) {
val gpgKey = decode64("ORG_GRADLE_PROJECT_gpg_key64")
useInMemoryPgpKeys(
"0x4272C851",
gpgKey,
System.getenv("ORG_GRADLE_PROJECT_gpg_passphrase"),
)
}
}

// find the project with the changelog (this project for plugins, root project for libs)
val changelogProject = if (pluginManager.hasPlugin("spotless.changelog")) project else rootProject
val changelogTasks = changelogProject.tasks
Expand Down
31 changes: 24 additions & 7 deletions plugin-gradle/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,3 +1,7 @@
import org.gradle.api.plugins.JavaPlugin.API_ELEMENTS_CONFIGURATION_NAME
import org.gradle.api.plugins.JavaPlugin.JAVADOC_ELEMENTS_CONFIGURATION_NAME
import org.gradle.api.plugins.JavaPlugin.RUNTIME_ELEMENTS_CONFIGURATION_NAME
import org.gradle.api.plugins.JavaPlugin.SOURCES_ELEMENTS_CONFIGURATION_NAME
import org.gradle.plugin.compatibility.compatibility

plugins {
Expand All @@ -15,6 +19,26 @@ plugins {

version = spotlessChangelog.versionNext

val publishedElements =
listOf(
API_ELEMENTS_CONFIGURATION_NAME,
RUNTIME_ELEMENTS_CONFIGURATION_NAME,
JAVADOC_ELEMENTS_CONFIGURATION_NAME,
SOURCES_ELEMENTS_CONFIGURATION_NAME,
)

configurations.configureEach {
when (name) {
in publishedElements ->
outgoing {
// Main/current capability.
capability("com.diffplug.spotless:spotless-plugin-gradle:$version")
// Historical capabilities.
capability("com.diffplug.gradle.spotless:spotless-plugin-gradle:$version")
}
}
}

dependencies {
if (
version.toString().endsWith("-SNAPSHOT") ||
Expand Down Expand Up @@ -79,13 +103,6 @@ gradlePlugin {
)
compatibility { features { configurationCache = true } }
}
create("spotlessPluginLegacy") {
id = "com.diffplug.gradle.spotless"
implementationClass = "com.diffplug.gradle.spotless.SpotlessPluginRedirect"
displayName = "Spotless formatting plugin (legacy)"
description = project.description
tags = listOf("format")
}
Comment on lines -82 to -88

@Goooler Goooler Sep 17, 2026 •

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I recalled there is no need for publishing the legacy plugin, just declare it as the history item in b667bcb. Copied from https://github.com/GradleUp/shadow/blob/35b7a3db0f0d9fa795c8e34557a8dd23e0edf2ac/build.gradle.kts#L93-L108

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

excellent!

}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
implementation-class=com.diffplug.gradle.spotless.SpotlessPluginRedirect
25 changes: 0 additions & 25 deletions settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,5 +1,3 @@
import kotlin.io.encoding.Base64

pluginManagement {
includeBuild("build-logic")
repositories {
Expand Down Expand Up @@ -92,26 +90,3 @@ val excludeMaven =
if (!excludeMaven) {
include("plugin-maven") // maven-specific glue code
}

fun decode64(varName: String): String {
val envValue = System.getenv(varName) ?: return ""
return String(Base64.Mime.decode(envValue), Charsets.UTF_8)
}

val projectProperties = startParameter.projectProperties.toMutableMap()

if (!projectProperties.containsKey("mavenCentralUsername")) {
System.getenv("ORG_GRADLE_PROJECT_nexus_user")?.let {
projectProperties["mavenCentralUsername"] = it
}
}

if (!projectProperties.containsKey("mavenCentralPassword")) {
decode64("ORG_GRADLE_PROJECT_nexus_pass64")
.takeIf { it.isNotEmpty() }
?.let {
projectProperties["mavenCentralPassword"] = it
}
}

startParameter.setProjectProperties(projectProperties)
Loading