Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 23 additions & 0 deletions .github/ci-gradle.properties
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
#
# Copyright 2020 The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
#

org.gradle.daemon=false
org.gradle.parallel=true
org.gradle.jvmargs=-Xmx5120m
org.gradle.workers.max=2

kotlin.incremental=false
kotlin.compiler.execution.strategy=in-process
146 changes: 146 additions & 0 deletions .github/workflows/build_and_test.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,146 @@
name: Build and Test

on:
push:
branches: [ "main" ]
pull_request:
branches: [ "main" ]
workflow_dispatch:

# Ensure that only the latest commit is tested for PRs
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.sha }}
cancel-in-progress: true

permissions:
contents: write # Needed for git-auto-commit-action

jobs:
build_test_lint:
name: "Build, Test, and Lint"
runs-on: ubuntu-latest
timeout-minutes: 60

steps:
- name: Checkout code
uses: actions/checkout@v4

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4
# Add cache-encryption-key if you set up the GRADLE_ENCRYPTION_KEY secret
# with:
# cache-encryption-key: ${{ secrets.GRADLE_ENCRYPTION_KEY }}

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build debug APK
run: ./gradlew assembleDebug --no-configuration-cache

- name: Apply Spotless
run: ./gradlew spotlessApply --init-script gradle/init.gradle.kts --no-configuration-cache

- name: Commit Spotless changes
uses: stefanzweifel/git-auto-commit-action@v5
with:
commit_message: 🤖 Apply Spotless formatting
file_pattern: '**/*.kt **/*.kts **/*.java **/*.xml'

- name: Verify Screenshot Tests (AndroidX)
run: ./gradlew validateDebugScreenshotTest

- name: Run local unit tests
run: ./gradlew testDebugUnitTest

- name: Check lint
run: ./gradlew lintDebug

- name: Upload build outputs (APKs)
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: APKs
path: '**/build/outputs/apk/debug/*.apk'

- name: Upload JVM local test results (XML)
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: local-test-results
path: '**/build/test-results/test*UnitTest/TEST-*.xml'

- name: Upload lint reports (HTML)
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: lint-reports-html
path: '**/build/reports/lint-results-debug.html'

androidTest:
name: "Instrumentation Tests (emulator)"
runs-on: ubuntu-latest
timeout-minutes: 60
strategy:
matrix:
api-level: [26]

steps:
- name: Delete unnecessary tools 🔧
uses: jlumbroso/[email protected]
with:
android: false # Don't remove Android tools
tool-cache: true # Remove image tool cache
dotnet: true
haskell: true
swap-storage: true

- name: Enable KVM group perms
run: |
echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
sudo udevadm control --reload-rules
sudo udevadm trigger --name-match=kvm

- name: Checkout code
uses: actions/checkout@v4

- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties

- name: Set up JDK 17
uses: actions/setup-java@v4
with:
java-version: '17'
distribution: 'temurin'

- name: Setup Gradle
uses: gradle/actions/setup-gradle@v4

- name: Grant execute permission for gradlew
run: chmod +x gradlew

- name: Build
run: ./gradlew assembleDebug assembleDebugAndroidTest

- name: Build projects and run instrumentation tests
uses: reactivecircus/android-emulator-runner@v2
with:
api-level: ${{ matrix.api-level }}
arch: x86
disable-animations: true
disk-size: 6000M
heap-size: 600M
script: ./gradlew connectedDebugAndroidTest


- name: Upload test reports
if: ${{ !cancelled() }}
uses: actions/upload-artifact@v4
with:
name: test-reports-${{ matrix.api-level }}
path: '**/build/reports/androidTests'
2 changes: 1 addition & 1 deletion app/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -153,4 +153,4 @@ androidComponents {
beforeVariants { variantBuilder ->
variantBuilder.enableAndroidTest = false
}
}
}
3 changes: 2 additions & 1 deletion app/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
<?xml version="1.0" encoding="utf-8"?><!--
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2025 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
Expand Down
7 changes: 7 additions & 0 deletions core/network/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -50,6 +50,13 @@ android {
}
}

// Explicitly disable the connectedAndroidTest task for this module
androidComponents {
beforeVariants(selector().all()) { variant ->
variant.enableAndroidTest = false
}
}

