Skip to content

Commit 5f503ca

Browse files
authored
Merge pull request #2875 from square/py/dependency-refresh
Update dependencies and the build toolchain
2 parents 9d8da57 + 35e12a3 commit 5f503ca

19 files changed

Lines changed: 111 additions & 89 deletions

File tree

.github/workflows/main.yml

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -13,18 +13,18 @@ jobs:
1313
validation:
1414
runs-on: ubuntu-latest
1515
steps:
16-
- uses: actions/checkout@v4
17-
- uses: gradle/actions/wrapper-validation@48b5f213c81028ace310571dc5ec0fbbca0b2947 # v4
16+
- uses: actions/checkout@v7
17+
- uses: gradle/actions/wrapper-validation@0723195856401067f7a2779048b490ace7a47d7c # v5
1818

1919
checks:
2020
runs-on: ubuntu-latest
2121
steps:
22-
- uses: actions/checkout@v4
23-
- uses: actions/setup-java@v4
22+
- uses: actions/checkout@v7
23+
- uses: actions/setup-java@v5
2424
with:
2525
java-version: 17
2626
distribution: 'zulu'
27-
- uses: gradle/actions/setup-gradle@48b5f213c81028ace310571dc5ec0fbbca0b2947 # v4
27+
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
2828
- name: Build project
2929
run: ./gradlew build --stacktrace
3030

@@ -64,12 +64,12 @@ jobs:
6464
sudo udevadm control --reload-rules
6565
sudo udevadm trigger --name-match=kvm
6666
ls /dev/kvm
67-
- uses: actions/checkout@v4
68-
- uses: actions/setup-java@v4
67+
- uses: actions/checkout@v7
68+
- uses: actions/setup-java@v5
6969
with:
7070
java-version: 17
7171
distribution: 'zulu'
72-
- uses: gradle/actions/setup-gradle@48b5f213c81028ace310571dc5ec0fbbca0b2947 # v4
72+
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
7373
# Create the AVD and boot it from scratch on every run, rather than restoring a cached
7474
# snapshot. android-emulator-runner decides the device is ready when `getprop
7575
# sys.boot_completed` returns 1 and then immediately sends `input keyevent 82` to dismiss the
@@ -115,7 +115,7 @@ jobs:
115115
pkill -9 -f "qemu-syste[m]" || true
116116
- name: Upload results
117117
if: ${{ always() }}
118-
uses: actions/upload-artifact@v4
118+
uses: actions/upload-artifact@v7
119119
with:
120120
name: ${{ matrix.api-level }}-${{ matrix.arch }}-instrumentation-test-results
121121
path: |
@@ -127,12 +127,12 @@ jobs:
127127
needs: [ checks ]
128128
runs-on: ubuntu-latest
129129
steps:
130-
- uses: actions/checkout@v4
131-
- uses: actions/setup-java@v4
130+
- uses: actions/checkout@v7
131+
- uses: actions/setup-java@v5
132132
with:
133133
java-version: 17
134134
distribution: 'zulu'
135-
- uses: gradle/actions/setup-gradle@48b5f213c81028ace310571dc5ec0fbbca0b2947 # v4
135+
- uses: gradle/actions/setup-gradle@0723195856401067f7a2779048b490ace7a47d7c # v5
136136
- name: Deploy snapshot
137137
run: ./gradlew publish
138138
env:

.github/workflows/publish-release.yml

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -11,8 +11,8 @@ jobs:
1111
runs-on: ubuntu-latest
1212
if: github.repository == 'square/leakcanary'
1313
steps:
14-
- uses: actions/checkout@v4
15-
- uses: actions/setup-java@v4
14+
- uses: actions/checkout@v7
15+
- uses: actions/setup-java@v5
1616
with:
1717
java-version: 17
1818
distribution: 'zulu'

