Skip to content

Commit c4be180

Browse files
authored
enable version generation in nexus and disable things to avoid flaky tests (#10)
1 parent 0257478 commit c4be180

File tree

10 files changed

+193
-9
lines changed

10 files changed

+193
-9
lines changed

.github/workflows/release.yml

Lines changed: 12 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,9 @@ on:
44
types: [published]
55
jobs:
66
library:
7-
runs-on: ubuntu-latest
7+
runs-on: [ self-hosted-org, linux ]
8+
container:
9+
image: docker://docker.tuenti.io/android/novum_android:12
810
steps:
911
- name: Checkout repo
1012
uses: actions/checkout@v4
@@ -16,10 +18,14 @@ jobs:
1618
ORG_GRADLE_PROJECT_signingKey: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEY }}
1719
ORG_GRADLE_PROJECT_signingPassword: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGPASSWORD }}
1820
ORG_GRADLE_PROJECT_signingKeyId: ${{ secrets.ORG_GRADLE_PROJECT_SIGNINGKEYID }}
21+
NEXUS_USER: ${{ secrets.NEXUS_RELEASE_USER }}
22+
NEXUS_PASS: ${{ secrets.NEXUS_RELEASE_PASSWORD }}
1923
run: |
20-
./gradlew publishReleasePublicationToSonatypeRepository -DLIBRARY_VERSION=${{ github.event.release.tag_name }} --max-workers 1 closeAndReleaseStagingRepository
24+
./gradlew publishReleasePublicationToMavenRepository -DLIBRARY_VERSION=${{ github.event.release.tag_name }}
2125
plugin:
22-
runs-on: ubuntu-latest
26+
runs-on: [ self-hosted-org, linux ]
27+
container:
28+
image: docker://docker.tuenti.io/android/novum_android:12
2329
steps:
2430
- name: Checkout repo
2531
uses: actions/checkout@v4
@@ -28,6 +34,8 @@ jobs:
2834
env:
2935
GRADLE_PUBLISH_KEY: ${{ secrets.GRADLE_PUBLISH_KEY }}
3036
GRADLE_PUBLISH_SECRET: ${{ secrets.GRADLE_PUBLISH_SECRET }}
37+
NEXUS_USER: ${{ secrets.NEXUS_RELEASE_USER }}
38+
NEXUS_PASS: ${{ secrets.NEXUS_RELEASE_PASSWORD }}
3139
run: |
3240
cd include-build
33-
../gradlew publishPlugins -DLIBRARY_VERSION=${{ github.event.release.tag_name }}
41+
../gradlew publishGradlePluginPublicationToMavenRepository -DLIBRARY_VERSION=${{ github.event.release.tag_name }}

android-snaptesting/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -48,6 +48,7 @@ dependencies {
4848
implementation(libs.androidx.test.monitor)
4949
implementation(libs.androidx.test.runner)
5050
implementation(libs.androidx.ui.test.junit4.android)
51+
implementation(libs.espresso.core)
5152
}
5253

5354
apply("${rootProject.projectDir}/mavencentral.gradle")

android-snaptesting/src/main/java/com/telefonica/androidsnaptesting/screenshots/ScreenshotsRule.kt

