Skip to content

Android: migrate Gradle build scripts from Groovy to Kotlin DSL - #7193

Open
pmclSF wants to merge 1 commit into
BOINC:masterfrom
pmclSF:android-gradle-kts
Open

Android: migrate Gradle build scripts from Groovy to Kotlin DSL#7193
pmclSF wants to merge 1 commit into
BOINC:masterfrom
pmclSF:android-gradle-kts

Conversation

@pmclSF

@pmclSF pmclSF commented Jul 28, 2026

Copy link
Copy Markdown
Contributor

Fixes #6923

Description of the Change

Converts the three Android build scripts (settings.gradle, build.gradle, app/build.gradle) to their Kotlin DSL equivalents, as discussed in #6923. Nothing in the native client build changes.

  • Same tasks, variants, and behavior. The armv6 asset stripping and its verification guards carry over unchanged.
  • The helper logic (version code and name from git, string resource validation, asset checks) becomes typed Kotlin functions. The app script ends up about 70 lines shorter.
  • One addition: lint.xml. Lint's ExpiredTargetSdkVersion check does not recognize the Groovy space-assignment form of the declaration, so it never fired before. With the Kotlin script it does (targetSdk is 28, which predates Google Play's current minimum). It's demoted to a warning so it stays visible in lint reports without failing release builds, and actually raising targetSdk is left as a separate decision. MissingTranslation is ignored, matching the previous effective behavior.

Verification

  • Gradle task list diff between the Groovy and Kotlin builds: identical. 99 project tasks on both sides; the only additions are Gradle's own kotlinDslAccessorsReport helper tasks, which exist in any Kotlin DSL build.
  • Emulator smoke test of an R8 release build (assembleRelease) on an Android 14 (API 34) x86_64 emulator with real client binaries from CI: the app installs and launches, the native client starts and the UI connects to it, and the add-project flow loads the project list.
  • CI exercises the rest on every PR: assembleRelease, assembleArmv6_release (which fires the armv6 verification guards), and the unit test suite via jacocoTestReportDebug.
  • One note for reviewers: the version code helpers use Grgit, which cannot resolve HEAD inside a git worktree. That is unchanged from the Groovy build (both fail the same way in a worktree; verified) and does not affect normal checkouts or CI.

Alternate Designs

Keeping Groovy was the alternative, and the migration was proposed and approved in #6923. Within the migration, moving the helper functions to buildSrc or precompiled script plugins was considered but rejected to keep the diff reviewable; the scripts stay self-contained as before.

Release Notes

N/A


Summary by cubic

Migrates the Android Gradle build to Kotlin DSL for type safety and simpler scripts. No changes to tasks, variants, outputs, or the native client build. Fixes #6923.

  • Refactors
    • Converted settings.gradle, build.gradle, and app/build.gradle to .kts, preserving behavior (including ARMv6 asset stripping and its guards).
    • Rewrote helpers as typed Kotlin functions (version code/name from org.ajoberstar.grgit, string resource checks, asset checks).
    • Updated lint.xml: keep MissingTranslation ignored; ignore ExpiredTargetSdkVersion to keep release lint passing under Kotlin DSL.

Written for commit ba41570. Summary will update on new commits.

Review in cubic

@cubic-dev-ai cubic-dev-ai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

No issues found across 7 files

Re-trigger cubic

@AenBleidd

Copy link
Copy Markdown
Member

@pmclSF, I allowed this once, but I kindly ask you to follow the AI assistant usage guide, in particular: AI cannot be a co-author of the PR, it might only assist a developer, and all the respobsibility lays on the developer, not an AI tool.
Please fix the commit message.
Thank you in advance.

Comment thread android/BOINC/app/lint.xml Outdated
check only started firing with the Kotlin DSL build script. Demoted to
warning so it stays visible in lint reports without failing the
release build (lintVital gates on fatal issues only). -->
<issue id="ExpiredTargetSdkVersion" severity="warning"/>

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

Please remove this. There is a reason why we stay at this particular SDK version, and having a warning just pollutes the log.

Comment thread android/BOINC/app/build.gradle.kts Outdated
}
}

