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
2 changes: 1 addition & 1 deletion .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -83,7 +83,7 @@ jobs:
id: gradle-instrumentation
env:
EW_API_TOKEN: ${{ secrets.EMULATOR_WTF_TOKEN }}
run: ./gradlew testReleaseWithEmulatorWtf --quiet
run: ./gradlew testWithEmulatorWtf --quiet

- name: Enable KVM group perms
run: |
Expand Down
53 changes: 24 additions & 29 deletions backstack/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -1,21 +1,25 @@
// Copyright (C) 2022 Slack Technologies, LLC
// SPDX-License-Identifier: Apache-2.0
import com.android.build.api.withAndroid
import org.jetbrains.kotlin.gradle.ExperimentalKotlinGradlePluginApi
import org.jetbrains.kotlin.gradle.ExperimentalWasmDsl
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask

plugins {
alias(libs.plugins.agp.library)
alias(libs.plugins.agp.kmp)
alias(libs.plugins.kotlin.multiplatform)
alias(libs.plugins.kotlin.atomicfu)
alias(libs.plugins.compose)
alias(libs.plugins.mavenPublish)
alias(libs.plugins.baselineprofile)
id("circuit.base")
id("circuit.publish")
}

kotlin {
// region KMP Targets
androidTarget { publishLibraryVariants("release") }
android {
namespace = "com.slack.circuit.backstack"
compileSdk = 36
}
jvm()
iosArm64()
iosSimulatorArm64()
Expand Down Expand Up @@ -46,9 +50,17 @@ kotlin {

@OptIn(ExperimentalKotlinGradlePluginApi::class)
applyDefaultHierarchyTemplate {
group("browserCommon") {
withJs()
withWasmJs()
common {
group("commonJvm") {
withJvm()
withAndroid()
}
}
common {
group("browserCommon") {
withJs()
withWasmJs()
}
}
}

Expand All @@ -74,18 +86,12 @@ kotlin {
implementation(projects.internalTestUtils)
}
}
get("browserCommonMain").dependsOn(commonMain.get())
get("browserCommonTest").dependsOn(commonTest.get())
androidMain {}
val commonJvmTest =
maybeCreate("commonJvmTest").apply {
dependsOn(commonTest.get())
dependencies {
implementation(libs.junit)
implementation(libs.truth)
}
maybeCreate("commonJvmTest").apply {
dependencies {
implementation(libs.junit)
implementation(libs.truth)
}
jvmTest { dependsOn(commonJvmTest) }
}
}
}

Expand All @@ -96,14 +102,3 @@ tasks.withType<KotlinCompilationTask<*>>().configureEach {
allWarningsAsErrors = false
}
}

android { namespace = "com.slack.circuit.backstack" }

androidComponents { beforeVariants { variant -> variant.androidTest.enable = false } }

baselineProfile {
mergeIntoMain = true
saveInSrc = true
from(project(projects.samples.star.benchmark.path))
filter { include("com.slack.circuit.backstack.**") }
}
29 changes: 29 additions & 0 deletions build-logic/build.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
// Copyright (C) 2026 Slack Technologies, LLC
// SPDX-License-Identifier: Apache-2.0
plugins {
`kotlin-dsl`
}

kotlin { jvmToolchain(libs.versions.jdk.get().removeSuffix("-ea").toInt()) }

dependencies {
compileOnly(libs.kotlin.gradlePlugin)
compileOnly(libs.kotlin.compose.compiler.gradlePlugin)
compileOnly(libs.agp)
implementation(
libs.plugins.mavenPublish.get().run { "$pluginId:$pluginId.gradle.plugin:$version" }
)
implementation(libs.plugins.dokka.get().run { "$pluginId:$pluginId.gradle.plugin:$version" })
implementation(
libs.plugins.dependencyGuard.get().run { "$pluginId:$pluginId.gradle.plugin:$version" }
)
implementation(
libs.plugins.spotless.get().run { "$pluginId:$pluginId.gradle.plugin:$version" }
)
implementation(
libs.plugins.emulatorWtf.get().run { "$pluginId:$pluginId.gradle.plugin:$version" }
)
implementation(
libs.plugins.anvil.get().run { "$pluginId:$pluginId.gradle.plugin:$version" }
)
}
12 changes: 12 additions & 0 deletions build-logic/settings.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Copyright (C) 2026 Slack Technologies, LLC
// SPDX-License-Identifier: Apache-2.0
dependencyResolutionManagement {
repositories {
mavenCentral()
google()
gradlePluginPortal()
}
versionCatalogs { maybeCreate("libs").apply { from(files("../gradle/libs.versions.toml")) } }
}

rootProject.name = "build-logic"
19 changes: 19 additions & 0 deletions build-logic/src/main/kotlin/CircuitProjectExtension.kt
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
// Copyright (C) 2026 Slack Technologies, LLC
// SPDX-License-Identifier: Apache-2.0
import javax.inject.Inject
import org.gradle.api.Project
import org.gradle.api.model.ObjectFactory
import org.gradle.api.provider.Property
import org.gradle.api.provider.ProviderFactory
import org.gradle.kotlin.dsl.property