Lines changed: 68 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,12 +4,19 @@ import android.app.Activity
44
import android.graphics.Bitmap
55
import android.graphics.BitmapFactory
66
import android.os.Build
7+
import android.os.Looper
8+
import android.view.View
9+
import android.widget.EditText
10+
import android.widget.HorizontalScrollView
11+
import android.widget.ScrollView
712
import androidx.annotation.RequiresApi
813
import androidx.compose.ui.graphics.asAndroidBitmap
914
import androidx.compose.ui.test.captureToImage
1015
import androidx.compose.ui.test.junit4.ComposeTestRule
1116
import androidx.compose.ui.test.onRoot
17+
import androidx.test.espresso.Espresso
1218
import androidx.test.platform.app.InstrumentationRegistry
19+
import androidx.test.platform.app.InstrumentationRegistry.getInstrumentation
1320
import androidx.test.runner.screenshot.Screenshot
1421
import com.dropbox.differ.ImageComparator
1522
import com.dropbox.differ.Mask
@@ -51,7 +58,7 @@ public class ScreenshotsRule(
5158
@RequiresApi(Build.VERSION_CODES.O)
5259
public fun compareScreenshot(
5360
rule: ComposeTestRule,
54-
name: String?,
61+
name: String? = null,
5562
) {
5663
rule.waitForIdle()
5764
val bitmap = rule.onRoot().captureToImage().asAndroidBitmap()
@@ -60,16 +67,20 @@ public class ScreenshotsRule(
6067

6168
public fun compareScreenshot(
6269
activity: Activity,
63-
name: String?,
70+
name: String? = null,
6471
) {
72+
val view = activity.findViewById<View>(android.R.id.content)
73+
74+
disableFlakyComponentsAndWaitForIdle(view)
75+
6576
val bitmap = Screenshot.capture(activity).bitmap
6677
compareScreenshot(bitmap, name)
6778
}
6879

6980
@Suppress("MemberVisibilityCanBePrivate")
7081
public fun compareScreenshot(
7182
bitmap: Bitmap,
72-
name: String?
83+
name: String? = null,
7384
) {
7485
val resourceName = "${className}_${name ?: testName}.png"
7586
val fileName = "$resourceName.${System.nanoTime()}"
@@ -141,4 +152,58 @@ public class ScreenshotsRule(
141152
)
142153
}
143154
}
155+
156+
private fun disableFlakyComponentsAndWaitForIdle(view: View? = null) {
157+
if (view != null) {
158+
disableAnimatedComponents(view)
159+
}
160+
if (notInAppMainThread()) {
161+
waitForAnimationsToFinish()
162+
}
163+
}
164+
165+
private fun disableAnimatedComponents(view: View) {
166+
runOnUi {
167+
hideEditTextCursors(view)
168+
hideScrollViewBars(view)
169+
}
170+
}
171+
172+
private fun hideEditTextCursors(view: View) {
173+
view.childrenViews<EditText>().forEach {
174+
it.isCursorVisible = false
175+
}
176+
}
177+
178+
private fun hideScrollViewBars(view: View) {
179+
view.childrenViews<ScrollView>().forEach {
180+
hideViewBars(it)
181+
}
182+
183+
view.childrenViews<HorizontalScrollView>().forEach {
184+
hideViewBars(it)
185+
}
186+
}
187+
188+
private fun hideViewBars(it: View) {
189+
it.isHorizontalScrollBarEnabled = false
190+
it.isVerticalScrollBarEnabled = false
191+
it.overScrollMode = View.OVER_SCROLL_NEVER
192+
}
193+
194+
public fun waitForAnimationsToFinish() {
195+
getInstrumentation().waitForIdleSync()
196+
Espresso.onIdle()
197+
}
198+
199+
public fun runOnUi(block: () -> Unit) {
200+
if (notInAppMainThread()) {
201+
getInstrumentation().runOnMainSync { block() }
202+
} else {
203+
block()
204+
}
205+
}
206+
207+
private fun notInAppMainThread() = Looper.myLooper() != Looper.getMainLooper()
208+
144209
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
package com.telefonica.androidsnaptesting.screenshots
2+
3+
import android.view.View
4+
import android.view.ViewGroup
5+
6+
@Suppress("UNCHECKED_CAST")
7+
public inline fun <reified T : View> View.childrenViews(): List<T> = filterChildrenViews {
8+
it is T
9+
} as List<T>
10+
11+
public fun View.filterChildrenViews(filter: (View) -> Boolean): List<View> {
12+
val children = mutableSetOf<View>()
13+
val view = this
14+
if (view !is ViewGroup) {
15+
if (filter.invoke(view)) {
16+
children.add(view)
17+
}
18+
} else {
19+
for (i in 0 until view.childCount) {
20+
view.getChildAt(i).let {
21+
children.addAll(it.filterChildrenViews(filter))
22+
if (filter.invoke(it)) {
23+
children.add(it)
24+
}
25+
}
26+
}
27+
}
28+
29+
return children.toList()
30+
}

app/src/androidTest/java/com/telefonica/androidsnaptesting/ExampleInstrumentedTest.kt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,9 @@ package com.telefonica.androidsnaptesting
22

33
import androidx.test.core.app.ActivityScenario
44
import androidx.test.ext.junit.runners.AndroidJUnit4
5+
import com.telefonica.androidsnaptesting.logs.LogsRecorder
6+
import com.telefonica.androidsnaptesting.logs.LogsRule
7+
import com.telefonica.androidsnaptesting.screenshots.ScreenshotsRule
58
import org.junit.Rule
69
import org.junit.Test
710
import org.junit.runner.RunWith

include-build/build.gradle.kts

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
plugins {
22
alias(libs.plugins.kotlin.jvm) apply false
33
alias(libs.plugins.detekt)
4+
alias(libs.plugins.publish)
45
}
56

67
allprojects {
@@ -14,3 +15,5 @@ allprojects {
1415
buildUponDefaultConfig = true
1516
}
1617
}
18+
19+
apply("${rootProject.projectDir}/../publish_maven_central.gradle")

include-build/gradle-plugin/build.gradle.kts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,3 +31,5 @@ gradlePlugin {
3131
}
3232
}
3333
}
34+
35+
apply("${rootProject.projectDir}/mavencentral.gradle")

include-build/gradle/libs.versions.toml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ ddmlib = "31.4.1"
55
kotlin = "1.9.23"
66
detekt = "1.23.6"
77
publish-plugin = "1.2.0"
8+
publish = "1.1.0"
89

910
[libraries]
1011
android-builder-test-api = { module = "com.android.tools.build:builder-test-api", version.ref = "agp" }
@@ -15,4 +16,5 @@ android-gradle = { module = "com.android.tools.build:gradle", version.ref = "agp
1516
[plugins]
1617
detekt = { id = "io.gitlab.arturbosch.detekt", version.ref = "detekt" }
1718
kotlin-jvm = { id = "org.jetbrains.kotlin.jvm", version.ref = "kotlin" }
18-
publish-plugin = { id = "com.gradle.plugin-publish", version.ref = "publish-plugin" }
19+
publish-plugin = { id = "com.gradle.plugin-publish", version.ref = "publish-plugin" }
20+
publish = { id = "io.github.gradle-nexus.publish-plugin", version.ref = "publish" }

include-build/mavencentral.gradle

Lines changed: 62 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,62 @@
1+
apply plugin: 'maven-publish'
2+
apply plugin: 'signing'
3+
4+
publishing {
5+
repositories {
6+
maven {
7+
credentials {
8+
username System.env.NEXUS_USER
9+
password System.env.NEXUS_PASS
10+
}
11+
url "https://nexusng.tuenti.io/repository/maven-release-private/"
12+
}
13+
}
14+
publications {
15+
gradlePlugin(MavenPublication) {
16+
groupId 'com.telefonica'
17+
artifactId 'android-snaptesting-gradle-plugin'
18+
version version
19+
20+
artifact("$buildDir/libs/gradle-plugin-${version}.jar")
21+
22+
pom {
23+
name = 'Android Snaptesting Gradle Plugin'
24+
description = 'Gradle Plugin for logs snapshot testing for Android Instrumentation tests.'
25+
url = 'https://github.com/Telefonica/android-snaptesting'
26+
licenses {
27+
license {
28+
name = 'The Apache License, Version 2.0'
29+
url = 'http://www.apache.org/licenses/LICENSE-2.0.txt'
30+
}
31+
}
32+
developers {
33+
developer {
34+
id = 'android-team-telefonica'
35+
name = 'Android Team'
36+
37+
}
38+
}
39+
scm {
40+
connection = 'scm:git:github.com/Telefonica/android-snaptesting.git'
41+
developerConnection = 'scm:git:ssh://github.com/Telefonica/android-snaptesting.git'
42+
url = 'https://github.com/Telefonica/android-snaptesting/tree/main'
43+
}
44+
withXml {
45+
def dependenciesNode = asNode().appendNode('dependencies')
46+
47+
project.configurations.getByName("implementation").dependencies.each {
48+
def dependencyNode = dependenciesNode.appendNode('dependency')
49+
dependencyNode.appendNode('groupId', it.group)
50+
dependencyNode.appendNode('artifactId', it.name)
51+
dependencyNode.appendNode('version', it.version)
52+
}
53+
}
54+
}
55+
}
56+
}
57+
}
58+
59+
afterEvaluate {
60+
tasks.getByName("publishGradlePluginPublicationToMavenLocal").dependsOn("jar")
61+
tasks.getByName("publishGradlePluginPublicationToMavenRepository").dependsOn("jar")
62+
}

mavencentral.gradle

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,15 @@ apply plugin: 'maven-publish'
1111
apply plugin: 'signing'
1212

1313
publishing {
14+
repositories {
15+
maven {
16+
credentials {
17+
username System.env.NEXUS_USER
18+
password System.env.NEXUS_PASS
19+
}
20+
url "https://nexusng.tuenti.io/repository/maven-release-private/"
21+
}
22+
}
1423
publications {
1524
release(MavenPublication) {
1625
groupId 'com.telefonica'
@@ -59,7 +68,6 @@ publishing {
5968

6069
afterEvaluate {
6170
tasks.getByName("publishReleasePublicationToMavenLocal").dependsOn("assembleRelease")
62-
tasks.getByName("publishReleasePublicationToSonatypeRepository").dependsOn("assembleRelease")
6371
tasks.getByName("signReleasePublication").dependsOn("assembleRelease")
6472
}
6573

0 commit comments

Comments
 (0)