fileTree("src/main/java") { include("**/*.java", "**/*.kt") }.forEach { source ->

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

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

There is no a single *.java file left in the projct, so could be safely removed

@github-project-automation github-project-automation Bot moved this from In progress to Review in progress in Client/Manager Jul 29, 2026
@AenBleidd
AenBleidd requested a review from Copilot July 29, 2026 00:16

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

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

Pull request overview

Migrates the Android Gradle build configuration from Groovy scripts to Kotlin DSL equivalents to improve type-safety and maintainability while aiming to preserve existing tasks/variants/behavior, and updates Android lint configuration to keep an expired targetSdk check visible without failing builds.

Changes:

  • Converted settings.gradle/build.gradle/app/build.gradle to Kotlin DSL (*.gradle.kts) while keeping the same task wiring (including ARMv6 asset stripping + verification guards).
  • Reimplemented existing helper logic (version derivation, resource/asset validation, Jacoco report task) as typed Kotlin functions and task configuration.
  • Added/updated lint.xml to warn (not fail) on ExpiredTargetSdkVersion and continue ignoring MissingTranslation.

Reviewed changes

Copilot reviewed 7 out of 7 changed files in this pull request and generated 2 comments.

Show a summary per file
File Description
android/BOINC/settings.gradle.kts Kotlin DSL replacement for settings script; keeps refreshVersions bootstrap.
android/BOINC/settings.gradle Removed Groovy settings script after migration.
android/BOINC/build.gradle.kts Kotlin DSL replacement for top-level buildscript repos/deps and jacoco aggregator task.
android/BOINC/build.gradle Removed Groovy top-level build script after migration.
android/BOINC/app/build.gradle.kts Kotlin DSL replacement for app module build, helper functions, ARMv6 asset stripping/guards, and Jacoco report task.
android/BOINC/app/build.gradle Removed Groovy app module build script after migration.
android/BOINC/app/lint.xml Adjusted lint severities to keep expired targetSdk visible as warning and ignore MissingTranslation.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +343 to +352
tasks.withType<MergeSourceSetFolders>().configureEach {
if (name.matches(Regex("mergeArmv6_(release|debug)Assets"))) {
val mergedAssetsDir = outputDir
doLast {
delete(fileTree(mergedAssetsDir) {
include("**/arm64-v8a/*", "**/armeabi-v7a/*", "**/x86/*", "**/x86_64/*")
})
}
}
}
Comment on lines +87 to +98
fun parseStringResources(xmlFile: File): Map<String, String> {
val root = DocumentBuilderFactory.newInstance().newDocumentBuilder().parse(xmlFile).documentElement
val strings = linkedMapOf<String, String>()
var node = root.firstChild
while (node != null) {
if (node is Element && node.tagName == "string") {
strings[node.getAttribute("name")] = node.textContent
}
node = node.nextSibling
}
return strings
}
@pmclSF
pmclSF force-pushed the android-gradle-kts branch from dcf8bad to 19d8d6d Compare July 29, 2026 00:58
@AenBleidd

Copy link
Copy Markdown
Member

@pmclSF, please check my comments above.
Thank you in advance.

- Convert settings.gradle, build.gradle, and app/build.gradle to their
  Kotlin DSL (.kts) equivalents; the native client build is unchanged
- Same tasks, variants, and behavior; the armv6 asset stripping and its
  verification guards carry over unchanged
- Helper logic (version code/name from git, string resource validation,
  asset checks) becomes typed Kotlin functions
- lint.xml: ignore ExpiredTargetSdkVersion. The check never fired under
  Groovy because lint does not recognize the space-assignment declaration
  form; it is fatal by default and staying at this targetSdk is
  intentional, so silence it to keep lintVital passing

Fixes BOINC#6923

Assisted-by: Claude Code:claude-fable-5
@pmclSF
pmclSF force-pushed the android-gradle-kts branch from 19d8d6d to ba41570 Compare August 2, 2026 03:27
@pmclSF

pmclSF commented Aug 2, 2026

Copy link
Copy Markdown
Contributor Author

I've addressed both comments. The Java include pattern is removed from the string validation scan. For lint.xml, I changed ExpiredTargetSdkVersion to "ignore" rather than deleting the entry: the check is fatal by default and only started firing with the Kotlin DSL script, so without the entry lintVital fails the release build.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Projects

Status: Review in progress

Development

Successfully merging this pull request may close these issues.

Migrate build.gradle from Groovy to Kotlin

3 participants