44 */
55package aws.sdk.kotlin.gradle.dsl
66
7+ import aws.sdk.kotlin.gradle.util.getOrNull
78import aws.sdk.kotlin.gradle.util.verifyRootProject
89import io.github.gradlenexus.publishplugin.NexusPublishExtension
910import org.gradle.api.Project
@@ -36,6 +37,7 @@ private object EnvironmentVariables {
3637 const val GPG_PASSPHRASE = " JRELEASER_GPG_PASSPHRASE"
3738 const val GPG_PUBLIC_KEY = " JRELEASER_GPG_PUBLIC_KEY"
3839 const val GPG_SECRET_KEY = " JRELEASER_GPG_SECRET_KEY"
40+ const val GENERIC_TOKEN = " JRELEASER_GENERIC_TOKEN"
3941}
4042
4143internal val ALLOWED_PUBLICATION_NAMES = setOf (
@@ -56,22 +58,27 @@ internal val ALLOWED_PUBLICATION_NAMES = setOf(
5658 " dynamodb-mapper-schema-generatorPluginMarkerMaven" ,
5759)
5860
59- internal val KOTLIN_NATIVE_PUBLICATION_NAMES = setOf (
61+ internal val ALLOWED_KOTLIN_NATIVE_PUBLICATION_NAMES = setOf (
6062 " iosArm64" ,
63+ " iosSimulatorArm64" ,
6164 " iosX64" ,
65+
6266 " linuxArm64" ,
6367 " linuxX64" ,
6468 " macosArm64" ,
6569 " macosX64" ,
6670 " mingwX64" ,
6771)
6872
69- // TODO Refactor to support project names _or_ publication group names.
70- // aws-crt-kotlin is not published with a group name, so we need to check project names instead.
71- private val KOTLIN_NATIVE_PROJECT_NAMES = setOf (
72- " aws-crt-kotlin" ,
73+ // Group names which are allowed to publish K/N artifacts
74+ private val ALLOWED_KOTLIN_NATIVE_GROUP_NAMES = setOf (
75+ " aws.sdk.kotlin.crt" ,
7376)
7477
78+ // Optional override to the above set.
79+ // Used to support local development where you want to run publishToMavenLocal in smithy-kotlin, aws-sdk-kotlin.
80+ internal const val OVERRIDE_KOTLIN_NATIVE_GROUP_NAME_VALIDATION = " aws.kotlin.native.allowPublication"
81+
7582/* *
7683 * Mark this project as excluded from publishing
7784 */
@@ -237,10 +244,7 @@ fun Project.configurePublishing(repoName: String, githubOrganization: String = "
237244 if (! secretKey.isNullOrBlank() && ! passphrase.isNullOrBlank()) {
238245 apply (plugin = " signing" )
239246 extensions.configure<SigningExtension > {
240- useInMemoryPgpKeys(
241- secretKey,
242- passphrase,
243- )
247+ useInMemoryPgpKeys(secretKey, passphrase)
244248 sign(publications)
245249 }
246250
@@ -306,47 +310,54 @@ fun Project.configureNexus(
306310fun Project.configureJReleaser () {
307311 verifyRootProject { " JReleaser configuration must be applied to the root project only" }
308312
309- var missingVariables = false
310- listOf (
313+ val requiredVariables = listOf (
311314 EnvironmentVariables .MAVEN_CENTRAL_USERNAME ,
312315 EnvironmentVariables .MAVEN_CENTRAL_TOKEN ,
313316 EnvironmentVariables .GPG_PASSPHRASE ,
314317 EnvironmentVariables .GPG_PUBLIC_KEY ,
315318 EnvironmentVariables .GPG_SECRET_KEY ,
316- ).forEach {
317- if (System .getenv(it).isNullOrBlank()) {
318- missingVariables = true
319- logger.info(" Skipping JReleaser configuration, missing required environment variable: $it " )
320- }
319+ EnvironmentVariables .GENERIC_TOKEN ,
320+ )
321+
322+ if (! requiredVariables.all { ! System .getenv(it).isNullOrBlank() }) {
323+ logger.warn(" Skipping JReleaser configuration, missing one or more required environment variables: ${requiredVariables.joinToString()} " )
324+ return
321325 }
322- if (missingVariables) return
323326
324- // Get SDK version from gradle.properties
325- val sdkVersion: String by project
327+ // Collect a set of native artifact IDs from every project
328+ val nativeArtifactIds = providers.provider {
329+ allprojects.flatMap {
330+ it.extensions.findByType(PublishingExtension ::class .java)
331+ ?.publications
332+ ?.withType(MavenPublication ::class .java)
333+ ?.filter { it.name in ALLOWED_KOTLIN_NATIVE_PUBLICATION_NAMES }
334+ ?.map { it.artifactId }
335+ ? : emptySet()
336+ }.toSet()
337+ }
326338
327339 apply (plugin = " org.jreleaser" )
328340 extensions.configure<JReleaserExtension > {
329341 project {
330- version = sdkVersion
342+ version = providers.gradleProperty( " sdkVersion" ).get()
331343 }
332344
345+ // FIXME We're currently signing the artifacts twice. Once using the logic in configurePublishing above,
346+ // and the second time during JReleaser's signing stage.
333347 signing {
334348 active = Active .ALWAYS
335349 armored = true
336350 }
337351
338- // Used for creating a tagged release, uploading files and generating changelogs.
339- // In the future we can set this up to push release tags to GitHub, but for now it's
340- // set up to do nothing.
341- // https://jreleaser.org/guide/latest/reference/release/index.html
352+ // JReleaser requires a releaser to be configured even though we don't use it.
353+ // https://github.com/jreleaser/jreleaser/discussions/1725#discussioncomment-10674529
342354 release {
343355 generic {
344- enabled = true
345356 skipRelease = true
346357 }
347358 }
348359
349- // Used to announce a release to configured announcers.
360+ // We don't announce our releases anywhere
350361 // https://jreleaser.org/guide/latest/reference/announce/index.html
351362 announce {
352363 active = Active .NEVER
@@ -356,14 +367,23 @@ fun Project.configureJReleaser() {
356367 maven {
357368 mavenCentral {
358369 create(" maven-central" ) {
359- active = Active .ALWAYS
360370 url = " https://central.sonatype.com/api/v1/publisher"
361371 stagingRepository(rootProject.layout.buildDirectory.dir(" m2" ).get().toString())
362372 artifacts {
363373 artifactOverride {
364374 artifactId = " version-catalog"
365- jar = false
366- verifyPom = false // jreleaser doesn't understand toml packaging
375+ jar = false // Version catalogs don't produce a JAR
376+ verifyPom = false // JReleaser fails when processing <packaging>toml</packaging> tag: `Unknown packaging: toml`
377+ }
378+ gradle.projectsEvaluated {
379+ nativeArtifactIds.get().forEach {
380+ artifactOverride {
381+ artifactId = it
382+ jar = false // Native artifacts produce klibs, not JARs
383+ verifyPom = false // JReleaser fails when processing <packaging>klib</packaging> tag: `Unknown packaging: klib`
384+ }
385+ }
386+ logger.info(" Configured JReleaser artifact overrides for the following artifacts: ${nativeArtifactIds.get().joinToString()} " )
367387 }
368388 }
369389 maxRetries = 100
@@ -381,17 +401,22 @@ internal fun isAvailableForPublication(project: Project, publication: MavenPubli
381401 // Check SKIP_PUBLISH_PROP
382402 if (project.extra.has(Properties .SKIP_PUBLISHING )) shouldPublish = false
383403
384- // Only publish publications with the configured group from JReleaser or everything if JReleaser group is not configured
385- val publishGroupName = System .getenv(EnvironmentVariables .GROUP_ID )
386- shouldPublish = shouldPublish && (publishGroupName == null || publication.groupId.startsWith(publishGroupName))
387-
388- // Validate publication name is allowed to be published
389- shouldPublish = shouldPublish &&
390- (
391- ALLOWED_PUBLICATION_NAMES .any { publication.name.equals(it, ignoreCase = true ) } ||
392- // standard publication
393- (KOTLIN_NATIVE_PUBLICATION_NAMES .any { publication.name.equals(it, ignoreCase = true ) } && KOTLIN_NATIVE_PROJECT_NAMES .any { project.name.equals(it, ignoreCase = true ) }) // Kotlin/Native publication
394- )
404+ // Allow overriding K/N publications for local development
405+ val overrideGroupNameValidation = project.extra.getOrNull<String >(OVERRIDE_KOTLIN_NATIVE_GROUP_NAME_VALIDATION ) == " true"
406+
407+ // Validate publication name
408+ if (publication.name in ALLOWED_PUBLICATION_NAMES ) {
409+ // Standard publication
410+ } else if (publication.name in ALLOWED_KOTLIN_NATIVE_PUBLICATION_NAMES ) {
411+ // Kotlin/Native publication
412+ if (overrideGroupNameValidation && publication.groupId !in ALLOWED_KOTLIN_NATIVE_PUBLICATION_NAMES ) {
413+ println (" Overriding K/N publication, project=${project.name} ; publication=${publication.name} ; group=${publication.groupId} " )
414+ } else {
415+ shouldPublish = shouldPublish && publication.groupId in ALLOWED_KOTLIN_NATIVE_GROUP_NAMES
416+ }
417+ } else {
418+ shouldPublish = false
419+ }
395420
396421 return shouldPublish
397422}
0 commit comments