.github/workflows/stale.yaml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ jobs:
99
permissions:
1010
issues: write
1111
steps:
12-
- uses: actions/stale@v5
12+
- uses: actions/stale@v11
1313
with:
1414
repo-token: ${{ secrets.GITHUB_TOKEN }}
1515
days-before-stale: 30

AGENTS.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,9 @@ every diff. Refactors, internal cleanups and test-only changes usually don't nee
110110
- Test heap dumps are built with the `dump { }` DSL from `shark-hprof-test` (see `docs/dev-env.md`)
111111
rather than committed as binary fixtures. Never hand-assemble hprof bytes. For a large realistic
112112
dump, drive a real JVM via `HotSpotDiagnosticMXBean.dumpHeap`.
113-
- Tests use JUnit 4 and AssertJ. Note AssertJ is pinned at **3.9.1**, which predates a lot of the
114-
assertions you may reach for — `hasSizeLessThanOrEqualTo` and friends don't exist.
113+
- Tests use JUnit 4 and AssertJ. Instrumentation tests depend on `libs.assertjCore.android` rather
114+
than `libs.assertjCore`, because AssertJ 3.16 and up can't load on API 24 — the catalog comment
115+
says why. So an assertion that a unit test can use may not compile in an instrumentation test.
115116

116117
## Scoped guides
117118