dependencies {
implementation(libs.androidx.app.startup)
implementation(libs.kotlinx.serialization.json)
Expand Down
17 changes: 15 additions & 2 deletions core/network/src/main/AndroidManifest.xml
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,19 @@
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>

<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- Core Firebase App Initialization -->
<meta-data android:name="com.android.developers.androidify.startup.FirebaseAppInitializer"
android:value="androidx.startup" />
<!-- Other Firebase Initializers -->
<meta-data android:name="com.android.developers.androidify.startup.FirebaseAppCheckInitializer"
android:value="androidx.startup" />
<meta-data android:name="com.android.developers.androidify.startup.FirebaseRemoteConfigInitializer"
android:value="androidx.startup" />
</provider>
</application>
</manifest>
</manifest>
22 changes: 22 additions & 0 deletions core/network/src/main/res/xml/startup_initializers.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
<?xml version="1.0" encoding="utf-8"?>
<!--
Copyright 2025 The Android Open Source Project

Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at

https://www.apache.org/licenses/LICENSE-2.0

Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
-->
<resources xmlns:android="http://schemas.android.com/apk/res/android">
<initializer
android:name="com.android.developers.androidify.startup.FirebaseAppCheckInitializer" />
<initializer
android:name="com.android.developers.androidify.startup.FirebaseRemoteConfigInitializer" />
</resources>
7 changes: 7 additions & 0 deletions core/testing/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,13 @@ android {
}
}

// Explicitly disable the connectedAndroidTest task for this module
androidComponents {
beforeVariants(selector().all()) { variant ->
variant.enableAndroidTest = false
}
}

dependencies {
api(libs.kotlinx.coroutines.test)
implementation(platform(libs.androidx.compose.bom))
Expand Down
13 changes: 6 additions & 7 deletions core/util/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ android {

defaultConfig {
minSdk = libs.versions.minSdk.get().toInt()
testInstrumentationRunner = "com.android.developers.testing.AndroidifyTestRunner"
}

compileOptions {
Expand All @@ -38,6 +37,12 @@ android {
jvmTarget = libs.versions.jvmTarget.get()
}
}
// Explicitly disable the connectedAndroidTest task for this module
androidComponents {
beforeVariants(selector().all()) { variant ->
variant.enableAndroidTest = false
}
}

dependencies {
implementation(platform(libs.androidx.compose.bom))
Expand All @@ -51,12 +56,6 @@ dependencies {
implementation(libs.androidx.window.core)
ksp(libs.hilt.compiler)

androidTestImplementation(platform(libs.androidx.compose.bom))
androidTestImplementation(libs.androidx.ui.test.junit4)
androidTestImplementation(libs.hilt.android.testing)
androidTestImplementation(project(":core:testing")) // Add dependency
kspAndroidTest(libs.hilt.compiler)

// debugImplementation(libs.androidx.ui.tooling)
// debugImplementation(libs.androidx.ui.test.manifest)
}
12 changes: 6 additions & 6 deletions data/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,6 @@ android {

defaultConfig {
minSdk = libs.versions.minSdk.get().toInt()
testInstrumentationRunner = "com.android.developers.testing.AndroidifyTestRunner"
}

compileOptions {
Expand All @@ -38,6 +37,12 @@ android {
jvmTarget = libs.versions.jvmTarget.get()
}
}
// Explicitly disable the connectedAndroidTest task for this module
androidComponents {
beforeVariants(selector().all()) { variant ->
variant.enableAndroidTest = false
}
}

dependencies {
implementation(project(":core:network"))
Expand All @@ -55,9 +60,4 @@ dependencies {
exclude(group = "com.google.guava")
}
ksp(libs.hilt.compiler)

androidTestImplementation(libs.androidx.ui.test.junit4)
androidTestImplementation(libs.hilt.android.testing)
androidTestImplementation(project(":core:testing"))
kspAndroidTest(libs.hilt.compiler)
}
4 changes: 4 additions & 0 deletions feature/camera/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ plugins {
alias(libs.plugins.kotlin.compose)
alias(libs.plugins.kotlin.ksp)
alias(libs.plugins.hilt)
alias(libs.plugins.composeScreenshot)
}

android {
Expand All @@ -41,6 +42,8 @@ android {
compose = true
}

experimentalProperties["android.experimental.enableScreenshotTest"] = true

testOptions {
targetSdk = 36
}
Expand Down Expand Up @@ -82,4 +85,5 @@ dependencies {
kspAndroidTest(libs.hilt.compiler)

debugImplementation(libs.androidx.ui.test.manifest)
screenshotTestImplementation(libs.androidx.ui.tooling)
}
20 changes: 20 additions & 0 deletions feature/camera/src/androidTest/AndroidManifest.xml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:tools="http://schemas.android.com/tools">
<application>
<provider
android:name="androidx.startup.InitializationProvider"
android:authorities="${applicationId}.androidx-startup"
android:exported="false"
tools:node="merge">
<!-- Remove Firebase App Initialization for tests -->
<meta-data android:name="com.android.developers.androidify.startup.FirebaseAppInitializer"
tools:node="remove" />
<!-- Remove Other Firebase Initializers for tests -->
<meta-data android:name="com.android.developers.androidify.startup.FirebaseAppCheckInitializer"
tools:node="remove" />
<meta-data android:name="com.android.developers.androidify.startup.FirebaseRemoteConfigInitializer"
tools:node="remove" />
</provider>
</application>
</manifest>
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading