Merge pull request #18 from gradle/sg/update-branch

Update with latest NiA main
pull/1445/head
Sterling Greene 1 year ago committed by GitHub
commit 62a20b56a7
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

@ -4,7 +4,6 @@ on:
push:
branches:
- main
- main-declarative
pull_request:
concurrency:
@ -23,24 +22,18 @@ jobs:
timeout-minutes: 60
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Checkout Declarative Gradle
uses: actions/checkout@v4
with:
repository: 'gradle/declarative-gradle'
ref: 'tt/declarative-no-conventions-nia'
path: 'declarative-gradle'
- name: Checkout Now in Android
uses: actions/checkout@v4
with:
repository: 'gradle/nowinandroid'
path: 'now-in-android'
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2
- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp now-in-android/.github/ci-gradle.properties ~/.gradle/gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
- name: Set up JDK 17
uses: actions/setup-java@v4
@ -52,15 +45,15 @@ jobs:
uses: gradle/gradle-build-action@v3
- name: Check build-logic
run: ./now-in-android/gradlew check -p now-in-android/build-logic
run: ./gradlew check -p build-logic
- name: Check spotless
run: ./now-in-android/gradlew spotlessCheck --init-script gradle/init.gradle.kts --no-configuration-cache -p now-in-android
run: ./gradlew spotlessCheck --init-script gradle/init.gradle.kts --no-configuration-cache
- name: Check Dependency Guard
id: dependencyguard_verify
continue-on-error: true
run: ./now-in-android/gradlew dependencyGuard -p now-in-android
run: ./gradlew dependencyGuard
- name: Prevent updating Dependency Guard baselines if this is a fork
id: checkfork_dependencyguard
@ -74,7 +67,7 @@ jobs:
id: dependencyguard_baseline
if: steps.dependencyguard_verify.outcome == 'failure' && github.event_name == 'pull_request'
run: |
./now-in-android/gradlew dependencyGuardBaseline -p now-in-android
./gradlew dependencyGuardBaseline
- name: Push new Dependency Guard baselines if available
uses: stefanzweifel/git-auto-commit-action@v5
@ -87,7 +80,7 @@ jobs:
- name: Run all local screenshot tests (Roborazzi)
id: screenshotsverify
continue-on-error: true
run: ./now-in-android/gradlew verifyRoborazziDemoDebug -p now-in-android
run: ./gradlew verifyRoborazziDemoDebug
- name: Prevent pushing new screenshots if this is a fork
id: checkfork_screenshots
@ -101,7 +94,7 @@ jobs:
id: screenshotsrecord
if: steps.screenshotsverify.outcome == 'failure' && github.event_name == 'pull_request'
run: |
./now-in-android/gradlew recordRoborazziDemoDebug -p now-in-android
./gradlew recordRoborazziDemoDebug
- name: Push new screenshots if available
uses: stefanzweifel/git-auto-commit-action@v5
@ -114,18 +107,17 @@ jobs:
# Run local tests after screenshot tests to avoid wrong UP-TO-DATE. TODO: Ignore screenshots.
- name: Run local tests and create report
if: always()
run: ./now-in-android/gradlew testDemoDebug :lint:test -p now-in-android
run: ./gradlew testDemoDebug :lint:test
# Replace task exclusions with `-Pandroidx.baselineprofile.skipgeneration` when
# https://android-review.googlesource.com/c/platform/frameworks/support/+/2602790 landed in a
# release build
- name: Build all build type and flavor permutations
run: ./now-in-android/gradlew :app:assemble :benchmarks:assemble
run: ./gradlew :app:assemble :benchmarks:assemble
-x pixel6Api33ProdNonMinifiedReleaseAndroidTest
-x pixel6Api33DemoNonMinifiedReleaseAndroidTest
-x collectDemoNonMinifiedReleaseBaselineProfile
-x collectProdNonMinifiedReleaseBaselineProfile
-p now-in-android
- name: Upload build outputs (APKs)
uses: actions/upload-artifact@v4
@ -140,8 +132,15 @@ jobs:
name: local-test-results
path: '**/build/test-results/test*UnitTest/**.xml'
- name: Upload screenshot results (PNG)
if: always()
uses: actions/upload-artifact@v4
with:
name: screenshot-test-results
path: '**/build/outputs/roborazzi/*_compare.png'
- name: Check lint
run: ./now-in-android/gradlew :app:lintProdRelease :app-nia-catalog:lintRelease :lint:lint -p now-in-android
run: ./gradlew :app:lintProdRelease :app-nia-catalog:lintRelease :lint:lint
- name: Upload lint reports (HTML)
if: always()
@ -151,7 +150,7 @@ jobs:
path: '**/build/reports/lint-results-*.html'
- name: Check badging
run: ./now-in-android/gradlew :app:checkProdReleaseBadging -p now-in-android
run: ./gradlew :app:checkProdReleaseBadging
androidTest:
runs-on: ubuntu-latest
@ -179,21 +178,15 @@ jobs:
sudo udevadm trigger --name-match=kvm
ls /dev/kvm
- name: Checkout
uses: actions/checkout@v4
- name: Checkout Declarative Gradle
uses: actions/checkout@v4
with:
repository: 'gradle/declarative-gradle'
ref: 'tt/declarative-no-conventions-nia'
path: 'declarative-gradle'
- name: Checkout Now in Android
uses: actions/checkout@v4
with:
repository: 'gradle/nowinandroid'
path: 'now-in-android'
- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp now-in-android/.github/ci-gradle.properties ~/.gradle/gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
- name: Set up JDK 17
uses: actions/setup-java@v4
@ -212,17 +205,17 @@ jobs:
disable-animations: true
disk-size: 6000M
heap-size: 600M
script: ./now-in-android/gradlew connectedDemoDebugAndroidTest --daemon -p now-in-android
script: ./gradlew connectedDemoDebugAndroidTest --daemon
- name: Run local tests (including Roborazzi) for the combined coverage report (only API 30)
if: matrix.api-level == 30
# There is no need to verify Roborazzi tests to generate coverage.
run: ./now-in-android/gradlew testDemoDebugUnitTest -Proborazzi.test.verify=false -p now-in-android # Add Prod if we ever add JVM tests for prod
run: ./gradlew testDemoDebugUnitTest -Proborazzi.test.verify=false # Add Prod if we ever add JVM tests for prod
# Add `createProdDebugUnitTestCoverageReport` if we ever add JVM tests for prod
- name: Generate coverage reports for Debug variants (only API 30)
if: matrix.api-level == 30
run: ./now-in-android/gradlew createDemoDebugCombinedCoverageReport -p now-in-android
run: ./gradlew createDemoDebugCombinedCoverageReport
- name: Upload test reports
if: always()

