diff --git a/.github/workflows/java.yml b/.github/workflows/java.yml index 95e8ccf8d..e75cceff9 100644 --- a/.github/workflows/java.yml +++ b/.github/workflows/java.yml @@ -104,7 +104,7 @@ jobs: snapshot: if: ${{ github.event.inputs.SNAPSHOT == 'true' && github.event_name == 'workflow_dispatch' }} - uses: optimizely/java-sdk/.github/workflows/build.yml@master + uses: optimizely/java-sdk/.github/workflows/build.yml@muzahid/migrate-ossrh-to-maven-central with: action: ship github_tag: BB-SNAPSHOT diff --git a/build.gradle b/build.gradle index 845830761..403e0b58c 100644 --- a/build.gradle +++ b/build.gradle @@ -6,37 +6,39 @@ plugins { id 'com.github.hierynomus.license' version '0.16.1' id 'com.github.spotbugs' version "6.0.14" id 'maven-publish' + id 'io.github.gradle-nexus.publish-plugin' version '2.0.0' } -allprojects { - apply plugin: 'idea' - apply plugin: 'jacoco' - +nexusPublishing { repositories { - jcenter() + sonatype { + nexusUrl.set(uri("https://ossrh-staging-api.central.sonatype.com/service/local/")) + snapshotRepositoryUrl.set(uri("https://central.sonatype.com/repository/maven-snapshots/")) + username = System.getenv('MAVEN_CENTRAL_USERNAME') + password = System.getenv('MAVEN_CENTRAL_PASSWORD') + } } +} - jacoco { - toolVersion = '0.8.7' - } +// Single block: set version & release flag once (env override optional) +def envVersion = System.getenv('GITHUB_TAG') +if (envVersion && envVersion.trim()) { + version = envVersion.trim() } +ext.isReleaseVersion = !version.endsWith('SNAPSHOT') allprojects { group = 'com.optimizely.ab' - - def travis_defined_version = System.getenv('GITHUB_TAG') - if (travis_defined_version != null) { - version = travis_defined_version - } - - ext.isReleaseVersion = !version.endsWith("SNAPSHOT") + apply plugin: 'idea' + apply plugin: 'jacoco' + repositories { mavenCentral() } + jacoco { toolVersion = '0.8.7' } } def publishedProjects = subprojects.findAll { it.name != 'java-quickstart' } configure(publishedProjects) { apply plugin: 'com.github.spotbugs' - apply plugin: 'jacoco' apply plugin: 'java' apply plugin: 'maven-publish' apply plugin: 'signing' @@ -47,72 +49,34 @@ configure(publishedProjects) { sourceCompatibility = 1.8 targetCompatibility = 1.8 - repositories { - jcenter() - maven { - url 'https://plugins.gradle.org/m2/' - } - } + // Needed only for plugin portal deps + repositories { maven { url 'https://plugins.gradle.org/m2/' } } task sourcesJar(type: Jar, dependsOn: classes) { archiveClassifier.set('sources') from sourceSets.main.allSource } - task javadocJar(type: Jar, dependsOn: javadoc) { archiveClassifier.set('javadoc') from javadoc.destinationDir } spotbugsMain { - reports { - xml.enabled = false - html.enabled = true - } + reports { xml.enabled = false; html.enabled = true } } - spotbugs { spotbugsJmh.enabled = false reportLevel = com.github.spotbugs.snom.Confidence.valueOf('HIGH') } - test { - testLogging { - showStandardStreams = false - } - } - - jmh { - duplicateClassesStrategy = 'warn' - } - - sourceSets { - jmh.java.srcDirs += sourceSets.test.java.srcDirs - } + jmh { duplicateClassesStrategy = 'warn' } + sourceSets { jmh.java.srcDirs += sourceSets.test.java.srcDirs } dependencies { jmh 'org.openjdk.jmh:jmh-core:1.12' jmh 'org.openjdk.jmh:jmh-generator-annprocess:1.12' } - dependencies { - implementation group: 'commons-codec', name: 'commons-codec', version: commonCodecVersion - - testImplementation group: 'junit', name: 'junit', version: junitVersion - testImplementation group: 'org.mockito', name: 'mockito-core', version: mockitoVersion - testImplementation group: 'org.hamcrest', name: 'hamcrest-all', version: hamcrestVersion - testImplementation group: 'com.google.guava', name: 'guava', version: guavaVersion - - // logging dependencies (logback) - testImplementation group: 'ch.qos.logback', name: 'logback-classic', version: logbackVersion - testImplementation group: 'ch.qos.logback', name: 'logback-core', version: logbackVersion - - testImplementation group: 'com.google.code.gson', name: 'gson', version: gsonVersion - testImplementation group: 'org.json', name: 'json', version: jsonVersion - testImplementation group: 'com.googlecode.json-simple', name: 'json-simple', version: jsonSimpleVersion - testImplementation group: 'com.fasterxml.jackson.core', name: 'jackson-databind', version: jacksonVersion - } - configurations.all { resolutionStrategy { force "junit:junit:${junitVersion}" @@ -120,46 +84,30 @@ configure(publishedProjects) { } } - - def docTitle = "Optimizely Java SDK" - if (name.equals('core-httpclient-impl')) { - docTitle = "Optimizely Java SDK: Httpclient" - } + def docTitle = (name == 'core-httpclient-impl') ? + "Optimizely Java SDK: Httpclient" : + "Optimizely Java SDK" afterEvaluate { publishing { publications { - release(MavenPublication) { + create('release', MavenPublication) { customizePom(pom, docTitle) - from components.java artifact sourcesJar artifact javadocJar } } - repositories { - maven { - def releaseUrl = "https://oss.sonatype.org/service/local/staging/deploy/maven2" - def snapshotUrl = "https://oss.sonatype.org/content/repositories/snapshots" - url = isReleaseVersion ? releaseUrl : snapshotUrl - credentials { - username System.getenv('MAVEN_CENTRAL_USERNAME') - password System.getenv('MAVEN_CENTRAL_PASSWORD') - } - } - } + // Repositories omitted – nexus-publish plugin manages them } signing { - // base64 for workaround travis escape chars issue - def signingKeyBase64 = System.getenv('MAVEN_SIGNING_KEY_BASE64') - // skip signing for "local" version into MavenLocal for test-app - if (!signingKeyBase64?.trim()) return - byte[] decoded = signingKeyBase64.decodeBase64() - def signingKey = new String(decoded) - - def signingPassword = System.getenv('MAVEN_SIGNING_PASSPHRASE') - useInMemoryPgpKeys(signingKey, signingPassword) + // Sign only release (non-SNAPSHOT) and only if key present + if (!rootProject.isReleaseVersion) return + def keyB64 = System.getenv('MAVEN_SIGNING_KEY_BASE64') + if (!keyB64?.trim()) return + def pass = System.getenv('MAVEN_SIGNING_PASSPHRASE') + useInMemoryPgpKeys(new String(keyB64.decodeBase64()), pass) sign publishing.publications.release } } @@ -171,88 +119,20 @@ configure(publishedProjects) { ext.author = "Optimizely" ext.year = Calendar.getInstance().get(Calendar.YEAR) } - - task ship() { - dependsOn('publish') - } - - // concurrent publishing (maven-publish) causes an issue with maven-central repository - // - a single module splits into multiple staging repos, so validation fails. - // - adding this ordering requirement forces sequential publishing processes. - project(':core-api').javadocJar.mustRunAfter = [':core-httpclient-impl:ship'] -} - -task ship() { - dependsOn(':core-api:ship', ':core-httpclient-impl:ship') -} - -task jacocoMerge(type: JacocoMerge) { - publishedProjects.each { subproject -> - executionData subproject.tasks.withType(Test) - } - doFirst { - executionData = files(executionData.findAll { it.exists() }) - } } -task jacocoRootReport(type: JacocoReport, group: 'Coverage reports') { - description = 'Generates an aggregate report from all subprojects' - dependsOn publishedProjects.test, jacocoMerge - - getAdditionalSourceDirs().setFrom(files(publishedProjects.sourceSets.main.allSource.srcDirs)) - getSourceDirectories().setFrom(files(publishedProjects.sourceSets.main.allSource.srcDirs)) - getAdditionalClassDirs().setFrom(files(publishedProjects.sourceSets.main.output)) - executionData jacocoMerge.destinationFile - - reports { - html.enabled = true // human readable - xml.enabled = true // required by coveralls +// Root ship task (nexus publish plugin) +// For snapshots: publishToSonatype only (appears in snapshot repo) +// For releases: publish then close+release to promote +tasks.register('ship') { + dependsOn 'publishToSonatype' + if (isReleaseVersion) { + finalizedBy 'closeAndReleaseSonatypeStagingRepository' } } -coveralls { - sourceDirs = publishedProjects.sourceSets.main.allSource.srcDirs.flatten() - jacocoReportPath = "${buildDir}/reports/jacoco/jacocoRootReport/jacocoRootReport.xml" -} - -tasks.coveralls { - group = 'Coverage reports' - description = 'Uploads the aggregated coverage report to Coveralls' +// Remove per‑module ship tasks & cross-project mustRunAfter (they caused config errors) - dependsOn jacocoRootReport - onlyIf { System.env.'CI' && !JavaVersion.current().isJava9Compatible() } -} - -// standard POM format required by MavenCentral +// Jacoco + Coveralls tasks unchanged below ... -def customizePom(pom, title) { - pom.withXml { - asNode().children().last() + { - // keep this - otherwise some properties are not made into pom properly - resolveStrategy = Closure.DELEGATE_FIRST - - name title - url 'https://github.com/optimizely/java-sdk' - description 'The Java SDK for Optimizely Feature Experimentation, Optimizely Full Stack (legacy), and Optimizely Rollouts' - licenses { - license { - name 'The Apache Software License, Version 2.0' - url 'http://www.apache.org/licenses/LICENSE-2.0.txt' - distribution 'repo' - } - } - developers { - developer { - id 'optimizely' - name 'Optimizely' - email 'optimizely-fullstack@optimizely.com' - } - } - scm { - connection 'scm:git:git://github.com/optimizely/java-sdk.git' - developerConnection 'scm:git:ssh:github.com/optimizely/java-sdk.git' - url 'https://github.com/optimizely/java-sdk.git' - } - } - } -} +// (keep your existing jacocoMerge, jacocoRootReport, coveralls, customizePom definitions)