Skip to content
Merged
Show file tree
Hide file tree
Changes from 5 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
4 changes: 1 addition & 3 deletions .github/workflows/upload-artifacts.yml
Original file line number Diff line number Diff line change
@@ -1,8 +1,6 @@
name: "Generate and upload distributions"
on:
push:
branches:
- release/**
pull_request:

concurrency:
group: ${{ github.workflow }}-${{ github.ref }}
Expand Down
7 changes: 5 additions & 2 deletions build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -31,16 +31,19 @@ subprojects {
apply<DistributionPlugin>()

val sep = File.separator
// The path where we want publishToMavenLocal to output the artifacts to
val buildPublishDir = "${project.layout.buildDirectory.get().asFile.path}${sep}sentry-local-publish$sep"

configure<DistributionContainer> {
this.configureForMultiplatform(this@subprojects)
this.configureForMultiplatform(this@subprojects, buildPublishDir)
}

tasks.named("distZip").configure {
System.setProperty("maven.repo.local", buildPublishDir)
Copy link
Member

@romtsn romtsn Jul 18, 2025

Choose a reason for hiding this comment

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

so this will tell the task where to publish to?

Copy link
Contributor Author

Choose a reason for hiding this comment

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

yep, it then publishes into the specified dir

this.dependsOn("publishToMavenLocal")
this.doLast {
val distributionFilePath =
"${this.project.buildDir}${sep}distributions${sep}${this.project.name}-${this.project.version}.zip"
"${project.layout.buildDirectory.get().asFile.path}${sep}distributions${sep}${this.project.name}-${this.project.version}.zip"
val file = File(distributionFilePath)
if (!file.exists()) throw GradleException("Distribution file: $distributionFilePath does not exist")
if (file.length() == 0L) throw GradleException("Distribution file: $distributionFilePath is empty")
Expand Down
13 changes: 7 additions & 6 deletions buildSrc/src/main/java/Config.kt
Original file line number Diff line number Diff line change
@@ -1,12 +1,13 @@
object Config {
val agpVersion = "7.4.2"
val kotlinVersion = "1.9.23"
val composeVersion = "1.6.1"
val kotlinVersion = "2.1.21"
val composePluginVersion = "1.8.0"
val gradleMavenPublishPluginVersion = "0.18.0"

val multiplatform = "multiplatform"
val cocoapods = "native.cocoapods"
val jetpackCompose = "org.jetbrains.compose"
val kotlinCompose = "org.jetbrains.kotlin.plugin.compose"
val gradleMavenPublishPlugin = "com.vanniktech.maven.publish"
val androidGradle = "com.android.library"
val kotlinSerializationPlugin = "plugin.serialization"
Expand All @@ -26,7 +27,7 @@ object Config {
val detekt = "io.gitlab.arturbosch.detekt"
val detektVersion = "1.22.0"
val binaryCompatibility = "org.jetbrains.kotlinx.binary-compatibility-validator"
val binaryCompatibilityVersion = "0.13.1"
val binaryCompatibilityVersion = "0.18.0"
}

object Libs {
Expand Down Expand Up @@ -59,9 +60,9 @@ object Config {
val ktorClientOkHttp = "io.ktor:ktor-client-okhttp:2.3.6"
val ktorClientDarwin = "io.ktor:ktor-client-darwin:2.3.6"

val roboelectric = "org.robolectric:robolectric:4.9"
val junitKtx = "androidx.test.ext:junit-ktx:1.1.5"
val mockitoCore = "org.mockito:mockito-core:5.4.0"
val roboelectric = "org.robolectric:robolectric:4.15.1"
val junitKtx = "androidx.test.ext:junit-ktx:1.2.1"
val mockitoCore = "org.mockito:mockito-core:5.18.0"
}

object Android {
Expand Down
254 changes: 38 additions & 216 deletions buildSrc/src/main/java/Publication.kt
Original file line number Diff line number Diff line change
@@ -1,228 +1,50 @@
import org.gradle.api.GradleException
import org.gradle.api.Project
import org.gradle.api.distribution.DistributionContainer
import org.gradle.api.file.CopySpec
import java.io.File

val sep: String = File.separator
private val sep: String = File.separator

// configure distZip tasks for multiplatform
fun DistributionContainer.configureForMultiplatform(project: Project) {
val version = project.properties["versionName"].toString()
this.getByName("main").contents {
from("build${sep}publications${sep}kotlinMultiplatform") {
renameModule(project.name, version = version)
}
// The current Kotlin version doesn't generate this *-all.jar anymore.
// This is a placeholder for backwards compatibility with craft until we fix it there directly.
from("build${sep}libs") {
include("${project.name}-metadata-$version*")
rename {
it.replace("metadata-$version", "$version-all")
}
}
from("build${sep}kotlinToolingMetadata") {
rename {
it.replace(
"kotlin-tooling-metadata.json",
"${project.name}-$version-kotlin-tooling-metadata.json"
)
}
}
from("build${sep}libs") {
include("${project.name}-kotlin*")
include("${project.name}-metadata*")
withJavadoc(project.name)
rename {
it.replace("multiplatform-kotlin", "multiplatform").replace("-metadata", "")
}
}
}
this.maybeCreate("android").contents {
from("build${sep}publications${sep}androidRelease") {
renameModule(project.name, "android", version)
}
from("build${sep}outputs${sep}aar${sep}${project.name}-release.aar") {
rename {
it.replace("-release", "-android-release")
}
}
from("build${sep}libs") {
include("*android*")
withJavadoc(project.name, "android")
}
}
this.maybeCreate("jvm").contents {
from("build${sep}publications${sep}jvm") {
renameModule(project.name, "jvm", version)
}
from("build${sep}libs$sep") {
include("*jvm*")
withJavadoc(project.name, "jvm")
}
}
this.maybeCreate("iosarm64").contents {
from("build${sep}publications${sep}iosArm64") {
renameModule(project.name, "iosarm64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-iosarm64*")
withJavadoc(project.name, "iosarm64")
}
fromKlib(project.name, "iosArm64", version)
}
this.maybeCreate("iosx64").contents {
from("build${sep}publications${sep}iosX64") {
renameModule(project.name, "iosx64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-iosx64*")
withJavadoc(project.name, "iosx64")
}
fromKlib(project.name, "iosX64", version)
}
this.maybeCreate("iossimulatorarm64").contents {
from("build${sep}publications${sep}iosSimulatorArm64") {
renameModule(project.name, "iossimulatorarm64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-iossimulatorarm64*")
withJavadoc(project.name, "iossimulatorarm64")
}
fromKlib(project.name, "iosSimulatorArm64", version)
}
this.maybeCreate("macosarm64").contents {
from("build${sep}publications${sep}macosArm64") {
renameModule(project.name, "macosarm64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-macosarm64*")
withJavadoc(project.name, "macosarm64")
}
fromKlib(project.name, "macosArm64", version)
}
this.maybeCreate("macosx64").contents {
from("build${sep}publications${sep}macosX64") {
renameModule(project.name, "macosx64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-macosx64*")
withJavadoc(project.name, "macosx64")
}
fromKlib(project.name, "macosX64", version)
}
this.maybeCreate("watchosx64").contents {
from("build${sep}publications${sep}watchosX64") {
renameModule(project.name, "watchosx64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-watchosx64*")
withJavadoc(project.name, "watchosx64")
}
fromKlib(project.name, "watchosX64", version)
}
this.maybeCreate("watchosarm32").contents {
from("build${sep}publications${sep}watchosArm32") {
renameModule(project.name, "watchosarm32", version)
}
from("build${sep}libs$sep") {
include("${project.name}-watchosarm32*")
withJavadoc(project.name, "watchosarm32")
}
fromKlib(project.name, "watchosArm32", version)
}
this.maybeCreate("watchosarm64").contents {
from("build${sep}publications${sep}watchosArm64") {
renameModule(project.name, "watchosarm64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-watchosarm64*")
withJavadoc(project.name, "watchosarm64")
}
fromKlib(project.name, "watchosArm64", version)
}
this.maybeCreate("watchossimulatorarm64").contents {
from("build${sep}publications${sep}watchosSimulatorArm64") {
renameModule(project.name, "watchossimulatorarm64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-watchossimulatorarm64*")
withJavadoc(project.name, "watchossimulatorarm64")
}
fromKlib(project.name, "watchosSimulatorArm64", version)
}
this.maybeCreate("tvosarm64").contents {
from("build${sep}publications${sep}tvosArm64") {
renameModule(project.name, "tvosarm64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-tvosarm64*")
withJavadoc(project.name, "tvosarm64")
}
fromKlib(project.name, "tvosArm64", version)
}
this.maybeCreate("tvosx64").contents {
from("build${sep}publications${sep}tvosX64") {
renameModule(project.name, "tvosx64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-tvosx64*")
withJavadoc(project.name, "tvosx64")
}
fromKlib(project.name, "tvosX64", version)
}
this.maybeCreate("tvossimulatorarm64").contents {
from("build${sep}publications${sep}tvosSimulatorArm64") {
renameModule(project.name, "tvossimulatorarm64", version)
}
from("build${sep}libs$sep") {
include("${project.name}-tvossimulatorarm64*")
withJavadoc(project.name, "tvossimulatorarm64")
}
fromKlib(project.name, "tvosSimulatorArm64", version)
}
}
fun DistributionContainer.configureForMultiplatform(project: Project, buildPublishDir: String) {
val version = project.property("versionName").toString()
if (version.isEmpty()) {
throw GradleException("DistZip: version name is empty")
}
val projectName = project.name
val platforms = mapOf(
"main" to projectName,
"android" to "$projectName-android",
"jvm" to "$projectName-jvm",
"iosarm64" to "$projectName-iosarm64",
"iossimulatorarm64" to "$projectName-iossimulatorarm64",
"iosx64" to "$projectName-iosx64",
"macosarm64" to "$projectName-macosarm64",
"macosx64" to "$projectName-macosx64",
"tvosarm64" to "$projectName-tvosarm64",
"tvossimulatorarm64" to "$projectName-tvossimulatorarm64",
"tvosx64" to "$projectName-tvosx64",
"watchosarm32" to "$projectName-watchosarm32",
"watchosarm64" to "$projectName-watchosarm64",
"watchossimulatorarm64" to "$projectName-watchossimulatorarm64",
"watchosx64" to "$projectName-watchosx64"
)

private fun CopySpec.fromKlib(projectName: String, target: String, version: String) {
val pos = projectName.length
from("build${sep}classes${sep}kotlin${sep}${target}${sep}main${sep}cinterop") {
include("*.klib")
rename {
it.replaceRange(pos, pos, "-${target.lowercase()}-$version")
}
}
from("build${sep}classes${sep}kotlin${sep}${target}${sep}main${sep}klib") {
rename {
"$projectName-${target.lowercase()}-$version.klib"
}
}
}
platforms.forEach { (distName, projectName) ->
val distribution = if (distName == "main") getByName("main") else maybeCreate(distName)
Copy link
Member

@romtsn romtsn Jul 18, 2025

Choose a reason for hiding this comment

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

not sure if we need an extension like getOrCreate something like that. Is it possible other sourcesets also exist and we should getByName in some cases?

Copy link
Contributor Author

@buenaflor buenaflor Jul 18, 2025

Choose a reason for hiding this comment

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

I think we can just use maybeCreate by default, it will look for it and if it doesnt exist it creates it which is basically a getOrCreate - updated it

distribution.contents {
val basePath = "${buildPublishDir}io${sep}sentry${sep}$projectName$sep$version"
if (File(basePath).exists().not()) {
throw GradleException("Artifact $distName does not exist: $basePath")
}

private fun CopySpec.renameModule(projectName: String, renameTo: String = "", version: String) {
var target = ""
if (renameTo.isNotEmpty()) {
target = "-$renameTo"
}
rename {
it.replace("module.json", "$projectName$target-$version.module")
}
}
// Rename the POM since craft looks for pom-default.xml
Copy link
Member

Choose a reason for hiding this comment

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

ugh, I guess ideal-world we wouldn't need this, but would have to change craft again 🙈 maybe makes sense to align this between repos and change craft at some point

from("$basePath/$projectName-$version.pom") {
rename { "pom-default.xml" }
}

private fun CopySpec.withJavadoc(projectName: String, renameTo: String = "") {
include("*javadoc*")
rename { fileName ->
when {
"javadoc" in fileName -> {
val newName = buildString {
append(fileName.substring(0, projectName.length))
if (renameTo.isNotEmpty()) {
append('-')
append(renameTo)
}
append(fileName.substring(projectName.length))
}
newName
from(basePath) {
exclude("*.pom")
}
else -> fileName
}
}
}
Loading