Use this skill to update Android library dependencies via refreshVersions. Invoke when the user asks to update, bump, or refresh dependencies or a specific library version, asks what updates are available, or hands over a dependency-update task from the Asana backlog. Covers running refreshVersions, judging which bumps are safe, handling libraries blocked by the project's Kotlin version, running the E2E suite, and the PR/Asana conventions for the change.
69
84%
Does it follow best practices?
Run evals on this skill
Adds up to 20 points to the overall score
View guide
Low
Low-risk findings worth noting
Dependencies are managed via versions.properties using the refreshVersions Gradle plugin (its
version is pinned in settings.gradle). The only file that should change in a dependency update PR is
versions.properties.
./gradlew refreshVersionsThis populates versions.properties with ## # available=X.Y.Z comment hints after each entry.
After deciding on versions, strip the noise:
sed -i '' '/^##/d' versions.propertiesIMPORTANT: The #### header block at the top of versions.properties must never be removed.
It is required by the refreshVersions plugin at build time. If missing, the build fails with:
Unable to find the version of refreshVersions that generated the versions.properties file
This is the most important judgement when evaluating a library update.
Read the project's Kotlin version from version.kotlin in versions.properties; languageVersion is
pinned in the root build.gradle. Some libraries publish releases compiled with a newer Kotlin than
the project targets, which fails the build at KSP time:
Module was compiled with an incompatible version of Kotlin.
The binary version of its metadata is <newer>, expected version is <project>.A library needing a Kotlin newer than the project's is a blocker, not something to work around.
Do not auto-revert. Instead, ask the engineer:
"Library X update from A → B requires a newer Kotlin than the project currently targets. Do you want to:
- Skip this update for now
- Include it as a separate task to upgrade Kotlin first"
The engineer may decide to batch multiple blocked libraries into a Kotlin upgrade task, or simply defer them. Either way, document the decision in the PR and Asana task.
Do not keep a list of blocked libraries here — it goes stale as soon as the project's Kotlin moves.
The live source of truth is a # Cannot update … because it requires Kotlin … comment on the entry in
versions.properties; check for one, and add one when you defer a library for this reason.
androidx.*) — backward compatible, Java/Kotlin mixedzxing, org.json, robolectric, desugar_jdk_libs).kotlin_module metadata is newer than the project's Kotlin versionkotlinx.collections.immutablerxjava2.rxjava, rxjava2.rxandroid) — kept at current versions intentionallyUse the E2E Nightly Full Suite GitHub Actions workflow to validate updates:
223981529gh workflow run 223981529 --repo duckduckgo/Android --ref <branch>
gh run list --repo duckduckgo/Android --workflow=223981529 --limit=3The workflow uploads internal + release APKs to Maestro Cloud and runs UI test suites.
Runtime ~1h30m. Uses appId: com.duckduckgo.mobile.android (release build).
versions.properties should differ from origin/developandroidx.appcompat 1.7.0 → 1.7.1)Before starting a dependency update, read the canonical process task:
1199899332680683 for the full checklist and process notesEach dep update task should be a subtask of [Doc] Update dependencies (GID: 1202236475215890).
Document updated libraries, deferred libraries, and Kotlin version blockers in the task notes.
7809186
If you maintain this skill, you can claim it as your own. Once claimed, you can manage eval scenarios, bundle related skills, attach documentation or rules, and ensure cross-agent compatibility.