@ -18,23 +18,18 @@ jobs:
sudo udevadm trigger --name-match=kvm
ls /dev/kvm
- name: Checkout
uses: actions/checkout@v4
- name: Checkout Declarative Gradle
uses: actions/checkout@v4
with:
repository: 'gradle/declarative-gradle'
path: 'declarative-gradle'
- name: Checkout Now in Android
uses: actions/checkout@v4
with:
repository: 'gradle/nowinandroid'
path: 'now-in-android'
- name: Validate Gradle Wrapper
uses: gradle/wrapper-validation-action@v2
- name: Copy CI gradle.properties
run: mkdir -p ~/.gradle ; cp now-in-android.github/ci-gradle.properties ~/.gradle/gradle.properties
run: mkdir -p ~/.gradle ; cp .github/ci-gradle.properties ~/.gradle/gradle.properties
- name: Set up JDK 17
uses: actions/setup-java@v4

3
.gitignore vendored

@ -43,3 +43,6 @@ _sandbox
# Android Studio captures folder
captures/
declarative-gradle

@ -4,11 +4,11 @@ This branch has been modified to work with the prototype of the Declarative Grad
## Running
First, checkout the `declarative-no-conventions-nia` branch of the [declarative-gradle](https://github.com/gradle/declarative-gradle) project into a **sibling directory** of this project:
First, checkout `main` branch of the [declarative-gradle](https://github.com/gradle/declarative-gradle) project into the **root** of this project:
```
declarative-gradle/
nowinandroid/
nowinandroid/
declarative-gradle/
```
then run the following command in the `nowinandroid` directory to build the project:

@ -94,10 +94,10 @@ io.coil-kt:coil-compose-base:2.6.0
io.coil-kt:coil-compose:2.6.0
io.coil-kt:coil:2.6.0
javax.inject:javax.inject:1
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.22
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.23
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0
org.jetbrains.kotlin:kotlin-stdlib:1.9.22
org.jetbrains.kotlin:kotlin-stdlib:1.9.23
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.7.3
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.7.3

@ -113,6 +113,7 @@ dependencies {
testImplementation(projects.core.dataTest)
testImplementation(projects.core.testing)
testImplementation(projects.sync.syncTest)
testImplementation(libs.androidx.compose.ui.test)
testImplementation(libs.hilt.android.testing)
testImplementation(libs.work.testing)

@ -203,10 +203,10 @@ io.coil-kt:coil-svg:2.6.0
io.coil-kt:coil:2.6.0
javax.inject:javax.inject:1
org.checkerframework:checker-qual:3.12.0
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.22
org.jetbrains.kotlin:kotlin-stdlib-common:1.9.23
org.jetbrains.kotlin:kotlin-stdlib-jdk7:1.9.0
org.jetbrains.kotlin:kotlin-stdlib-jdk8:1.9.0
org.jetbrains.kotlin:kotlin-stdlib:1.9.22
org.jetbrains.kotlin:kotlin-stdlib:1.9.23
org.jetbrains.kotlinx:kotlinx-coroutines-android:1.8.0
org.jetbrains.kotlinx:kotlinx-coroutines-bom:1.8.0
org.jetbrains.kotlinx:kotlinx-coroutines-core-jvm:1.8.0

@ -16,7 +16,6 @@
package com.google.samples.apps.nowinandroid.ui
import android.util.Log
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.runtime.CompositionLocalProvider
@ -28,10 +27,6 @@ import androidx.compose.ui.test.onRoot
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.test.platform.app.InstrumentationRegistry
import androidx.work.Configuration
import androidx.work.testing.SynchronousExecutor
import androidx.work.testing.WorkManagerTestInitHelper
import com.github.takahirom.roborazzi.captureRoboImage
import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.data.repository.UserDataRepository
@ -109,17 +104,6 @@ class NiaAppScreenSizesScreenshotTests {
@Before
fun setup() {
val config = Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setExecutor(SynchronousExecutor())
.build()
// Initialize WorkManager for instrumentation tests.
WorkManagerTestInitHelper.initializeTestWorkManager(
InstrumentationRegistry.getInstrumentation().context,
config,
)
hiltRule.inject()
// Configure user data

@ -16,13 +16,14 @@
package com.google.samples.apps.nowinandroid.ui
import android.util.Log
import androidx.compose.foundation.layout.BoxWithConstraints
import androidx.compose.material3.SnackbarDuration.Indefinite
import androidx.compose.material3.SnackbarHostState
import androidx.compose.material3.windowsizeclass.ExperimentalMaterial3WindowSizeClassApi
import androidx.compose.material3.windowsizeclass.WindowSizeClass
import androidx.compose.runtime.CompositionLocalProvider
import androidx.compose.runtime.rememberCoroutineScope
import androidx.compose.ui.platform.LocalInspectionMode
import androidx.compose.ui.test.DeviceConfigurationOverride
import androidx.compose.ui.test.ForcedSize
import androidx.compose.ui.test.junit4.createAndroidComposeRule
@ -30,10 +31,6 @@ import androidx.compose.ui.test.onRoot
import androidx.compose.ui.unit.Dp
import androidx.compose.ui.unit.DpSize
import androidx.compose.ui.unit.dp
import androidx.test.platform.app.InstrumentationRegistry
import androidx.work.Configuration
import androidx.work.testing.SynchronousExecutor
import androidx.work.testing.WorkManagerTestInitHelper
import com.github.takahirom.roborazzi.captureRoboImage
import com.google.samples.apps.nowinandroid.core.data.repository.TopicsRepository
import com.google.samples.apps.nowinandroid.core.data.repository.UserNewsResourceRepository
@ -60,6 +57,7 @@ import org.robolectric.RobolectricTestRunner
import org.robolectric.annotation.Config
import org.robolectric.annotation.GraphicsMode
import org.robolectric.annotation.LooperMode
import java.util.TimeZone
import javax.inject.Inject
/**
@ -112,17 +110,6 @@ class SnackbarScreenshotTests {
@Before
fun setup() {
val config = Configuration.Builder()
.setMinimumLoggingLevel(Log.DEBUG)
.setExecutor(SynchronousExecutor())
.build()
// Initialize WorkManager for instrumentation tests.
WorkManagerTestInitHelper.initializeTestWorkManager(
InstrumentationRegistry.getInstrumentation().context,
config,
)
hiltRule.inject()
// Configure user data
@ -135,6 +122,12 @@ class SnackbarScreenshotTests {
}
}
@Before
fun setTimeZone() {
// Make time zone deterministic in tests
TimeZone.setDefault(TimeZone.getTimeZone("UTC"))
}
@Test
fun phone_noSnackbar() {
val snackbarHostState = SnackbarHostState()
@ -207,22 +200,27 @@ class SnackbarScreenshotTests {
) {
lateinit var scope: CoroutineScope
composeTestRule.setContent {
scope = rememberCoroutineScope()
DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(width, height)),
CompositionLocalProvider(
// Replaces images with placeholders
LocalInspectionMode provides true,
) {
BoxWithConstraints {
val appState = rememberNiaAppState(
windowSizeClass = WindowSizeClass.calculateFromSize(
DpSize(maxWidth, maxHeight),
),
networkMonitor = networkMonitor,
userNewsResourceRepository = userNewsResourceRepository,
timeZoneMonitor = timeZoneMonitor,
)
NiaTheme {
NiaApp(appState, snackbarHostState, false, {}, {})
scope = rememberCoroutineScope()
DeviceConfigurationOverride(
DeviceConfigurationOverride.ForcedSize(DpSize(width, height)),
) {
BoxWithConstraints {
val appState = rememberNiaAppState(
windowSizeClass = WindowSizeClass.calculateFromSize(
DpSize(maxWidth, maxHeight),
),
networkMonitor = networkMonitor,
userNewsResourceRepository = userNewsResourceRepository,
timeZoneMonitor = timeZoneMonitor,
)
NiaTheme {
NiaApp(appState, snackbarHostState, false, {}, {})
}
}
}
}

Binary file not shown.

Before

Width:  |  Height:  |  Size: 33 KiB

After

Width:  |  Height:  |  Size: 49 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 34 KiB

After

Width:  |  Height:  |  Size: 50 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 156 KiB

After

Width:  |  Height:  |  Size: 210 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 72 KiB

After

Width:  |  Height:  |  Size: 96 KiB

@ -57,6 +57,7 @@ internal fun Project.configureAndroidCompose(
kotlinOptions {
freeCompilerArgs += buildComposeMetricsParameters()
freeCompilerArgs += stabilityConfiguration()
freeCompilerArgs += strongSkippingConfiguration()
}
}
}
@ -84,6 +85,7 @@ private fun Project.buildComposeMetricsParameters(): List<String> {
"plugin:androidx.compose.compiler.plugins.kotlin:reportsDestination=" + reportsFolder.absolutePath
)
}
return metricParameters.toList()
}
@ -91,3 +93,8 @@ private fun Project.stabilityConfiguration() = listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:stabilityConfigurationPath=${project.rootDir.absolutePath}/compose_compiler_config.conf",
)
private fun Project.strongSkippingConfiguration() = listOf(
"-P",
"plugin:androidx.compose.compiler.plugins.kotlin:experimentalStrongSkipping=true",
)

@ -2,5 +2,10 @@
// It allows us to define classes that our not part of our codebase without wrapping them in a stable class.
// For more information, check https://developer.android.com/jetpack/compose/performance/stability/fix#configuration-file
// We always use immutable classes for our data model, to avoid running the Compose compiler
// in the module we declare it to be stable here.
com.google.samples.apps.nowinandroid.core.model.data.*
// Java standard library classes
java.time.ZoneId
java.time.ZoneOffset

@ -1,6 +1,6 @@
distributionBase=GRADLE_USER_HOME
distributionPath=wrapper/dists
distributionUrl=https\://services.gradle.org/distributions-snapshots/gradle-8.9-20240424122219+0000-bin.zip
distributionUrl=https\://services.gradle.org/distributions-snapshots/gradle-8.9-20240425000222+0000-bin.zip
networkTimeout=10000
validateDistributionUrl=true
zipStoreBase=GRADLE_USER_HOME

@ -16,7 +16,7 @@
pluginManagement {
includeBuild("build-logic")
includeBuild("../declarative-gradle/unified-prototype/unified-plugin")
includeBuild("declarative-gradle/unified-prototype/unified-plugin")
repositories {
google()
mavenCentral()

@ -18,6 +18,8 @@ package com.google.samples.apps.nowinandroid.core.sync.test
import com.google.samples.apps.nowinandroid.core.data.util.SyncManager
import com.google.samples.apps.nowinandroid.sync.di.SyncModule
import com.google.samples.apps.nowinandroid.sync.status.StubSyncSubscriber
import com.google.samples.apps.nowinandroid.sync.status.SyncSubscriber
import dagger.Binds
import dagger.Module
import dagger.hilt.components.SingletonComponent
@ -33,4 +35,9 @@ internal interface TestSyncModule {
fun bindsSyncStatusMonitor(
syncStatusMonitor: NeverSyncingSyncManager,
): SyncManager
@Binds
fun bindsSyncSubscriber(
syncSubscriber: StubSyncSubscriber,
): SyncSubscriber
}

@ -24,7 +24,7 @@ private const val TAG = "StubSyncSubscriber"
/**
* Stub implementation of [SyncSubscriber]
*/
internal class StubSyncSubscriber @Inject constructor() : SyncSubscriber {
class StubSyncSubscriber @Inject constructor() : SyncSubscriber {
override suspend fun subscribe() {
Log.d(TAG, "Subscribing to sync")
}

Loading…
Cancel
Save