From 6c1e41ba1050c92f4b615f7e857e0d085120a242 Mon Sep 17 00:00:00 2001 From: Harsh Shandilya Date: Fri, 16 Oct 2020 20:48:11 +0530 Subject: [PATCH] Revamp build configuration (#1156) * release: move scripts to scripts directory Signed-off-by: Harsh Shandilya * Move CI secrets to secrets directory Signed-off-by: Harsh Shandilya * gradle: uprev to 6.7 Signed-off-by: Harsh Shandilya * gradle: suppress warnings about unsupported options Signed-off-by: Harsh Shandilya * build: update dependencies Signed-off-by: Harsh Shandilya * build: move Gradle plugins to ext Signed-off-by: Harsh Shandilya * build: move configuration tasks to buildSrc Signed-off-by: Harsh Shandilya * CHANGELOG: add entry for #1137 Signed-off-by: Harsh Shandilya * Fix lint warnings Signed-off-by: Harsh Shandilya --- .github/workflows/deploy_snapshot.yml | 6 +- .github/workflows/release.yml | 4 +- .gitignore | 3 +- CHANGELOG.md | 1 + app/build.gradle.kts | 16 ++-- .../main/res/layout/oreo_autofill_dataset.xml | 3 +- .../res/layout/oreo_autofill_filter_row.xml | 4 +- autofill-parser/build.gradle.kts | 6 +- build.gradle.kts | 66 ++------------ buildSrc/build.gradle.kts | 21 ++++- buildSrc/buildDependencies.gradle | 11 +++ buildSrc/src/main/java/BaseProjectConfig.kt | 83 ++++++++++++++++++ .../main/java/BinaryCompatibilityValidator.kt | 16 ++++ buildSrc/src/main/java/Dependencies.kt | 15 +--- buildSrc/src/main/java/KotlinCompilerArgs.kt | 8 ++ buildSrc/src/main/java/PasswordStorePlugin.kt | 44 ++++++++++ gradle.properties | 4 +- gradle/wrapper/gradle-wrapper.properties | 4 +- {release => scripts}/deploy-snapshot.sh | 0 {release => scripts}/encrypt-secret.sh | 0 {release => scripts}/signing-cleanup.sh | 0 {release => scripts}/signing-setup.sh | 4 +- {release => secrets}/keystore.cipher | Bin {release => secrets}/props.cipher | Bin 24 files changed, 222 insertions(+), 97 deletions(-) create mode 100644 buildSrc/buildDependencies.gradle create mode 100644 buildSrc/src/main/java/BaseProjectConfig.kt create mode 100644 buildSrc/src/main/java/BinaryCompatibilityValidator.kt create mode 100644 buildSrc/src/main/java/KotlinCompilerArgs.kt create mode 100644 buildSrc/src/main/java/PasswordStorePlugin.kt rename {release => scripts}/deploy-snapshot.sh (100%) rename {release => scripts}/encrypt-secret.sh (100%) rename {release => scripts}/signing-cleanup.sh (100%) rename {release => scripts}/signing-setup.sh (76%) rename {release => secrets}/keystore.cipher (100%) rename {release => secrets}/props.cipher (100%) diff --git a/.github/workflows/deploy_snapshot.yml b/.github/workflows/deploy_snapshot.yml index c31bbb78..272a0738 100644 --- a/.github/workflows/deploy_snapshot.yml +++ b/.github/workflows/deploy_snapshot.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v2 - name: Decrypt secrets - run: release/signing-setup.sh "$ENCRYPT_KEY" + run: scripts/signing-setup.sh "$ENCRYPT_KEY" env: ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }} @@ -28,10 +28,10 @@ jobs: arguments: :app:assembleFreeRelease :app:assembleNonFreeRelease - name: Clean secrets - run: release/signing-cleanup.sh + run: scripts/signing-cleanup.sh - name: Deploy snapshot - run: release/deploy-snapshot.sh + run: scripts/deploy-snapshot.sh env: ACTIONS_DEPLOY_KEY: ${{ secrets.ACTIONS_DEPLOY_KEY }} SSH_USERNAME: ${{ secrets.SSH_USERNAME }} diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index 521f7af1..8a8a3244 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -13,7 +13,7 @@ jobs: uses: actions/checkout@v2 - name: Decrypt secrets - run: release/signing-setup.sh "$ENCRYPT_KEY" + run: scripts/signing-setup.sh "$ENCRYPT_KEY" env: ENCRYPT_KEY: ${{ secrets.ENCRYPT_KEY }} @@ -45,7 +45,7 @@ jobs: - name: Clean secrets if: always() - run: release/signing-cleanup.sh + run: scripts/signing-cleanup.sh create_github_release: name: Create GitHub Release diff --git a/.gitignore b/.gitignore index 5e3a6720..bc49e503 100644 --- a/.gitignore +++ b/.gitignore @@ -1,4 +1,3 @@ - # Created by https://www.gitignore.io/api/androidstudio,gradle # Edit at https://www.gitignore.io/?templates=androidstudio,gradle @@ -44,7 +43,7 @@ out/ # Signing files .signing/ -keystore.* +/keystore.* # Local configuration file (sdk path, etc) local.properties diff --git a/CHANGELOG.md b/CHANGELOG.md index 508b409a..05b036ea 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -14,6 +14,7 @@ All notable changes to this project will be documented in this file. - Add GPG key selection step to onboarding flow - Allow configuring an app-wide HTTP(S) proxy +- Add option to automatically sync repository on app launch ## [1.12.1] - 2020-10-13 diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a5a3b4c9..150a16ef 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -6,7 +6,9 @@ import com.android.build.gradle.internal.api.BaseVariantOutputImpl import java.util.Properties plugins { + id("com.android.application") kotlin("android") + `aps-plugin` } val keystorePropertiesFile = rootProject.file("keystore.properties") @@ -26,13 +28,16 @@ android { adbOptions.installOptions("--user 0") - buildFeatures.viewBinding = true - buildFeatures.buildConfig = true + buildFeatures { + viewBinding = true + buildConfig = true + } defaultConfig { applicationId = "dev.msfjarvis.aps" versionCode = 11211 versionName = "1.13.0-SNAPSHOT" + testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" } lintOptions { @@ -41,13 +46,6 @@ android { disable("MissingTranslation", "PluralsCandidate", "ImpliedQuantity") } - packagingOptions { - exclude("**/*.version") - exclude("**/*.txt") - exclude("**/*.kotlin_module") - exclude("**/plugin.properties") - } - buildTypes { named("release") { isMinifyEnabled = true diff --git a/app/src/main/res/layout/oreo_autofill_dataset.xml b/app/src/main/res/layout/oreo_autofill_dataset.xml index 5b828712..2e9f48b9 100644 --- a/app/src/main/res/layout/oreo_autofill_dataset.xml +++ b/app/src/main/res/layout/oreo_autofill_dataset.xml @@ -4,6 +4,7 @@ --> + app:layout_constraintTop_toTopOf="parent" + app:tint="?colorOnPrimary" /> by extra repositories { google() jcenter() @@ -14,64 +12,14 @@ buildscript { maven { url = uri("https://kotlin.bintray.com/kotlinx") } } dependencies { - classpath(Plugins.agp) - classpath(Plugins.binaryCompatibilityValidator) - classpath(Plugins.kotlin) + classpath(build.getValue("androidGradlePlugin")) + classpath(build.getValue("binaryCompatibilityValidator")) + classpath(build.getValue("kotlinGradlePlugin")) } } plugins { id("com.github.ben-manes.versions") version "0.33.0" -} - -apply(plugin = "binary-compatibility-validator") - -extensions.configure { - ignoredProjects = mutableSetOf( - "app" - ) -} - -subprojects { - repositories { - google() - jcenter() - maven { - setUrl("https://jitpack.io") - } - } - if (name == "app") { - apply(plugin = "com.android.application") - } else { - apply(plugin = "com.android.library") - } - configure { - compileSdkVersion(29) - defaultConfig { - minSdkVersion(23) - targetSdkVersion(29) - testInstrumentationRunner = "androidx.test.runner.AndroidJUnitRunner" - } - compileOptions { - sourceCompatibility = JavaVersion.VERSION_1_8 - targetCompatibility = JavaVersion.VERSION_1_8 - } - tasks.withType { - options.compilerArgs.add("-Xlint:unchecked") - options.isDeprecation = true - } - } - tasks.withType { - kotlinOptions { - jvmTarget = "1.8" - freeCompilerArgs = listOf("-Xopt-in=kotlin.RequiresOptIn", "-Xallow-result-return-type") - languageVersion = "1.4" - } - } -} - -tasks.wrapper { - gradleVersion = "6.6.1" - distributionType = Wrapper.DistributionType.ALL - distributionSha256Sum = "11657af6356b7587bfb37287b5992e94a9686d5c8a0a1b60b87b9928a2decde5" + `binary-compatibility-validator` + `aps-plugin` } diff --git a/buildSrc/build.gradle.kts b/buildSrc/build.gradle.kts index 3457e2c2..2c721629 100644 --- a/buildSrc/build.gradle.kts +++ b/buildSrc/build.gradle.kts @@ -1,11 +1,30 @@ +apply(from = "buildDependencies.gradle") +val build: Map by extra + plugins { `kotlin-dsl` } repositories { - jcenter() + google() + gradlePluginPortal() } kotlinDslPluginOptions { experimentalWarning.set(false) } + +gradlePlugin { + plugins { + register("aps") { + id = "aps-plugin" + implementationClass = "PasswordStorePlugin" + } + } +} + +dependencies { + implementation(build.getValue("kotlinGradlePlugin")) + implementation(build.getValue("androidGradlePlugin")) + implementation(build.getValue("binaryCompatibilityValidator")) +} diff --git a/buildSrc/buildDependencies.gradle b/buildSrc/buildDependencies.gradle new file mode 100644 index 00000000..d9b2bbb7 --- /dev/null +++ b/buildSrc/buildDependencies.gradle @@ -0,0 +1,11 @@ +rootProject.ext.versions = [ + agp : '4.1.0', + kotlin : '1.4.10', + binary_compatibility_validator : '0.2.3', +] + +rootProject.ext.build = [ + androidGradlePlugin : "com.android.tools.build:gradle:${versions.agp}", + kotlinGradlePlugin : "org.jetbrains.kotlin:kotlin-gradle-plugin:${versions.kotlin}", + binaryCompatibilityValidator : "org.jetbrains.kotlinx:binary-compatibility-validator:${versions.binary_compatibility_validator}", +] diff --git a/buildSrc/src/main/java/BaseProjectConfig.kt b/buildSrc/src/main/java/BaseProjectConfig.kt new file mode 100644 index 00000000..3b2a3f3b --- /dev/null +++ b/buildSrc/src/main/java/BaseProjectConfig.kt @@ -0,0 +1,83 @@ +/* + * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +import com.android.build.gradle.TestedExtension +import org.gradle.api.JavaVersion +import org.gradle.api.Project +import org.gradle.api.tasks.Delete +import org.gradle.api.tasks.testing.Test +import org.gradle.api.tasks.testing.logging.TestLogEvent +import org.gradle.api.tasks.wrapper.Wrapper +import org.gradle.kotlin.dsl.repositories +import org.gradle.kotlin.dsl.withType +import org.jetbrains.kotlin.gradle.tasks.KotlinCompile + +/** + * Configure root project. + * Note that classpath dependencies still need to be defined in the `buildscript` block in the top-level build.gradle.kts file. + */ +internal fun Project.configureForRootProject() { + // register task for cleaning the build directory in the root project + tasks.register("clean", Delete::class.java) { + delete(rootProject.buildDir) + } + tasks.withType { + gradleVersion = "6.7" + distributionType = Wrapper.DistributionType.ALL + distributionSha256Sum = "0080de8491f0918e4f529a6db6820fa0b9e818ee2386117f4394f95feb1d5583" + } + configureBinaryCompatibilityValidator() +} + +/** + * Configure all projects including the root project + */ +internal fun Project.configureForAllProjects() { + repositories { + google() + jcenter() + maven { setUrl("https://jitpack.io") } + } + tasks.withType { + kotlinOptions { + jvmTarget = JavaVersion.VERSION_1_8.toString() + freeCompilerArgs = freeCompilerArgs + additionalCompilerArgs + languageVersion = "1.4" + } + } + tasks.withType { + maxParallelForks = Runtime.getRuntime().availableProcessors() * 2 + testLogging { + events(TestLogEvent.PASSED, TestLogEvent.SKIPPED, TestLogEvent.FAILED) + } + } +} + +/** + * Apply baseline configurations for all Android projects (Application and Library). + */ +@Suppress("UnstableApiUsage") +internal fun TestedExtension.configureCommonAndroidOptions() { + compileSdkVersion(29) + + defaultConfig { + minSdkVersion(23) + targetSdkVersion(29) + } + + packagingOptions { + exclude("**/*.version") + exclude("**/*.txt") + exclude("**/*.kotlin_module") + exclude("**/plugin.properties") + } + + compileOptions { + sourceCompatibility = JavaVersion.VERSION_1_8 + targetCompatibility = JavaVersion.VERSION_1_8 + } + + testOptions.animationsDisabled = true +} diff --git a/buildSrc/src/main/java/BinaryCompatibilityValidator.kt b/buildSrc/src/main/java/BinaryCompatibilityValidator.kt new file mode 100644 index 00000000..b622513c --- /dev/null +++ b/buildSrc/src/main/java/BinaryCompatibilityValidator.kt @@ -0,0 +1,16 @@ +/* + * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +import kotlinx.validation.ApiValidationExtension +import org.gradle.api.Project +import org.gradle.kotlin.dsl.configure + +internal fun Project.configureBinaryCompatibilityValidator() { + extensions.configure { + ignoredProjects = mutableSetOf( + "app" + ) + } +} diff --git a/buildSrc/src/main/java/Dependencies.kt b/buildSrc/src/main/java/Dependencies.kt index 0f8c903d..715ec811 100644 --- a/buildSrc/src/main/java/Dependencies.kt +++ b/buildSrc/src/main/java/Dependencies.kt @@ -5,13 +5,6 @@ private const val KOTLIN_VERSION = "1.4.10" -object Plugins { - - const val agp = "com.android.tools.build:gradle:4.0.2" - const val binaryCompatibilityValidator = "org.jetbrains.kotlinx:binary-compatibility-validator:0.2.3" - const val kotlin = "org.jetbrains.kotlin:kotlin-gradle-plugin:$KOTLIN_VERSION" -} - object Dependencies { object Kotlin { object Coroutines { @@ -28,7 +21,7 @@ object Dependencies { const val activity_ktx = "androidx.activity:activity-ktx:1.2.0-beta01" const val annotation = "androidx.annotation:annotation:1.1.0" - const val autofill = "androidx.autofill:autofill:1.1.0-alpha02" + const val autofill = "androidx.autofill:autofill:1.1.0-beta01" const val appcompat = "androidx.appcompat:appcompat:1.3.0-alpha02" const val biometric = "androidx.biometric:biometric:1.1.0-beta01" const val constraint_layout = "androidx.constraintlayout:constraintlayout:2.0.2" @@ -38,7 +31,7 @@ object Dependencies { const val lifecycle_common = "androidx.lifecycle:lifecycle-common-java8:$lifecycleVersion" const val lifecycle_livedata_ktx = "androidx.lifecycle:lifecycle-livedata-ktx:$lifecycleVersion" const val lifecycle_viewmodel_ktx = "androidx.lifecycle:lifecycle-viewmodel-ktx:$lifecycleVersion" - const val material = "com.google.android.material:material:1.3.0-alpha02" + const val material = "com.google.android.material:material:1.3.0-alpha03" const val preference = "androidx.preference:preference:1.1.1" const val recycler_view = "androidx.recyclerview:recyclerview:1.2.0-alpha06" const val recycler_view_selection = "androidx.recyclerview:recyclerview-selection:1.1.0-rc03" @@ -72,12 +65,12 @@ object Dependencies { object NonFree { - const val google_play_auth_api_phone = "com.google.android.gms:play-services-auth-api-phone:17.4.0" + const val google_play_auth_api_phone = "com.google.android.gms:play-services-auth-api-phone:17.5.0" } object Testing { - const val junit = "junit:junit:4.13" + const val junit = "junit:junit:4.13.1" const val kotlin_test_junit = "org.jetbrains.kotlin:kotlin-test-junit:$KOTLIN_VERSION" object AndroidX { diff --git a/buildSrc/src/main/java/KotlinCompilerArgs.kt b/buildSrc/src/main/java/KotlinCompilerArgs.kt new file mode 100644 index 00000000..b4931917 --- /dev/null +++ b/buildSrc/src/main/java/KotlinCompilerArgs.kt @@ -0,0 +1,8 @@ +/* + * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +internal val additionalCompilerArgs = listOf( + "-Xopt-in=kotlin.RequiresOptIn" +) diff --git a/buildSrc/src/main/java/PasswordStorePlugin.kt b/buildSrc/src/main/java/PasswordStorePlugin.kt new file mode 100644 index 00000000..37a23b02 --- /dev/null +++ b/buildSrc/src/main/java/PasswordStorePlugin.kt @@ -0,0 +1,44 @@ +/* + * Copyright © 2014-2020 The Android Password Store Authors. All Rights Reserved. + * SPDX-License-Identifier: GPL-3.0-only + */ + +import com.android.build.gradle.TestedExtension +import com.android.build.gradle.internal.plugins.AppPlugin +import com.android.build.gradle.internal.plugins.LibraryPlugin +import org.gradle.api.Plugin +import org.gradle.api.Project +import org.gradle.api.plugins.JavaLibraryPlugin +import org.gradle.api.plugins.JavaPlugin +import org.gradle.api.tasks.compile.JavaCompile +import org.gradle.kotlin.dsl.getByType +import org.gradle.kotlin.dsl.withType + +class PasswordStorePlugin : Plugin { + + override fun apply(project: Project) { + project.configureForAllProjects() + + if (project.isRoot) { + project.configureForRootProject() + } + + project.plugins.all { + when (this) { + is JavaPlugin, + is JavaLibraryPlugin -> { + project.tasks.withType { + options.compilerArgs.add("-Xlint:unchecked") + options.isDeprecation = true + } + } + is LibraryPlugin, + is AppPlugin -> { + project.extensions.getByType().configureCommonAndroidOptions() + } + } + } + } +} + +private val Project.isRoot get() = this == this.rootProject diff --git a/gradle.properties b/gradle.properties index 99dc45a1..ced8321c 100644 --- a/gradle.properties +++ b/gradle.properties @@ -8,7 +8,6 @@ org.gradle.caching=true # Enabling filesystem watching org.gradle.vfs.watch=true -org.gradle.unsafe.watch-fs=true # Enable Kotlin incremental compilation kotlin.incremental=true @@ -49,3 +48,6 @@ android.defaults.buildfeatures.aidl=false android.defaults.buildfeatures.renderscript=false android.defaults.buildfeatures.resvalues=false android.defaults.buildfeatures.shaders=false + +# Disable warnings about unsupported features, we know what we're doing +android.suppressUnsupportedOptionWarnings=android.enableR8.fullMode,android.enableResourceOptimizations,android.nonTransitiveRClass,android.suppressUnsupportedOptionWarnings diff --git a/gradle/wrapper/gradle-wrapper.properties b/gradle/wrapper/gradle-wrapper.properties index 0e422340..99d667cc 100644 --- a/gradle/wrapper/gradle-wrapper.properties +++ b/gradle/wrapper/gradle-wrapper.properties @@ -1,6 +1,6 @@ distributionBase=GRADLE_USER_HOME distributionPath=wrapper/dists -distributionSha256Sum=11657af6356b7587bfb37287b5992e94a9686d5c8a0a1b60b87b9928a2decde5 -distributionUrl=https\://services.gradle.org/distributions/gradle-6.6.1-all.zip +distributionSha256Sum=0080de8491f0918e4f529a6db6820fa0b9e818ee2386117f4394f95feb1d5583 +distributionUrl=https\://services.gradle.org/distributions/gradle-6.7-all.zip zipStoreBase=GRADLE_USER_HOME zipStorePath=wrapper/dists diff --git a/release/deploy-snapshot.sh b/scripts/deploy-snapshot.sh similarity index 100% rename from release/deploy-snapshot.sh rename to scripts/deploy-snapshot.sh diff --git a/release/encrypt-secret.sh b/scripts/encrypt-secret.sh similarity index 100% rename from release/encrypt-secret.sh rename to scripts/encrypt-secret.sh diff --git a/release/signing-cleanup.sh b/scripts/signing-cleanup.sh similarity index 100% rename from release/signing-cleanup.sh rename to scripts/signing-cleanup.sh diff --git a/release/signing-setup.sh b/scripts/signing-setup.sh similarity index 76% rename from release/signing-setup.sh rename to scripts/signing-setup.sh index e930e04d..362ec583 100755 --- a/release/signing-setup.sh +++ b/scripts/signing-setup.sh @@ -4,8 +4,8 @@ set -e ENCRYPT_KEY=$1 declare -A SECRETS -SECRETS[release/keystore.cipher]=keystore.jks -SECRETS[release/props.cipher]=keystore.properties +SECRETS[secrets/keystore.cipher]=keystore.jks +SECRETS[secrets/props.cipher]=keystore.properties if [[ -n "$ENCRYPT_KEY" ]]; then for src in "${!SECRETS[@]}"; do diff --git a/release/keystore.cipher b/secrets/keystore.cipher similarity index 100% rename from release/keystore.cipher rename to secrets/keystore.cipher diff --git a/release/props.cipher b/secrets/props.cipher similarity index 100% rename from release/props.cipher rename to secrets/props.cipher