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
47 changes: 26 additions & 21 deletions .github/workflows/gradle-publish-release.yml
Original file line number Diff line number Diff line change
@@ -1,42 +1,47 @@
# This workflow uses actions that are not certified by GitHub.
# They are provided by a third-party and are governed by
# separate terms of service, privacy policy, and support
# documentation.
# This workflow will build a package using Gradle and then publish it to GitHub packages when a release is created
# For more information see: https://github.com/actions/setup-java/blob/main/docs/advanced-usage.md#Publishing-using-gradle
# This workflow publishes to Maven Central using JReleaser when a GitHub release is created
# For more information see: https://jreleaser.org/guide/latest/examples/maven/maven-central.html

name: Publish Release
name: Publish Release with JReleaser

on:
release:
types: [ released ]


jobs:
build:
publish:
runs-on: ubuntu-latest
permissions:
contents: read
contents: write # Needed for JReleaser to update the release

steps:

- uses: actions/checkout@v4
- name: Set up JDK 18
with:
fetch-depth: 0 # Required for JReleaser git operations

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '18'
distribution: 'temurin'

- name: Define library version env var at run-time - RELEASE
- name: Stage artifacts to local directory
env:
LIBRARY_VERSION: ${{ github.event.release.tag_name }}
run: |
echo 'ORG_GRADLE_PROJECT_LIBRARY_VERSION=${{ github.event.release.tag_name }}' >> $GITHUB_ENV
./gradlew :DittoToolsAndroid:publishReleasePublicationToLocalStagingRepository -PLIBRARY_VERSION=${{ github.event.release.tag_name }}

- name: Publish to Maven Central
- name: Publish to Maven Central via JReleaser
env:
ORG_GRADLE_PROJECT_MAVEN_CENTRAL_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_MAVEN_CENTRAL_USERNAME }}
ORG_GRADLE_PROJECT_MAVEN_CENTRAL_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_MAVEN_CENTRAL_PASSWORD }}
ORG_GRADLE_PROJECT_GPG_SIGNING_IN_MEMORY_KEY: ${{ secrets.ORG_GRADLE_PROJECT_GPG_SIGNING_IN_MEMORY_KEY }}
ORG_GRADLE_PROJECT_GPG_SIGNING_IN_MEMORY_KEY_PWD: ${{ secrets.ORG_GRADLE_PROJECT_GPG_SIGNING_IN_MEMORY_KEY_PWD }}
ORG_GRADLE_PROJECT_PUBLISH_TO_MAVEN_CENTRAL: "TRUE"
# Library version from release tag
LIBRARY_VERSION: ${{ github.event.release.tag_name }}
# GitHub token for JReleaser (provided by GitHub Actions)
JRELEASER_GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
# Map existing Maven Central secrets to JReleaser variables
JRELEASER_MAVENCENTRAL_USERNAME: ${{ secrets.ORG_GRADLE_PROJECT_MAVEN_CENTRAL_USERNAME }}
JRELEASER_MAVENCENTRAL_PASSWORD: ${{ secrets.ORG_GRADLE_PROJECT_MAVEN_CENTRAL_PASSWORD }}
# Map existing GPG secrets to JReleaser variables
JRELEASER_GPG_PUBLIC_KEY: ${{ secrets.ORG_GRADLE_PROJECT_GPG_PUBLIC_KEY }}
JRELEASER_GPG_SECRET_KEY: ${{ secrets.ORG_GRADLE_PROJECT_GPG_SIGNING_IN_MEMORY_KEY }}
JRELEASER_GPG_PASSPHRASE: ${{ secrets.ORG_GRADLE_PROJECT_GPG_SIGNING_IN_MEMORY_KEY_PWD }}
run: |
./gradlew publish
./gradlew :DittoToolsAndroid:jreleaserFullRelease -PLIBRARY_VERSION=${{ github.event.release.tag_name }}
1 change: 1 addition & 0 deletions DittoToolsAndroid/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ plugins {
alias(libs.plugins.com.android.library)
alias(libs.plugins.org.jetbrains.kotlin.android)
alias(libs.plugins.compose.compiler)
alias(libs.plugins.jreleaser)
}

val libraryArtifactId by extra("ditto-tools-android")
Expand Down
1 change: 1 addition & 0 deletions build.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ plugins {
alias libs.plugins.com.android.library apply false
alias libs.plugins.org.jetbrains.kotlin.android apply false
alias(libs.plugins.compose.compiler) apply false
alias(libs.plugins.jreleaser) apply false
}