build.gradle.kts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import com.android.build.api.dsl.LibraryExtension
44
import com.android.build.api.variant.LibraryAndroidComponentsExtension
55
import com.android.build.api.variant.ScopedArtifacts
66
import com.vanniktech.maven.publish.MavenPublishBaseExtension
7-
import com.vanniktech.maven.publish.SonatypeHost
87
import io.gitlab.arturbosch.detekt.extensions.DetektExtension
98
import java.net.URI
109
import org.gradle.api.tasks.testing.logging.TestExceptionFormat
@@ -202,7 +201,7 @@ val publicApiProjects = subprojects.filter {
202201
configure(publicApiProjects) {
203202
pluginManager.withPlugin("com.vanniktech.maven.publish") {
204203
extensions.configure<MavenPublishBaseExtension> {
205-
publishToMavenCentral(SonatypeHost.CENTRAL_PORTAL, automaticRelease = true)
204+
publishToMavenCentral(automaticRelease = true)
206205
signAllPublications()
207206
}
208207
}

docs/changelog.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -43,6 +43,7 @@ Releases before 2.8.1 predate these markers.
4343
* 🔀 `ShortestPathObjectNode.retainedIncrease` is now 0 until the third heap dump. Computing it needs a retained size for the previous heap dump, computed with the same metric while that heap dump was still open, and the first traversal has no growing objects to compute a retained size from. `ShortestPathObjectNode.retained` is still reported from the second heap dump on.
4444
* 🔨 The traversal doesn't keep a dominator for every object it visits anymore. Instead, the objects that stay reachable without going through a growing object are walked once at the end of the traversal, and only when there are growing objects to report.
4545
* ⚠️ [#2841](https://github.com/square/leakcanary/pull/2841) The deobfuscation Gradle plugin moved to the Android Gradle Plugin Variant API and now requires AGP 8.0 or newer. `leakCanary.filterObfuscatedVariants` receives a `com.android.build.api.variant.Variant` instead of the removed `BaseVariant`, the task that copies the mapping file is renamed from `leakCanaryCopyObfuscationMappingFor${VariantName}` to `copy${VariantName}LeakCanaryObfuscationMapping`, and `CopyObfuscationMappingFileTask` no longer exposes `mergeAssetsDirectory` or `leakCanaryAssetsOutputFile`. Applying the plugin to a variant that doesn't have minification enabled now fails when the task runs rather than when the project is configured.
46+
* 🔀 Curtains 1.2.4 → 1.2.5, which reports Compose popup windows as `POPUP_WINDOW` instead of `UNKNOWN`. `RootViewWatcher.WindowTypeFilter` doesn't expect popup windows to become weakly reachable when they're detached, because Android widgets keep detached popup instances around, so a Compose popup that stays in memory after being detached is no longer reported as a leak.
4647

4748
## Version 3.0 Alpha 9 (2026-06-25)
4849

docs/releasing.md

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,6 @@ python3 -m venv venv
2424
source venv/bin/activate
2525
pip3 install --requirement docs/requirements.txt
2626
```
27-
* The Google Analytics key, required by `mkdocs` when deploying the docs. Add to your `~/.bashrc`:
28-
```bash
29-
export LEAKCANARY_GOOGLE_ANALYTICS_KEY="UA-142834539-1"
30-
```
3127

3228
### Milestone management aliases (optional helpers)
3329

docs/requirements.txt

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,3 @@
1-
mkdocs==1.4.2
2-
mkdocs-material==9.1.3
3-
mkdocs-markdownextradata-plugin==0.2.5
1+
mkdocs==1.6.1
2+
mkdocs-material==9.7.7
3+
mkdocs-markdownextradata-plugin==0.2.6

gradle/libs.versions.toml

Lines changed: 49 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -13,30 +13,35 @@
1313
# limitations under the License.
1414

1515
[versions]
16-
# We would like to use Kotlin recent language features but keep Kotlin 1.3 library APIs
17-
# The benefit is that depending clients do not have to upgrade to Kotlin 1.4
18-
compose = "1.4.3"
19-
kotlin = "2.4.0"
16+
compose = "1.11.4"
17+
# androidx.lifecycle 2.11.0 requires compiling against the Android 37 SDK
18+
lifecycle = "2.10.0"
19+
kotlin = "2.4.10"
20+
# Exposed transitively by shark, avoid increasing
2021
coroutines = "1.7.3"
21-
androidXTest = "1.5.0"
22-
androidXJunit = "1.1.5"
22+
androidXTest = "1.7.0"
23+
androidXJunit = "1.3.0"
24+
# Exposed transitively by leakcanary-android-process, avoid increasing
2325
workManager = "2.7.0"
2426
detekt = "1.23.8"
2527
dokka = "2.2.0"
2628
hilt = "2.60.1"
2729
sqldelight = "2.3.2"
2830
androidMinSdk = "24"
29-
androidCompileSdk = "35"
31+
androidCompileSdk = "36"
3032

3133
[libraries]
34+
# Held at 9.2.1: the lint that AGP 9.3 bundles calls java.util.List.removeLast() from Java 8
35+
# bytecode, and that method only exists from Java 21, so every lint task dies with a
36+
# NoSuchMethodError on the JDK 17 this repo builds with.
3237
gradlePlugin-android = { module = "com.android.tools.build:gradle", version = "9.2.1" }
3338
gradlePlugin-kotlin = { module = "org.jetbrains.kotlin:kotlin-gradle-plugin", version.ref = "kotlin" }
3439
gradlePlugin-dokka = { module = "org.jetbrains.dokka:dokka-gradle-plugin", version.ref = "dokka" }
35-
gradlePlugin-mavenPublish = { module = "com.vanniktech:gradle-maven-publish-plugin", version = "0.32.0" }
40+
gradlePlugin-mavenPublish = { module = "com.vanniktech:gradle-maven-publish-plugin", version = "0.37.0" }
3641
gradlePlugin-detekt = { module = "io.gitlab.arturbosch.detekt:detekt-gradle-plugin", version.ref = "detekt" }
3742
gradlePlugin-sqldelight = { module = "app.cash.sqldelight:gradle-plugin", version.ref = "sqldelight" }
3843
gradlePlugin-hilt = { module = "com.google.dagger:hilt-android-gradle-plugin", version.ref = "hilt" }
39-
gradlePlugin-ksp = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version = "2.3.9" }
44+
gradlePlugin-ksp = { module = "com.google.devtools.ksp:com.google.devtools.ksp.gradle.plugin", version = "2.3.10" }
4045
gradlePlugin-composeCompiler = { module = "org.jetbrains.kotlin.plugin.compose:org.jetbrains.kotlin.plugin.compose.gradle.plugin", version.ref = "kotlin" }
4146
# Used by the root build script to validate the ABI of Android library modules, see KT-83410.
4247
kotlin-abi-tools = { module = "org.jetbrains.kotlin:abi-tools", version.ref = "kotlin" }
@@ -60,35 +65,57 @@ androidX-fragment = { module = "androidx.fragment:fragment", version = "1.0.0" }
6065
# INITIALIZED lifecycle state, which LeakCanary has to account for. Instrumentation tests run
6166
# against a recent version so that they cover the behavior that apps actually run, while the
6267
# compileOnly dependency above stays at the lowest version LeakCanary supports.
63-
androidX-fragment-test = { module = "androidx.fragment:fragment", version = "1.8.6" }
68+
androidX-fragment-test = { module = "androidx.fragment:fragment", version = "1.8.9" }
6469
androidX-multidex = { module = "androidx.multidex:multidex", version = "2.0.1" }
6570
# Exposed transitively, avoid increasing
6671
androidX-startup = { module = "androidx.startup:startup-runtime", version = "1.0.0" }
67-
androidX-test-core = { module = "androidx.test:core", version = "1.5.0" }
68-
androidX-test-monitor = { module = "androidx.test:monitor", version = "1.6.1" }
72+
androidX-test-core = { module = "androidx.test:core", version = "1.7.0" }
73+
androidX-test-monitor = { module = "androidx.test:monitor", version = "1.8.0" }
6974
androidX-test-rules = { module = "androidx.test:rules", version.ref = "androidXTest" }
7075
# Exposed transitively, avoid increasing
7176
androidX-test-runner = { module = "androidx.test:runner", version = "1.5.2" }
72-
androidX-test-orchestrator = { module = "androidx.test:orchestrator", version = "1.5.0" }
73-
androidX-test-espresso = { module = "androidx.test.espresso:espresso-core", version = "3.5.1" }
77+
androidX-test-orchestrator = { module = "androidx.test:orchestrator", version = "1.6.1" }
78+
androidX-test-espresso = { module = "androidx.test.espresso:espresso-core", version = "3.7.0" }
7479
androidX-test-junit = { module = "androidx.test.ext:junit", version.ref = "androidXJunit" }
7580
androidX-test-junitKtx = { module = "androidx.test.ext:junit-ktx", version.ref = "androidXJunit" }
81+
# Exposed transitively by leakcanary-android-uiautomator, avoid increasing
7682
androidX-test-uiautomator = { module = "androidx.test.uiautomator:uiautomator", version = "2.2.0" }
7783
androidX-work-runtime = { module = "androidx.work:work-runtime", version.ref = "workManager" }
7884
androidX-work-multiprocess = { module = "androidx.work:work-multiprocess", version.ref = "workManager" }
85+
# Exposed transitively by shark-graph, avoid increasing
7986
androidX-collections = { module = "androidx.collection:collection-ktx", version = "1.4.0" }
8087

81-
androidSupport = { module = "com.android.support:support-v4", version = "28.0.0" }
82-
assertjCore = { module = "org.assertj:assertj-core", version = "3.9.1" }
83-
clikt = { module = "com.github.ajalt:clikt", version = "2.3.0" }
84-
neo4j = { module = "org.neo4j:neo4j", version = "4.4.6" }
85-
curtains = { module = "com.squareup.curtains:curtains", version = "1.2.4" }
88+
assertjCore = { module = "org.assertj:assertj-core", version = "3.27.7" }
89+
# AssertJ 3.16.0 builds java.time formatters in StandardRepresentation's static initializer, and
90+
# java.time only exists from API 26, so on API 24 the very first assertion dies with a
91+
# NoClassDefFoundError. Instrumentation tests run on every API level LeakCanary supports, so they
92+
# stay on the last version that loads there. Unit tests run on the JVM and use the version above.
93+
assertjCore-android = { module = "org.assertj:assertj-core", version = "3.15.0" }
94+
clikt = { module = "com.github.ajalt:clikt", version = "2.8.0" }
95+
neo4j = { module = "org.neo4j:neo4j", version = "4.4.48" }
96+
curtains = { module = "com.squareup.curtains:curtains", version = "1.2.5" }
8697
jline = { module = "jline:jline", version = "2.14.6" }
8798
junit = { module = "junit:junit", version = "4.13.2" }
8899
kotlinStatistics = { module = "org.nield:kotlin-statistics", version = "1.2.1" }
89-
mockito = { module = "org.mockito:mockito-core", version = "3.5.10" }
90-
mockitoKotlin = { module = "com.nhaarman.mockitokotlin2:mockito-kotlin", version = "2.2.0" }
91-
robolectric = { module = "org.robolectric:robolectric", version = "4.0-alpha-3" }
100+
mockito = { module = "org.mockito:mockito-core", version = "5.23.0" }
101+
mockitoKotlin = { module = "org.mockito.kotlin:mockito-kotlin", version = "6.3.0" }
102+
# Exposed transitively by every published module that reads heap dumps, avoid increasing
92103
okio2 = { module = "com.squareup.okio:okio", version = "2.2.2" }
93104
sqldelight-android = { module = "app.cash.sqldelight:android-driver", version.ref = "sqldelight" }
94105
sqldelight-coroutines = { module = "app.cash.sqldelight:coroutines-extensions", version.ref = "sqldelight" }
106+
107+
# Only used by leakcanary-app, the standalone UI app, which isn't published, so these can track the
108+
# latest release.
109+
androidX-activity-compose = { module = "androidx.activity:activity-compose", version = "1.13.0" }
110+
# androidx.core 1.19.0 requires compiling against the Android 37 SDK
111+
androidX-core = { module = "androidx.core:core-ktx", version = "1.18.0" }
112+
androidX-lifecycle-runtime = { module = "androidx.lifecycle:lifecycle-runtime-ktx", version.ref = "lifecycle" }
113+
androidX-lifecycle-viewModelCompose = { module = "androidx.lifecycle:lifecycle-viewmodel-compose", version.ref = "lifecycle" }
114+
androidX-sqlite-framework = { module = "androidx.sqlite:sqlite-framework", version = "2.7.0" }
115+
compose-material3 = { module = "androidx.compose.material3:material3", version = "1.4.0" }
116+
# The Material icons stopped shipping with Compose Material 3 and are frozen at 1.7.8.
117+
compose-materialIcons = { module = "androidx.compose.material:material-icons-core", version = "1.7.8" }
118+
compose-ui = { module = "androidx.compose.ui:ui", version.ref = "compose" }
119+
compose-ui-tooling = { module = "androidx.compose.ui:ui-tooling", version.ref = "compose" }
120+
compose-ui-toolingPreview = { module = "androidx.compose.ui:ui-tooling-preview", version.ref = "compose" }
121+
extendedSpans = { module = "me.saket.extendedspans:extendedspans", version = "1.4.0" }

leakcanary/leakcanary-android-core/build.gradle.kts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -19,12 +19,10 @@ dependencies {
1919
testImplementation(libs.assertjCore)
2020
testImplementation(libs.junit)
2121
testImplementation(libs.kotlin.reflect)
22-
testImplementation(libs.mockito)
23-
testImplementation(libs.mockitoKotlin)
2422
androidTestImplementation(libs.androidX.test.espresso)
2523
androidTestImplementation(libs.androidX.test.rules)
2624
androidTestImplementation(libs.androidX.test.runner)
27-
androidTestImplementation(libs.assertjCore)
25+
androidTestImplementation(libs.assertjCore.android)
2826
androidTestImplementation(projects.shark.sharkHprofTest)
2927
androidTestUtil(libs.androidX.test.orchestrator)
3028
}

0 commit comments

Comments
 (0)