diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 8b899f17c1..dd94a31485 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -19,7 +19,7 @@ jobs: # ktlintCheck does not have per-variant tasks, so runs once over everything ktlint: name: ktlintCheck - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -34,7 +34,7 @@ jobs: # Tools are not per-variant tools: name: Test tools - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -50,7 +50,7 @@ jobs: # Custom lint rules are not per-variant custom-lint: name: Custom lint - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 @@ -74,7 +74,7 @@ jobs: store: [ "Fdroid", "Github", "Google" ] type: [ "Debug", "Release" ] name: Android Lint - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - name: Checkout @@ -112,9 +112,9 @@ jobs: matrix: color: ["orange"] store: [ "Fdroid", "Github", "Google" ] - type: [ "Debug", "Release" ] + type: [ "Debug" ] name: Android Test - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - name: Checkout @@ -127,15 +127,16 @@ jobs: - name: test ${{ matrix.color }}${{ matrix.store }}${{ matrix.type }} run: ./gradlew test${{ matrix.color }}${{ matrix.store }}${{ matrix.type }} - # Android assemble is per variant + # Android assemble is per variant. "Release" only in this job, "Debug" variants + # are assembled in the emulator tests. assemble: strategy: matrix: color: ["orange"] store: [ "Fdroid", "Github", "Google" ] - type: [ "Debug", "Release" ] + type: [ "Release" ] name: Android Assemble - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - name: Checkout @@ -158,12 +159,19 @@ jobs: api-level: [31] target: [default] name: Android Emulator Tests - runs-on: ubuntu-latest + runs-on: blacksmith-4vcpu-ubuntu-2404 steps: - name: Checkout uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6 + - uses: ./.github/actions/setup-build-env + with: + gradle-cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }} + + - name: assemble ${{ matrix.color }}${{ matrix.store }}${{ matrix.type }} + run: ./gradlew assemble${{ matrix.color }}${{ matrix.store }}${{ matrix.type }} + - name: Enable KVM run: | echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules diff --git a/build-logic/convention/src/main/kotlin/app/pachli/KotlinAndroid.kt b/build-logic/convention/src/main/kotlin/app/pachli/KotlinAndroid.kt index 9113c494e5..1912cb3611 100644 --- a/build-logic/convention/src/main/kotlin/app/pachli/KotlinAndroid.kt +++ b/build-logic/convention/src/main/kotlin/app/pachli/KotlinAndroid.kt @@ -21,6 +21,7 @@ import org.gradle.api.JavaVersion import org.gradle.api.Project import org.gradle.kotlin.dsl.assign import org.gradle.kotlin.dsl.dependencies +import org.gradle.kotlin.dsl.invoke import org.gradle.kotlin.dsl.provideDelegate import org.gradle.kotlin.dsl.withType import org.jetbrains.kotlin.gradle.dsl.JvmTarget @@ -55,6 +56,17 @@ internal fun Project.configureKotlinAndroid( // "Method myLooper in android.os.Looper not mocked" isReturnDefaultValues = true } + + // https://developer.android.com/studio/test/managed-devices + managedDevices { + localDevices { + create("pixel9api31") { + device = "Pixel 9 Pro XL" + apiLevel = 31 + systemImageSource = "aosp-atd" + } + } + } } buildFeatures { diff --git a/build.gradle.kts b/build.gradle.kts index 184c2eb33c..afea65a10a 100644 --- a/build.gradle.kts +++ b/build.gradle.kts @@ -61,3 +61,34 @@ subprojects { tasks.register("clean") { delete(layout.buildDirectory) } + +// Create a "precommit" lifecycle task that depends on other tasks that +// give reasonable confidence the change will pass CI. The tasks are +// limited to the "orangeGoogleDebug" flavour/variant. While problems +// might affect other combinations (and CI will check all of them), this +// combination passing gives high confidence for the amount of time it +// takes to run. +// +// - :app:lintOrangeGoogleDebug +// - *:testOrangeGoogleDebugUnitTest +// - :app:assembleOrangeDebug +// - *:pixel9api31orangegoogledebugAndroidTest +tasks.register("precommit") { + group = "Verification" + description = "Runs the precommit tests." + dependsOn(":app:lintOrangeGoogleDebug") + allprojects + .flatMap { it.tasks } + .filter { it.name.equals("testOrangeGoogleDebugUnitTest", ignoreCase = true) } + .forEach { + dependsOn(it.path) + } + dependsOn(":app:assembleOrangeGoogleDebug") + allprojects + .flatMap { it.tasks } + .filter { it.name.equals("pixel9api31OrangeGoogleDebugAndroidTest", ignoreCase = true) } + .forEach { + println("dep: $it.name") + dependsOn(it.path) + } +} diff --git a/checks/src/main/java/app/pachli/lint/checks/ContextCompatGetDrawableDetector.kt b/checks/src/main/java/app/pachli/lint/checks/ContextCompatGetDrawableDetector.kt index ce1eac94e3..0486f60145 100644 --- a/checks/src/main/java/app/pachli/lint/checks/ContextCompatGetDrawableDetector.kt +++ b/checks/src/main/java/app/pachli/lint/checks/ContextCompatGetDrawableDetector.kt @@ -62,7 +62,7 @@ class ContextCompatGetDrawableDetector : Detector(), SourceCodeScanner { issue = ISSUE, scope = node, location = context.getCallLocation(node, includeReceiver = true, includeArguments = true), - message = "Use AppCompatResources.getDrawable", + message = "Use `AppCompatResources`.getDrawable", quickfixData = fix, ) } @@ -75,7 +75,7 @@ class ContextCompatGetDrawableDetector : Detector(), SourceCodeScanner { id = "ContextCompatGetDrawableDetector", briefDescription = "Don't use `ContextCompat.getDrawable()`, use `AppCompatResources.getDrawable()`", explanation = """ - AppCompatResources().getDrawable() backports features and bug fixes, + `AppCompatResources().getDrawable()` backports features and bug fixes, ContextCompat.getDrawable() does not. See https://medium.com/@crafty/yes-contextcompat-just-saves-you-the-api-level-check-it-doesnt-back-port-and-features-or-bug-9cd7d5f09be4 """, diff --git a/checks/src/main/java/app/pachli/lint/checks/StringResourceEntityDetector.kt b/checks/src/main/java/app/pachli/lint/checks/StringResourceEntityDetector.kt index ce3894cbce..4e74d1aae8 100644 --- a/checks/src/main/java/app/pachli/lint/checks/StringResourceEntityDetector.kt +++ b/checks/src/main/java/app/pachli/lint/checks/StringResourceEntityDetector.kt @@ -315,7 +315,7 @@ class StringResourceEntityDetector : Detector(), SourceCodeScanner, OtherFileSca val ISSUE = Issue.create( id = "StringResourceEntityDetector", briefDescription = "`<` and `>` in string resources should use angle brackets", - explanation = "This string resource is passed to getText(), which expects HTML.", + explanation = "This string resource is passed to `getText()`, which expects HTML.", category = Category.CORRECTNESS, priority = 10, severity = Severity.WARNING,