Small plugins to reduce boilerplate in Gradle build scripts.
⚠️ It is designed to use with Gradle Kotlin DSL and can't be used from Groovy DSL.
If you're planning to use android plugins, add Google repository to settings.gradle.kts
:
pluginManagement {
repositories {
google() // Required if you use infrastructure-android
gradlePluginPortal()
}
}
Then you can apply any of plugins where you need:
plugins {
id("com.redmadrobot.kotlin-library") version "0.17"
id("com.redmadrobot.publish") version "0.17"
id("com.redmadrobot.detekt") version "0.17"
id("com.redmadrobot.application") version "0.17"
id("com.redmadrobot.android-library") version "0.17"
}
If you want to configure subprojects from root project, you can apply *-config
plugins to root project.
This way subprojects will use configs from parent projects as defaults.
./build.gradle.kts
:
plugins {
id("com.redmadrobot.android-config")
}
redmadrobot {
android {
minSdk.set(28)
}
}
./app/build/build.gradle.kts
:
plugins {
id("com.redmadrobot.application")
}
// Will be used minSdk = 28 by default
android {
// ...
}
Look at samples for quick start.
Common configurations for pure Kotlin libraries.
- Applies plugin
kotlin
- Specifies
jvmTarget
1.8 - Adds repository
mavenCentral
(see Automatically added repositories) - Enables explicit API mode
Common publish configurations for both Android and Kotlin libraries.
- Applies plugin
maven-publish
- Adds sources and javadocs to publication
You should specify publishing repositories manually. You can also use predicates for publication:
publishing {
repositories {
// Unconditional publication
rmrNexus()
// Publication with conditions
if (isRunningOnCi) githubPackages("RedMadRobot/gradle-infrastructure")
if (isReleaseVersion && credentialsExist("ossrh")) ossrh()
}
}
You can configure publication via extension redmadrobot.publishing
:
redmadrobot {
publishing {
signArtifacts.set(true) // Enables artifacts signing, required for publication to OSSRH
useGpgAgent.set(true) // By default use gpg-agent for artifacts signing
}
}
Read more about singing configuration in Signing Plugin docs.
You can configure POM properties common for all modules.
Note: there are extension-functions to simplify common configuration use-cases. All available extensions you can find here.
redmadrobot {
publishing {
pom {
// Configure <url>, <scm> and <issueManagement> tags for GitHub project by it's name
setGitHubProject("RedMadRobot/gradle-infrastructure")
licenses {
mit() // Add MIT license
}
developers {
// Shorthand to add a developer
developer(id = "j.doe", name = "John Doe", email = "john@doe.com")
}
}
}
}
Use publishing
extension in module build script to configure publication for the single module.
Take publication name from PUBLICATION_NAME
constant.
Read more in Maven Publish plugin docs.
publishing {
publications {
getByName<MavenPublication>(PUBLICATION_NAME) {
// Configure publication here
}
}
}
// or even shorter
publishing.publications.getByName<MavenPublication>(PUBLICATION_NAME) {
// Configure publication here
}
- Adds repository
mavenCentral
(see Automatically added repositories) - Applies
detekt
plugin withdetekt-formatting
- Configures additional tasks:
detektAll
- Runs Detekt over the whole codebasedetektBaselineAll
Creates single baseline file in the config directory with issues from thedetektAll
task.detektFormat
- Reformats the whole codebase with DetektdetektDiff
- Runs Detekt only on changed files (see Enable Detekt checks only on changed files)detekt[Variant]All
- Runs Detekt checks with type resolution on specified build variant (exampledetektDebugAll
) or main source set (detektMainAll
) if project is non-androiddetektBaseline[Variant]All
Creates single baseline file in the config directory with issues from thedetekt[Variant]All
task.
⚠️ onlydetekt[Variant]All
tasks are compatible with type resolution.
Common configurations for Android libraries and application.
Both:
- Specifies
jvmTarget
andcompatibility
1.8 - Specifies default compile, min and target SDK
- Disables
aidl
,renderScript
andshaders
build-features - Adds repositories
mavenCentral
andgoogle
(see Automatically added repositories) - Applies android-cache-fix-gradle-plugin
Library:
- Applies plugin
com.android.library
- Adds all proguard files from
proguard
folder asconsumerProguardFiles
- Disables
buildConfig
,androidResources
andresValues
build-features - Enables explicit API mode
Application:
- Applies plugin
com.android.application
- Adds all proguard files from
proguard
folder - Configures
debug
,qa
andrelease
build types - Adds
LOCK_ORIENTATION
andCRASH_REPORTS_ENABLED
BuildConfig variables whichfalse
only fordebug
build type - Configures Android Lint default options
By default, for QA builds used name "qa", but you can configure BUILD_TYPE_QA
via gradle.properties
:
# Override QA build type name
redmadrobot.android.build.type.qa=staging
You can configure the plugins with an extension named redmadrobot
.
Look for available properties with description in RedmadrobotExtension.
The extension should be configured in root project.
// root project build.gradle.kts
redmadrobot {
configsDir.set(file("path/to/configs/"))
}
It is not a part of gradle-infrastructure but it is important to know.
To align the Kotlin version for all dependencies including transitive ones, use kotlin-bom
:
dependencies {
// Align versions of all Kotlin components
implementation(platform(kotlin("bom", version = "1.6.10")))
// Now you can add Kotlin components without version
implementation(kotlin("stdlib-jdk8"))
testImplementation(kotlin("test-junit5"))
}
Another way is using kotlin.coreLibrariesVersion
property:
// Set version for all Kotlin components
kotlin.coreLibrariesVersion = "1.6.10"
dependencies {
// Now you can add Kotlin components without version
implementation(kotlin("stdlib-jdk8"))
testImplementation(kotlin("test-junit5"))
}
By default, infrastructure plugins enable Kotlin compiler's option allWarningsAsErrors
(-Werror
) on CI.
You can change it by defining the warningsAsErrors
project property.
Read more about Gradle project properties
You can share sources between two build types.
For example, you need to use debug panel in both debug and QA builds, and don't want to write similar duplicating code for each of these build types.
You can do it with one line with addSharedSourceSetRoot extension-function:
android {
// We need to share sources between debug and QA builds
addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA)
// We can specify name for the source set root if need
addSharedSourceSetRoot(BUILD_TYPE_DEBUG, BUILD_TYPE_QA, name = "debugPanel")
}
Plugin com.redmadrobot.detekt
adds task detektDiff
to check the only files changed comparing to the base branch.
To enable this feature, you should specify base branch name:
redmadrobot {
detekt {
checkOnlyDiffWithBranch("develop")
}
}
The plugin then adds a detektDiff
task that allows you to check only changed files comparing to the specified base branch.
The modified files are provided by Git.
Task
detektDiff
is incompatible with type resolution. It means some configured rules will not work.
The detektDiff
task includes the '.kt' and '.kts' files.
You can change it by providing a set of extensions in the configuration block to checkOnlyDiffWithBranch
:
redmadrobot {
detekt {
checkOnlyDiffWithBranch("develop") {
fileExtensions = setOf(".kt")
}
}
}
By default, the plugin uses the JUnit Platform to run tests.
If you want to configure it, for example include an engine, you can do it using the test
extension for both JVM and android.
redmadrobot {
test {
useJunitPlatform {
includeEngines("spek2")
}
}
android {
test {
useJunitPlatform {
includeEngines("spek2")
}
}
}
}
If you want to use JUnit 4 framework to run tests, you need to specify useJunit()
in test block.
redmadrobot {
test {
useJunit()
}
}
Infrastructure plugins automatically add repositories required to make project work:
- kotlin plugin adds
mavenCentral
repo - detekt plugin adds
mavenCentral
repo - android plugins add
mavenCentral
andgoogle
repos
In the case you don't want these repositories to be added automatically, you can disable this behavior via flag in gradle.properties
:
redmadrobot.add.repositories=false
Look for samples in samples package.
If you need closer to life samples, check these projects:
- mapmemory - Multi module, kotlin library, publication, detekt
- itemsadapter - Multi module, android library, publication, detekt
- redmadrobot-android-ktx - Multi module, android library, publication, detekt
- infrastructure - Gradle plugin, publication
A problem was found with the configuration of task ':mylib:generateReleaseUnitTestStubRFile' (type 'GenerateLibraryRFileTask').
> No value has been specified for property 'localResourcesFile'.
It is a known bug in AGP 4.1.0 caused when androidResources
is disabled.
As workaround, you can enable this build feature for module:
android {
// TODO: Remove when bug in AGP will be fixed.
// https://issuetracker.google.com/issues/161586464
buildFeatures.androidResources = true
}
Execution failed for task ':app:processDebugResources'.
> A failure occurred while executing com.android.build.gradle.internal.tasks.Workers$ActionFacade
> Android resource linking failed
AAPT: error: resource style/TextAppearance.App.Headline4 (aka com.example.app.debug:style/TextAppearance.App.Headline4) not found.
error: resource style/TextAppearance.App.Body2 (aka com.example.app.debug:style/TextAppearance.App.Body2) not found.
error: resource style/Theme.App (aka com.example.app.debug:style/Theme.App) not found.
error: resource style/Theme.App (aka com.example.app.debug:style/Theme.App) not found.
error: failed linking references.
Build feature androidResources
is disabled by default for android libraries.
If you get these errors you should enable it:
android {
buildFeatures.androidResources = true
}
Execution failed for task ':app:stripDebugDebugSymbols'.
> No version of NDK matched the requested version 21.0.6113669. Versions available locally: 21.1.6352462
It is because NDK version on CI differs from a requested version.
You can change requested version by setting android.ndkVersion
.
Plugins com.redmadrobot.android-library
and com.redmadrobot.application
by default apply NDK version from env variable ANDROID_NDK_VERSION
if it set.
> Could not resolve all files for configuration ':app:debugRuntimeClasspath'.
> Could not find com.xwray:groupie:2.7.2
Searched in the following locations:
- ...
Required by:
project :app > com.xwray:groupie:2.7.2
It may be because of gradle-infrastructure
uses mavenCentral
instead of jcenter
by default.
JCenter is at the end of life and should not be used anymore.
Unfortunately not all libraries migrated to Maven Central yet.
To avoid these errors, declare jcenter
repository in your build script and configure it to be used only for missing dependencies.
repositories {
jcenter {
content {
// It is useful to add a link to the issue about migration from JCenter
// https://github.com/lisawray/groupie/issues/384
includeModule("com.xwray", "groupie")
}
}
}
Merge requests are welcome. For major changes, please open an issue first to discuss what you would like to change.