A gradle plugin for detecting regressions in Jetpack Compose / Compose Multiplatform:
- New restartable but not skippable @Composables are added
- New unstable classes are added (only triggers if they are used as a @Composable parameter)
- New @dynamic properties are added
- New unstable parameters are added to a @Composable
In an Android project, Compose Guard adds 3 tasks:
<variant>ComposeCompilerGenerate
(example./gradlew releaseComposeCompilerGenerate
)- Generate golden compose metrics to compare against
<variant>ComposeCompilerCheck
(example./gradlew releaseComposeCompilerCheck
)- Generates new metrics and compares against golden values
./gradlew composeCompilerClean
- Deletes all compiler metrics
In a Multiplatform project, Compose Guard adds the same 2 Check
and Generate
tasks (as well as a root composeCompilerClean
task) for each supported target following the pattern <target><variant if applicable>ComposeCompilerGenerate
<target><variant>ComposeCompilerGenerate
- Examples:
./gradlew androidReleaseComposeCompilerGenerate
,./gradlew jvmComposeCompilerGenerate
,./gradlew iosArm64ComposeCompilerGenerate
,./gradlew jsComposeCompilerGenerate
,./gradlew wasmJsComposeCompilerGenerate
- Generate golden compose metrics to compare against
- Examples:
<target><variant>ComposeCompilerCheck
- Examples:
./gradlew androidReleaseComposeCompilerCheck
,./gradlew jvmComposeCompilerCheck
,./gradlew iosArm64ComposeCompilerCheck
,./gradlew jsComposeCompilerCheck
,./gradlew wasmJsComposeCompilerCheck
- Generates new metrics and compares against golden values
- Examples:
./gradlew composeCompilerClean
- Deletes all compiler metrics
✅ | ✅ | ✅ | ✅ |
In your root build file:
plugins {
id("com.joetr.compose.guard") version "<latest version>" apply false
}
In any module you want to apply checks:
plugins {
id("com.joetr.compose.guard")
}
Each check that is performed has the ability to be turned off in case it is not useful to you.
composeGuardCheck {
errorOnNewDynamicProperties = false // defaults to true
errorOnNewRestartableButNotSkippableComposables = false // defaults to true
errorOnNewUnstableClasses = false // defaults to true
errorOnNewUnstableParams = false // defaults to true
/**
* In strong skipping mode (https://developer.android.com/develop/ui/compose/performance/stability/strongskipping)
* you may not care about new unstable params if the composable is already skippable
*/
ignoreUnstableParamsOnSkippableComposables = true // defaults to false
}
Additionally, the output directory of the golden metrics has the ability to be configured as well.
composeGuardGenerate {
outputDirectory = layout.projectDirectory.dir("custom_dir").asFile
}
This is required to test.
- Install gnupg - https://formulae.brew.sh/formula/gnupg
- Generate a key - https://central.sonatype.org/publish/requirements/gpg/#generating-a-key-pair
gpg --full-generate-key
- List keys and grab newly generated key (40 digits)
gpg --list-keys
gpg --export-secret-keys THE_KEY_THAT_YOU_JUST_GENERATED > composeguard.gpg
- Modify your gradle home
gradle.properties
with the following:
signing.keyId=LAST_8_DIGITS_OF_KEY
signing.password=PASSWORD_USED_TO_GENERATE_KEY
signing.secretKeyRingFile=/Users/YOURUSERNAME/.gnupg/composeguard.gpg (or wherever you stored the keyring you generated earlier)
This project uses this tool to ensure the public binary API wasn't changed in a way that makes it binary incompatible.
The tool allows dumping binary API of a JVM part of a Kotlin library that is public in the sense of Kotlin visibilities.
To generate a new binary dump, run ./gradlew apiDump
in the root of the project.