/** Extension for configuring Circuit project conventions. */
abstract class CircuitProjectExtension @Inject constructor(private val project: Project, objects: ObjectFactory, providers: ProviderFactory) {
/** Whether Compose is enabled for this project. Defaults to true unless `circuit.noCompose` is set. */
val hasCompose: Property<Boolean> = objects.property<Boolean>().convention(
providers.provider {
// project-local property, which providers.gradleProperty doesn't cover
// TODO replace this with DSL calls in the project
!project.hasProperty("circuit.noCompose") }
)
}
142 changes: 142 additions & 0 deletions build-logic/src/main/kotlin/circuit.android.gradle.kts
Original file line number Diff line number Diff line change
@@ -0,0 +1,142 @@
// Copyright (C) 2026 Slack Technologies, LLC
// SPDX-License-Identifier: Apache-2.0
import com.android.build.api.dsl.ApplicationExtension
import com.android.build.api.dsl.CommonExtension
import com.android.build.api.dsl.KotlinMultiplatformAndroidHostTestCompilation
import com.android.build.api.dsl.KotlinMultiplatformAndroidLibraryTarget
import com.android.build.api.dsl.LibraryExtension
import com.android.build.api.dsl.TestExtension
import org.jetbrains.kotlin.gradle.dsl.KotlinMultiplatformExtension
import org.jetbrains.kotlin.gradle.dsl.kotlinExtension

val catalog = rootProject.extensions.getByType<VersionCatalogsExtension>().named("libs")
val jvmTargetVersion = catalog.findVersion("jvmTarget").get().requiredVersion
val compileSdkVersion = catalog.findVersion("android-compileSdk").get().requiredVersion.toInt()
val circuitExtension = extensions.getByType<CircuitProjectExtension>()

// Android Library configuration
pluginManager.withPlugin("com.android.kotlin.multiplatform.library") {
pluginManager.withPlugin("org.jetbrains.kotlin.multiplatform") {
(kotlinExtension as KotlinMultiplatformExtension)
.targets
.withType(KotlinMultiplatformAndroidLibraryTarget::class.java)
.configureEach {
compileSdk = compileSdkVersion
minSdk = 23
compilations.withType(KotlinMultiplatformAndroidHostTestCompilation::class.java) {
targetSdk { release(compileSdkVersion) }
}
lint {
// https://issuetracker.google.com/issues/243267012
disable += "Instantiatable"
checkTestSources = true
checkDependencies = false
lintConfig = rootProject.file("config/lint/lint.xml")
}
}
}
dependencies { add("lintChecks", catalog.findLibrary("lints-compose").get()) }
}

fun CommonExtension.configureCommonAndroid() {
compileSdk = compileSdkVersion
}

pluginManager.withPlugin("com.android.test") {
extensions.configure<TestExtension> {
configureCommonAndroid()

defaultConfig { minSdk = 28 }

compileOptions {
sourceCompatibility = JavaVersion.toVersion(jvmTargetVersion)
targetCompatibility = JavaVersion.toVersion(jvmTargetVersion)
}
lint {
// https://issuetracker.google.com/issues/243267012
disable += "Instantiatable"
checkTestSources = true
checkDependencies = false
lintConfig = rootProject.file("config/lint/lint.xml")
}
}
}

// Android (non-KMP) Library configuration
pluginManager.withPlugin("com.android.library") {
extensions.configure<LibraryExtension> {
configureCommonAndroid()

buildFeatures { compose = circuitExtension.hasCompose.get() }

compileOptions {
sourceCompatibility = JavaVersion.toVersion(jvmTargetVersion)
targetCompatibility = JavaVersion.toVersion(jvmTargetVersion)
}

defaultConfig { minSdk = 23 }

lint {
// https://issuetracker.google.com/issues/243267012
disable += "Instantiatable"
checkTestSources = true
checkDependencies = false
lintConfig = rootProject.file("config/lint/lint.xml")
}
}

dependencies {
add("lintChecks", catalog.findLibrary("lints-compose").get())
}
}

// Android Application configuration
pluginManager.withPlugin("com.android.application") {
extensions.configure<ApplicationExtension> {
configureCommonAndroid()

buildFeatures { compose = circuitExtension.hasCompose.get() }

compileOptions {
sourceCompatibility = JavaVersion.toVersion(jvmTargetVersion)
targetCompatibility = JavaVersion.toVersion(jvmTargetVersion)
isCoreLibraryDesugaringEnabled = true
}

defaultConfig {
minSdk = 23
targetSdk = compileSdkVersion
}

buildTypes {
maybeCreate("debug").apply { matchingFallbacks += listOf("release") }
maybeCreate("release").apply {
isMinifyEnabled = true
signingConfig = signingConfigs.getByName("debug")
matchingFallbacks += listOf("release")
}
}

// https://issuetracker.google.com/issues/501744304
// AGP 9 ignores lint configuration on application modules entirely,
// causing it to lint transitive dependency test sources.
// Just disable the tasks until this is fixed.
afterEvaluate {
tasks.matching { it.name.contains("lint", ignoreCase = true) }.configureEach {
enabled = false
}
}
lint {
// https://issuetracker.google.com/issues/243267012
disable += "Instantiatable"
checkTestSources = true
checkDependencies = false
lintConfig = rootProject.file("config/lint/lint.xml")
}
}

dependencies {
add("lintChecks", catalog.findLibrary("lints-compose").get())
add("coreLibraryDesugaring", catalog.findLibrary("desugarJdkLibs").get())
}
}
Loading
Loading