version = findProperty("LIBRARY_VERSION")
Expand Down
95 changes: 87 additions & 8 deletions gradle/deploy.gradle
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,6 @@ android {

afterEvaluate {
publishing {

publications {
release(MavenPublication) {
from components.release
Expand All @@ -40,6 +39,13 @@ afterEvaluate {

version = findProperty("LIBRARY_VERSION") ?: "SNAPSHOT"

// Include resolved versions in POM for BOM-managed dependencies
versionMapping {
allVariants {
fromResolutionResult()
}
}

pom {
name = 'Ditto Tools'
description = 'Ditto Tools'
Expand All @@ -66,20 +72,93 @@ afterEvaluate {
email = 'support@ditto.live'
}
}

// Maven Central requires all dependencies to have explicit versions in the POM.
// Android projects using Compose BOM get versions via dependencyManagement, but
// Maven Central's validation rejects this. This block post-processes the generated
// POM to: 1) Remove the dependencyManagement section, 2) Resolve actual versions
// from the build's runtime classpath, 3) Add explicit version tags to all dependencies.

withXml {
def dependenciesNode = asNode().dependencies[0]
def dependencyManagementNode = asNode().dependencyManagement

// Remove dependencyManagement section
if (dependencyManagementNode) {
asNode().remove(dependencyManagementNode[0])
}

// Add versions to dependencies that don't have them
if (dependenciesNode) {
dependenciesNode.dependency.each { dep ->
if (!dep.version) {
def groupId = dep.groupId.text()
def artifactId = dep.artifactId.text()

// Try to find in runtime classpath
def resolved = project.configurations.releaseRuntimeClasspath.resolvedConfiguration.resolvedArtifacts.find {
it.moduleVersion.id.group == groupId && it.moduleVersion.id.name == artifactId
}

if (resolved) {
dep.appendNode('version', resolved.moduleVersion.id.version)
} else {
// If not found, try getting from incoming resolution result
project.configurations.releaseRuntimeClasspath.incoming.resolutionResult.allComponents.each { component ->
if (component.moduleVersion.group == groupId && component.moduleVersion.name == artifactId) {
dep.appendNode('version', component.moduleVersion.version)
}
}
}
}
}
}
}
}
}
}
repositories {
maven {
credentials {
username = findProperty("MAVEN_CENTRAL_USERNAME")
password = findProperty("MAVEN_CENTRAL_PASSWORD")
}
name = 'localStaging'
url = uri("${project.buildDir}/staging-deploy")
}
}
}

def releasesRepoUrl = uri("https://s01.oss.sonatype.org/service/local/staging/deploy/maven2/")
def snapshotsRepoUrl = uri("https://s01.oss.sonatype.org/content/repositories/snapshots/")
jreleaser {
gitRootSearch = true

url = version.endsWith('SNAPSHOT') ? snapshotsRepoUrl : releasesRepoUrl
project {
name = 'Ditto Tools'
description = 'Ditto Tools for Android'
website = 'https://ditto.com'
authors = ['Ditto']
license = 'MIT'
version = findProperty("LIBRARY_VERSION") ?: "1.0.0-SNAPSHOT"
}

release {
github {
skipRelease = true
}
}

signing {
// Enable signing when GPG keys are available (e.g., in CI/CD)
active = System.getenv('JRELEASER_GPG_SECRET_KEY') ? 'ALWAYS' : 'NEVER'
armored = true
}

deploy {
maven {
mavenCentral {
sonatype {
active = 'ALWAYS'
url = 'https://central.sonatype.com/api/v1/publisher'
stagingRepository('build/staging-deploy')
verifyPom = false // Disable strict POM validation for Android libraries
}
}
}
}
}
Expand Down
4 changes: 3 additions & 1 deletion gradle/libs.versions.toml
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ gradle-nexus-publish-plugin = "2.0.0"
runtimeAndroid = "1.7.6"
webkit = "1.12.1"
kotlin = "2.1.0"
jreleaser = "1.20.0"

[libraries]
androidx-appcompat-appcompat = { group = "androidx.appcompat", name = "appcompat", version.ref = "androidx-appcompat" }
Expand Down Expand Up @@ -57,4 +58,5 @@ com-android-application = { id = "com.android.application", version.ref = "andro
com-android-library = { id = "com.android.library", version.ref = "android-gradle-plugin" }
org-jetbrains-kotlin-android = { id = "org.jetbrains.kotlin.android", version.ref = "kotlin-gradle-plugin" }
io-github-gradle-nexus-publish-plugin = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "gradle-nexus-publish-plugin"}
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
compose-compiler = { id = "org.jetbrains.kotlin.plugin.compose", version.ref = "kotlin" }
jreleaser = { id = "org.jreleaser", version.ref = "jreleaser"}