From 05a910f4ebca55dd305cdda5916a77e18e2176e4 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Tue, 24 Feb 2026 10:46:56 +0100 Subject: [PATCH 01/16] Screenshot tests were failing, JUnit downgrade needed Signed-off-by: tobiasKaminsky --- app/build.gradle.kts | 1 + gradle/libs.versions.toml | 2 +- gradle/verification-metadata.xml | 23 +++++++++++++++++++++++ 3 files changed, 25 insertions(+), 1 deletion(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index a659e78e0037..bb4f5f7b28fd 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -352,6 +352,7 @@ dependencies { implementation(libs.compose.activity) implementation(libs.compose.ui.tooling.preview) implementation(libs.foundation) + implementation(libs.espresso.accessibility) debugImplementation(libs.compose.ui.tooling) // endregion diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 3713b891335e..6a36cdf085bf 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -47,7 +47,7 @@ jackrabbitWebdavVersion = "2.13.5" jacoco = "0.8.14" jsonVersion = "20250517" junit = "4.13.2" -junitVersion = "1.3.0" +junitVersion = "1.1.0" juniversalchardetVersion = "2.5.0" kotlin = "2.3.21" kotlinxSerializationJson = "1.11.0" diff --git a/gradle/verification-metadata.xml b/gradle/verification-metadata.xml index faab2c1fdb31..231939635396 100644 --- a/gradle/verification-metadata.xml +++ b/gradle/verification-metadata.xml @@ -3394,6 +3394,11 @@ + + + + + @@ -11008,6 +11013,11 @@ + + + + + @@ -11080,6 +11090,11 @@ + + + + + @@ -11399,6 +11414,14 @@ + + + + + + + + From c46c71d42ae4d2e84ac0311b95bc54282dbcbbdc Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Tue, 24 Feb 2026 15:52:42 +0100 Subject: [PATCH 02/16] wip Signed-off-by: tobiasKaminsky --- .../androidTest/java/com/owncloud/android/AbstractIT.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/app/src/androidTest/java/com/owncloud/android/AbstractIT.java b/app/src/androidTest/java/com/owncloud/android/AbstractIT.java index 5230036f5bff..5144272f9637 100644 --- a/app/src/androidTest/java/com/owncloud/android/AbstractIT.java +++ b/app/src/androidTest/java/com/owncloud/android/AbstractIT.java @@ -34,7 +34,6 @@ import com.nextcloud.client.preferences.AppPreferencesImpl; import com.nextcloud.client.preferences.DarkMode; import com.nextcloud.common.NextcloudClient; -import com.nextcloud.test.GrantStoragePermissionRule; import com.nextcloud.test.RandomStringGenerator; import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.ArbitraryDataProviderImpl; @@ -59,8 +58,6 @@ import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; -import org.junit.Rule; -import org.junit.rules.TestRule; import java.io.File; import java.io.FileWriter; @@ -92,8 +89,8 @@ * Common base for all integration tests. */ public abstract class AbstractIT { - @Rule - public final TestRule storagePermissionRule = GrantStoragePermissionRule.grant(); +// @Rule +// public final TestRule storagePermissionRule = GrantStoragePermissionRule.grant(); protected ConnectivityService connectivityServiceMock = ConnectivityManagerFactory.INSTANCE.getMock(); From 2fd7610dbdf8d7ad8f35db43c9a576f757fc54bd Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 25 Feb 2026 08:30:00 +0100 Subject: [PATCH 03/16] use API34 Signed-off-by: tobiasKaminsky --- .github/workflows/screenShotTest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/screenShotTest.yml b/.github/workflows/screenShotTest.yml index 9d96cec73e30..3b38413d23b1 100644 --- a/.github/workflows/screenShotTest.yml +++ b/.github/workflows/screenShotTest.yml @@ -23,7 +23,7 @@ jobs: matrix: scheme: [ Light ] color: [ blue ] - api-level: [ 28 ] + api-level: [ 34 ] steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 From ae1a3ee71c67394109e98fd5bad72d89e94a6010 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 25 Feb 2026 08:42:50 +0100 Subject: [PATCH 04/16] use API33 Signed-off-by: tobiasKaminsky --- .github/workflows/screenShotTest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/screenShotTest.yml b/.github/workflows/screenShotTest.yml index 3b38413d23b1..cd07adef72cd 100644 --- a/.github/workflows/screenShotTest.yml +++ b/.github/workflows/screenShotTest.yml @@ -23,7 +23,7 @@ jobs: matrix: scheme: [ Light ] color: [ blue ] - api-level: [ 34 ] + api-level: [ 33 ] steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 From c218bd59171bbbf851395d4d204d105d40aa93b3 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 25 Feb 2026 09:10:34 +0100 Subject: [PATCH 05/16] use API29 Signed-off-by: tobiasKaminsky --- .github/workflows/screenShotTest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/screenShotTest.yml b/.github/workflows/screenShotTest.yml index cd07adef72cd..2e4277f6028c 100644 --- a/.github/workflows/screenShotTest.yml +++ b/.github/workflows/screenShotTest.yml @@ -23,7 +23,7 @@ jobs: matrix: scheme: [ Light ] color: [ blue ] - api-level: [ 33 ] + api-level: [ 29 ] steps: - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 From 65ca59d2cf22575989dfdbb38a9174ae67f82496 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 25 Feb 2026 10:26:59 +0100 Subject: [PATCH 06/16] wip: test disabling granting permission Signed-off-by: tobiasKaminsky --- .../client/FileDisplayActivityScreenshotIT.kt | 13 +++++-------- 1 file changed, 5 insertions(+), 8 deletions(-) diff --git a/app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityScreenshotIT.kt b/app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityScreenshotIT.kt index d727d1acd9aa..169b0c547635 100644 --- a/app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityScreenshotIT.kt +++ b/app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityScreenshotIT.kt @@ -8,7 +8,6 @@ */ package com.nextcloud.client -import android.Manifest import androidx.test.core.app.launchActivity import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches @@ -17,7 +16,6 @@ import androidx.test.espresso.contrib.NavigationViewActions import androidx.test.espresso.matcher.ViewMatchers import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isRoot -import androidx.test.rule.GrantPermissionRule import com.owncloud.android.AbstractIT import com.owncloud.android.R import com.owncloud.android.lib.common.utils.Log_OC @@ -25,17 +23,16 @@ import com.owncloud.android.ui.activity.FileDisplayActivity import com.owncloud.android.ui.fragment.EmptyListState import com.owncloud.android.utils.ScreenshotTest import org.junit.Assert -import org.junit.Rule import org.junit.Test class FileDisplayActivityScreenshotIT : AbstractIT() { private val testClassName = "com.nextcloud.client.FileDisplayActivityScreenshotIT" - @get:Rule - val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.POST_NOTIFICATIONS - ) + // @get:Rule + // val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( + // Manifest.permission.WRITE_EXTERNAL_STORAGE, + // Manifest.permission.POST_NOTIFICATIONS + // ) companion object { private const val TAG = "FileDisplayActivityScreenshotIT" From ef34aa400bd54caae1615e86759fcd9f4f0822d6 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 25 Feb 2026 13:20:08 +0100 Subject: [PATCH 07/16] wip Signed-off-by: tobiasKaminsky --- .../com/nextcloud/ui/SetOnlineStatusBottomSheetIT.kt | 1 - .../com/nextcloud/ui/SetStatusMessageBottomSheetIT.kt | 1 - .../java/com/owncloud/android/AbstractIT.java | 7 +++++-- .../java/com/owncloud/android/ScreenshotsIT.kt | 10 ---------- .../owncloud/android/ui/activity/DrawerActivityIT.kt | 1 - .../com/owncloud/android/ui/dialog/DialogFragmentIT.kt | 1 - .../dialog/SyncFileNotEnoughSpaceDialogFragmentTest.kt | 1 - .../android/ui/preview/PreviewTextFileFragmentTest.kt | 1 - 8 files changed, 5 insertions(+), 18 deletions(-) diff --git a/app/src/androidTest/java/com/nextcloud/ui/SetOnlineStatusBottomSheetIT.kt b/app/src/androidTest/java/com/nextcloud/ui/SetOnlineStatusBottomSheetIT.kt index c9e07da94cfd..650706c309d0 100644 --- a/app/src/androidTest/java/com/nextcloud/ui/SetOnlineStatusBottomSheetIT.kt +++ b/app/src/androidTest/java/com/nextcloud/ui/SetOnlineStatusBottomSheetIT.kt @@ -28,7 +28,6 @@ class SetOnlineStatusBottomSheetIT : AbstractIT() { @get:Rule val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.POST_NOTIFICATIONS ) diff --git a/app/src/androidTest/java/com/nextcloud/ui/SetStatusMessageBottomSheetIT.kt b/app/src/androidTest/java/com/nextcloud/ui/SetStatusMessageBottomSheetIT.kt index b9e9feec6e2e..998a4877aeaa 100644 --- a/app/src/androidTest/java/com/nextcloud/ui/SetStatusMessageBottomSheetIT.kt +++ b/app/src/androidTest/java/com/nextcloud/ui/SetStatusMessageBottomSheetIT.kt @@ -29,7 +29,6 @@ import org.junit.Test class SetStatusMessageBottomSheetIT : AbstractIT() { @get:Rule val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.POST_NOTIFICATIONS ) diff --git a/app/src/androidTest/java/com/owncloud/android/AbstractIT.java b/app/src/androidTest/java/com/owncloud/android/AbstractIT.java index 5144272f9637..5230036f5bff 100644 --- a/app/src/androidTest/java/com/owncloud/android/AbstractIT.java +++ b/app/src/androidTest/java/com/owncloud/android/AbstractIT.java @@ -34,6 +34,7 @@ import com.nextcloud.client.preferences.AppPreferencesImpl; import com.nextcloud.client.preferences.DarkMode; import com.nextcloud.common.NextcloudClient; +import com.nextcloud.test.GrantStoragePermissionRule; import com.nextcloud.test.RandomStringGenerator; import com.owncloud.android.datamodel.ArbitraryDataProvider; import com.owncloud.android.datamodel.ArbitraryDataProviderImpl; @@ -58,6 +59,8 @@ import org.junit.After; import org.junit.Before; import org.junit.BeforeClass; +import org.junit.Rule; +import org.junit.rules.TestRule; import java.io.File; import java.io.FileWriter; @@ -89,8 +92,8 @@ * Common base for all integration tests. */ public abstract class AbstractIT { -// @Rule -// public final TestRule storagePermissionRule = GrantStoragePermissionRule.grant(); + @Rule + public final TestRule storagePermissionRule = GrantStoragePermissionRule.grant(); protected ConnectivityService connectivityServiceMock = ConnectivityManagerFactory.INSTANCE.getMock(); diff --git a/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt b/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt index 100395a13fa9..f706c670c830 100644 --- a/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt @@ -6,7 +6,6 @@ */ package com.owncloud.android -import android.Manifest import androidx.test.core.app.launchActivity import androidx.test.espresso.Espresso import androidx.test.espresso.Espresso.onView @@ -18,7 +17,6 @@ import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.espresso.matcher.ViewMatchers.withId import androidx.test.espresso.matcher.ViewMatchers.withText -import androidx.test.rule.GrantPermissionRule import com.owncloud.android.datamodel.OCFile import com.owncloud.android.ui.activity.FileDisplayActivity import com.owncloud.android.ui.activity.SettingsActivity @@ -27,20 +25,12 @@ import com.owncloud.android.utils.ScreenshotTest import org.junit.Assert.assertTrue import org.junit.BeforeClass import org.junit.ClassRule -import org.junit.Rule import org.junit.Test import tools.fastlane.screengrab.Screengrab import tools.fastlane.screengrab.UiAutomatorScreenshotStrategy import tools.fastlane.screengrab.locale.LocaleTestRule class ScreenshotsIT : AbstractIT() { - - @get:Rule - val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.WRITE_EXTERNAL_STORAGE, - Manifest.permission.POST_NOTIFICATIONS - ) - @Test @ScreenshotTest fun gridViewScreenshot() { diff --git a/app/src/androidTest/java/com/owncloud/android/ui/activity/DrawerActivityIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/activity/DrawerActivityIT.kt index 93caa0dba447..d3639df5d1a5 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/activity/DrawerActivityIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/activity/DrawerActivityIT.kt @@ -40,7 +40,6 @@ class DrawerActivityIT : AbstractIT() { @get:Rule val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.POST_NOTIFICATIONS ) diff --git a/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt index 5c4707f99e06..c58139f03003 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt @@ -85,7 +85,6 @@ class DialogFragmentIT : AbstractIT() { @get:Rule val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.POST_NOTIFICATIONS ) diff --git a/app/src/androidTest/java/com/owncloud/android/ui/dialog/SyncFileNotEnoughSpaceDialogFragmentTest.kt b/app/src/androidTest/java/com/owncloud/android/ui/dialog/SyncFileNotEnoughSpaceDialogFragmentTest.kt index f83e116a6da5..84d70be84290 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/dialog/SyncFileNotEnoughSpaceDialogFragmentTest.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/dialog/SyncFileNotEnoughSpaceDialogFragmentTest.kt @@ -26,7 +26,6 @@ class SyncFileNotEnoughSpaceDialogFragmentTest : AbstractIT() { @get:Rule val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.POST_NOTIFICATIONS ) diff --git a/app/src/androidTest/java/com/owncloud/android/ui/preview/PreviewTextFileFragmentTest.kt b/app/src/androidTest/java/com/owncloud/android/ui/preview/PreviewTextFileFragmentTest.kt index 93ac4bef85af..0febfb57e20e 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/preview/PreviewTextFileFragmentTest.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/preview/PreviewTextFileFragmentTest.kt @@ -27,7 +27,6 @@ class PreviewTextFileFragmentTest : AbstractIT() { @get:Rule val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.WRITE_EXTERNAL_STORAGE, Manifest.permission.POST_NOTIFICATIONS ) From 0d40aa303a933eccde9ab238791aabf6517c3bd0 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Tue, 3 Mar 2026 10:07:13 +0100 Subject: [PATCH 08/16] wip Signed-off-by: tobiasKaminsky --- .../androidTest/java/com/owncloud/android/ScreenshotsIT.kt | 2 +- .../com/owncloud/android/ui/dialog/DialogFragmentIT.kt | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt b/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt index f706c670c830..6b7d24426f12 100644 --- a/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt @@ -55,7 +55,7 @@ class ScreenshotsIT : AbstractIT() { OCFile(path).apply { storageManager.saveFile(this) } - onView(withId(R.id.list_root)).perform(click()) + // onView(withId(R.id.list_root)).perform(click()) onView(isRoot()).check(matches(isDisplayed())) Screengrab.screenshot("02_listView") diff --git a/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt index c58139f03003..64d30d0c10b9 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt @@ -8,7 +8,6 @@ */ package com.owncloud.android.ui.dialog -import android.Manifest import android.accounts.Account import android.accounts.AccountManager import android.app.Dialog @@ -27,7 +26,6 @@ import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isRoot -import androidx.test.rule.GrantPermissionRule import com.google.android.material.bottomsheet.BottomSheetBehavior import com.google.gson.Gson import com.google.gson.reflect.TypeToken @@ -83,11 +81,6 @@ class DialogFragmentIT : AbstractIT() { private val testClassName = "com.owncloud.android.ui.dialog.DialogFragmentIT" private val serverUrl = "https://nextcloud.localhost" - @get:Rule - val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.POST_NOTIFICATIONS - ) - @After fun quitLooperIfNeeded() { Looper.myLooper()?.quitSafely() From c133cd6dfe065195a895e4a14cafd77570ef0eb3 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Tue, 3 Mar 2026 10:39:02 +0100 Subject: [PATCH 09/16] wip Signed-off-by: tobiasKaminsky --- .../android/ui/dialog/DialogFragmentIT.kt | 38 +++++++++---------- 1 file changed, 19 insertions(+), 19 deletions(-) diff --git a/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt index 64d30d0c10b9..cedc929fa278 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/dialog/DialogFragmentIT.kt @@ -97,7 +97,7 @@ class DialogFragmentIT : AbstractIT() { OCFile("/Test/"), OCFile("/") ).run { - showDialog(this) + showDialog(this, "testRenameFileDialog") } } @@ -105,7 +105,7 @@ class DialogFragmentIT : AbstractIT() { @ScreenshotTest fun testLoadingDialog() { LoadingDialog.newInstance("Wait…").run { - showDialog(this) + showDialog(this, "testLoadingDialog") } } @@ -121,7 +121,7 @@ class DialogFragmentIT : AbstractIT() { -1, -1 ).run { - showDialog(this) + showDialog(this, "testConfirmationDialogWithOneAction") } } @@ -137,7 +137,7 @@ class DialogFragmentIT : AbstractIT() { -1, -1 ).run { - showDialog(this) + showDialog(this, "testConfirmationDialogWithTwoAction") } } @@ -153,7 +153,7 @@ class DialogFragmentIT : AbstractIT() { R.string.common_confirm, -1 ).run { - showDialog(this) + showDialog(this, "testConfirmationDialogWithThreeAction") } } @@ -170,7 +170,7 @@ class DialogFragmentIT : AbstractIT() { R.string.common_confirm, -1 ).run { - showDialog(this) + showDialog(this, "testConfirmationDialogWithThreeActionRTL") resetLocale() } } @@ -179,7 +179,7 @@ class DialogFragmentIT : AbstractIT() { @ScreenshotTest fun testRemoveFileDialog() { RemoveFilesDialogFragment.newInstance(OCFile("/Test.md")).run { - showDialog(this) + showDialog(this, "testRemoveFileDialog") } } @@ -192,14 +192,14 @@ class DialogFragmentIT : AbstractIT() { } val dialog: RemoveFilesDialogFragment = RemoveFilesDialogFragment.newInstance(toDelete) - showDialog(dialog) + showDialog(dialog, "testRemoveFilesDialog") } @Test @ScreenshotTest fun testRemoveFolderDialog() { val dialog = RemoveFilesDialogFragment.newInstance(OCFile("/Folder/")) - showDialog(dialog) + showDialog(dialog, "testRemoveFolderDialog") } @Test @@ -210,7 +210,7 @@ class DialogFragmentIT : AbstractIT() { toDelete.add(OCFile("/Documents/")) val dialog: RemoveFilesDialogFragment = RemoveFilesDialogFragment.newInstance(toDelete) - showDialog(dialog) + showDialog(dialog, "testRemoveFoldersDialog") } @Test @@ -220,7 +220,7 @@ class DialogFragmentIT : AbstractIT() { Looper.prepare() } val sut = CreateFolderDialogFragment.newInstance(OCFile("/")) - showDialog(sut) + showDialog(sut, "testNewFolderDialog") } @Test @@ -230,7 +230,7 @@ class DialogFragmentIT : AbstractIT() { Looper.prepare() } val sut = SharePasswordDialogFragment.newInstance(OCFile("/"), createShare = true, askForPassword = false) - showDialog(sut) + showDialog(sut, "testEnforcedPasswordDialog") } @Test @@ -239,8 +239,8 @@ class DialogFragmentIT : AbstractIT() { if (Looper.myLooper() == null) { Looper.prepare() } - val sut = SharePasswordDialogFragment.newInstance(OCFile("/"), createShare = true, askForPassword = true) - showDialog(sut) + val sut = SharePasswordDialogFragment.newInstance(OCFile("/"), true, true) + showDialog(sut, "testOptionalPasswordDialog") } @Test @@ -632,7 +632,7 @@ class DialogFragmentIT : AbstractIT() { val handler = mockk(relaxed = true) SslUntrustedCertDialog.newInstanceForEmptySslError(sslError, handler).run { - showDialog(this) + showDialog(this, "testSslUntrustedCertDialog") } } @@ -644,7 +644,7 @@ class DialogFragmentIT : AbstractIT() { } val dialog = StoragePermissionDialogFragment() - showDialog(dialog) + showDialog(dialog, "testStoragePermissionDialog") } @Test @@ -659,11 +659,11 @@ class DialogFragmentIT : AbstractIT() { } newInstance(ocFile, false).run { - showDialog(this) + showDialog(this, "testFileActionsBottomSheet") } } - private fun showDialog(dialog: DialogFragment) { + private fun showDialog(dialog: DialogFragment, testName: String) { launchActivity().use { scenario -> scenario.onActivity { sut -> dialog.show(sut.supportFragmentManager, null) @@ -676,7 +676,7 @@ class DialogFragmentIT : AbstractIT() { if (viewGroup != null) { hideCursors(viewGroup) } - screenshot(dialogInstance.window?.decorView) + screenshotViaName(dialogInstance.window?.decorView, "${testClassName}_$testName") } onView(isRoot()).check(matches(isDisplayed())) From a7df43940fcd5a0eec3a19b2aa62837a659dd855 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Tue, 3 Mar 2026 12:25:53 +0100 Subject: [PATCH 10/16] wip Signed-off-by: tobiasKaminsky --- .../java/com/nextcloud/ui/SetOnlineStatusBottomSheetIT.kt | 8 -------- .../com/nextcloud/ui/SetStatusMessageBottomSheetIT.kt | 7 ------- .../com/owncloud/android/ui/activity/DrawerActivityIT.kt | 7 ------- .../ui/dialog/SyncFileNotEnoughSpaceDialogFragmentTest.kt | 8 -------- .../android/ui/preview/PreviewTextFileFragmentTest.kt | 8 -------- 5 files changed, 38 deletions(-) diff --git a/app/src/androidTest/java/com/nextcloud/ui/SetOnlineStatusBottomSheetIT.kt b/app/src/androidTest/java/com/nextcloud/ui/SetOnlineStatusBottomSheetIT.kt index 650706c309d0..5a7ddf6b0ac5 100644 --- a/app/src/androidTest/java/com/nextcloud/ui/SetOnlineStatusBottomSheetIT.kt +++ b/app/src/androidTest/java/com/nextcloud/ui/SetOnlineStatusBottomSheetIT.kt @@ -8,29 +8,21 @@ */ package com.nextcloud.ui -import android.Manifest import androidx.test.core.app.launchActivity import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isRoot import androidx.test.espresso.matcher.ViewMatchers.withId -import androidx.test.rule.GrantPermissionRule import com.owncloud.android.AbstractIT import com.owncloud.android.R import com.owncloud.android.lib.resources.users.Status import com.owncloud.android.lib.resources.users.StatusType import com.owncloud.android.ui.activity.FileDisplayActivity -import org.junit.Rule import org.junit.Test class SetOnlineStatusBottomSheetIT : AbstractIT() { - @get:Rule - val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.POST_NOTIFICATIONS - ) - @Test fun open() { launchActivity().use { scenario -> diff --git a/app/src/androidTest/java/com/nextcloud/ui/SetStatusMessageBottomSheetIT.kt b/app/src/androidTest/java/com/nextcloud/ui/SetStatusMessageBottomSheetIT.kt index 998a4877aeaa..83b73b1fbe04 100644 --- a/app/src/androidTest/java/com/nextcloud/ui/SetStatusMessageBottomSheetIT.kt +++ b/app/src/androidTest/java/com/nextcloud/ui/SetStatusMessageBottomSheetIT.kt @@ -8,7 +8,6 @@ */ package com.nextcloud.ui -import android.Manifest import androidx.test.core.app.launchActivity import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches @@ -23,15 +22,9 @@ import com.owncloud.android.lib.resources.users.PredefinedStatus import com.owncloud.android.lib.resources.users.Status import com.owncloud.android.lib.resources.users.StatusType import com.owncloud.android.ui.activity.FileDisplayActivity -import org.junit.Rule import org.junit.Test class SetStatusMessageBottomSheetIT : AbstractIT() { - @get:Rule - val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.POST_NOTIFICATIONS - ) - @Test fun open() { launchActivity().use { scenario -> diff --git a/app/src/androidTest/java/com/owncloud/android/ui/activity/DrawerActivityIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/activity/DrawerActivityIT.kt index d3639df5d1a5..6eab228be93d 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/activity/DrawerActivityIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/activity/DrawerActivityIT.kt @@ -8,7 +8,6 @@ */ package com.owncloud.android.ui.activity -import android.Manifest import android.accounts.Account import android.accounts.AccountManager import android.net.Uri @@ -17,7 +16,6 @@ import androidx.test.espresso.Espresso.onView import androidx.test.espresso.action.ViewActions import androidx.test.espresso.matcher.ViewMatchers import androidx.test.platform.app.InstrumentationRegistry -import androidx.test.rule.GrantPermissionRule import com.nextcloud.client.account.User import com.nextcloud.client.account.UserAccountManager import com.nextcloud.client.account.UserAccountManagerImpl @@ -38,11 +36,6 @@ class DrawerActivityIT : AbstractIT() { @JvmField val retryTestRule = RetryTestRule() - @get:Rule - val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.POST_NOTIFICATIONS - ) - @Test fun switchAccountViaAccountList() { launchActivity().use { scenario -> diff --git a/app/src/androidTest/java/com/owncloud/android/ui/dialog/SyncFileNotEnoughSpaceDialogFragmentTest.kt b/app/src/androidTest/java/com/owncloud/android/ui/dialog/SyncFileNotEnoughSpaceDialogFragmentTest.kt index 84d70be84290..495bec37b3c8 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/dialog/SyncFileNotEnoughSpaceDialogFragmentTest.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/dialog/SyncFileNotEnoughSpaceDialogFragmentTest.kt @@ -6,29 +6,21 @@ */ package com.owncloud.android.ui.dialog -import android.Manifest import androidx.test.core.app.launchActivity import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isRoot -import androidx.test.rule.GrantPermissionRule import com.owncloud.android.AbstractIT import com.owncloud.android.datamodel.OCFile import com.owncloud.android.ui.activity.FileDisplayActivity import com.owncloud.android.ui.dialog.SyncFileNotEnoughSpaceDialogFragment.Companion.newInstance import com.owncloud.android.utils.ScreenshotTest -import org.junit.Rule import org.junit.Test class SyncFileNotEnoughSpaceDialogFragmentTest : AbstractIT() { private val testClassName = "com.owncloud.android.ui.dialog.SyncFileNotEnoughSpaceDialogFragmentTest" - @get:Rule - val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.POST_NOTIFICATIONS - ) - @Test @ScreenshotTest fun showNotEnoughSpaceDialogForFolder() { diff --git a/app/src/androidTest/java/com/owncloud/android/ui/preview/PreviewTextFileFragmentTest.kt b/app/src/androidTest/java/com/owncloud/android/ui/preview/PreviewTextFileFragmentTest.kt index 0febfb57e20e..0ed47bdef0ed 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/preview/PreviewTextFileFragmentTest.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/preview/PreviewTextFileFragmentTest.kt @@ -6,30 +6,22 @@ */ package com.owncloud.android.ui.preview -import android.Manifest import androidx.test.core.app.launchActivity import androidx.test.espresso.Espresso.onView import androidx.test.espresso.assertion.ViewAssertions.matches import androidx.test.espresso.matcher.ViewMatchers.isDisplayed import androidx.test.espresso.matcher.ViewMatchers.isRoot -import androidx.test.rule.GrantPermissionRule import com.owncloud.android.AbstractIT import com.owncloud.android.datamodel.OCFile import com.owncloud.android.ui.activity.FileDisplayActivity import com.owncloud.android.utils.MimeTypeUtil import com.owncloud.android.utils.ScreenshotTest -import org.junit.Rule import org.junit.Test import java.io.IOException class PreviewTextFileFragmentTest : AbstractIT() { private val testClassName = "com.owncloud.android.ui.preview.PreviewTextFileFragmentTest" - @get:Rule - val permissionRule: GrantPermissionRule = GrantPermissionRule.grant( - Manifest.permission.POST_NOTIFICATIONS - ) - @Test @ScreenshotTest @Throws(IOException::class) From 860dda0c9030d3432f6603f3636911aec40403f8 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Tue, 3 Mar 2026 13:38:58 +0100 Subject: [PATCH 11/16] wip Signed-off-by: tobiasKaminsky --- .../FileDetailFragmentStaticServerIT.kt | 23 ++++++++++++++----- .../fragment/FileDetailSharingFragmentIT.kt | 12 +++++----- .../OCFileListFragmentStaticServerIT.kt | 6 +++++ 3 files changed, 29 insertions(+), 12 deletions(-) diff --git a/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailFragmentStaticServerIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailFragmentStaticServerIT.kt index da634d4d62c6..f7696b344b89 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailFragmentStaticServerIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailFragmentStaticServerIT.kt @@ -79,11 +79,10 @@ class FileDetailFragmentStaticServerIT : AbstractIT() { var activity: TestActivity? = null scenario.onActivity { sut -> activity = sut - val fragment = ImageDetailFragment.newInstance(oCFile, user).apply { - hideMap() - } + val fragment = ImageDetailFragment.newInstance(oCFile, user) sut.addFragment(fragment) sut.supportFragmentManager.executePendingTransactions() + fragment.hideMap() } val screenShotName = createName(testClassName + "_" + "showFileDetailDetailsFragment", "") @@ -155,7 +154,11 @@ class FileDetailFragmentStaticServerIT : AbstractIT() { val fragment = FileDetailFragment.newInstance(oCFile, user, 0) sut.addFragment(fragment) sut.supportFragmentManager.executePendingTransactions() - fragment.fileDetailActivitiesFragment.populateList(activities as List?, true) + } + + scenario.onActivity { sut -> + (sut.fragment as FileDetailFragment) + .fileDetailActivitiesFragment.populateList(activities as List?, true) } val screenShotName = createName(testClassName + "_" + "showDetailsActivities", "") @@ -171,10 +174,14 @@ class FileDetailFragmentStaticServerIT : AbstractIT() { var activity: TestActivity? = null scenario.onActivity { sut -> activity = sut - val fragment = FileDetailFragment.newInstance(oCFile, user, 0) + val fragment = FileDetailFragment.newInstance(oCFile, user, 1) sut.addFragment(fragment) activity.supportFragmentManager.executePendingTransactions() - fragment.fileDetailActivitiesFragment.populateList(emptyList(), true) + } + + scenario.onActivity { sut -> + (sut.fragment as FileDetailFragment) + .fileDetailActivitiesFragment.populateList(emptyList(), true) } val screenShotName = createName(testClassName + "_" + "showDetailsActivitiesNone", "") @@ -193,6 +200,10 @@ class FileDetailFragmentStaticServerIT : AbstractIT() { val fragment = FileDetailFragment.newInstance(oCFile, user, 0) sut.addFragment(fragment) sut.supportFragmentManager.executePendingTransactions() + } + + scenario.onActivity { sut -> + val fragment = sut.fragment as FileDetailFragment fragment.fileDetailActivitiesFragment.disableLoadingActivities() fragment.fileDetailActivitiesFragment.setErrorContent( targetContext.resources.getString(R.string.file_detail_activity_error) diff --git a/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt index 93fe006ffe70..eb86d192fa1a 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/fragment/FileDetailSharingFragmentIT.kt @@ -83,7 +83,7 @@ class FileDetailSharingFragmentIT : AbstractIT() { @Test @ScreenshotTest fun listSharesFileNone() { - show(file) + show(file, "listSharesFileNone") } @Test @@ -91,7 +91,7 @@ class FileDetailSharingFragmentIT : AbstractIT() { fun listSharesFileResharingNotAllowed() { file.permissions = "" - show(file) + show(file, "listSharesFileResharingNotAllowed") } @Test @@ -139,7 +139,7 @@ class FileDetailSharingFragmentIT : AbstractIT() { } } - show(file) + show(file, "listSharesDownloadLimit") } } @@ -256,11 +256,11 @@ class FileDetailSharingFragmentIT : AbstractIT() { } } - show(file) + show(file, "listSharesFileAllShareTypes") } } - private fun show(file: OCFile) { + private fun show(file: OCFile, testName: String) { launchActivity().use { scenario -> var activity: TestActivity? = null scenario.onActivity { sut -> @@ -269,7 +269,7 @@ class FileDetailSharingFragmentIT : AbstractIT() { sut.addFragment(fragment) } - val screenShotName = createName(testClassName + "_" + "show", "") + val screenShotName = createName(testClassName + "_" + testName, "") onView(isRoot()).check(matches(isDisplayed())) screenshotViaName(activity, screenShotName) } diff --git a/app/src/androidTest/java/com/owncloud/android/ui/fragment/OCFileListFragmentStaticServerIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/fragment/OCFileListFragmentStaticServerIT.kt index 59bf0b97f64f..f42004c51cd5 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/fragment/OCFileListFragmentStaticServerIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/fragment/OCFileListFragmentStaticServerIT.kt @@ -36,6 +36,7 @@ import com.owncloud.android.utils.MimeType import com.owncloud.android.utils.ScreenshotTest import org.hamcrest.Matchers.allOf import org.hamcrest.Matchers.not +import org.junit.After import org.junit.Assert import org.junit.Before import org.junit.Rule @@ -53,6 +54,11 @@ class OCFileListFragmentStaticServerIT : AbstractIT() { Intents.init() } + @After + fun releaseIntentRecording() { + Intents.release() + } + @Test @ScreenshotTest @Suppress("MagicNumber") From 05029eadae9034a809e8789e098a78e66dbb0f50 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 4 Mar 2026 09:18:54 +0100 Subject: [PATCH 12/16] wip Signed-off-by: tobiasKaminsky --- .../client/FileDisplayActivityScreenshotIT.kt | 2 +- .../com/nextcloud/client/SyncedFoldersActivityIT.kt | 11 ++++++++--- .../java/com/owncloud/android/ScreenshotsIT.kt | 2 +- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityScreenshotIT.kt b/app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityScreenshotIT.kt index 169b0c547635..840a5ae67630 100644 --- a/app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityScreenshotIT.kt +++ b/app/src/androidTest/java/com/nextcloud/client/FileDisplayActivityScreenshotIT.kt @@ -66,8 +66,8 @@ class FileDisplayActivityScreenshotIT : AbstractIT() { } } + // @ScreenshotTest disabled for now @Test - @ScreenshotTest fun showMediaThenAllFiles() { try { launchActivity().use { scenario -> diff --git a/app/src/androidTest/java/com/nextcloud/client/SyncedFoldersActivityIT.kt b/app/src/androidTest/java/com/nextcloud/client/SyncedFoldersActivityIT.kt index 6ae0157b6706..21b714a9d31c 100644 --- a/app/src/androidTest/java/com/nextcloud/client/SyncedFoldersActivityIT.kt +++ b/app/src/androidTest/java/com/nextcloud/client/SyncedFoldersActivityIT.kt @@ -75,7 +75,9 @@ class SyncedFoldersActivityIT : AbstractIT() { scenario.onActivity { sut -> val fragment = newInstance(item, 0) fragment!!.show(sut.supportFragmentManager, "") - screenshot(fragment.requireDialog().window?.decorView, screenShotName) + } + scenario.onActivity { sut -> + screenshotViaName(sut, screenShotName) } } } @@ -96,9 +98,12 @@ class SyncedFoldersActivityIT : AbstractIT() { sut.showPowerCheckDialog() } - val screenShotName = createName(testClassName + "_" + "showPowerCheckDialog", "") onView(isRoot()).check(matches(isDisplayed())) - screenshot(dialog!!.window?.decorView, screenShotName) + + scenario.onActivity { sut -> + val screenShotName = createName(testClassName + "_" + "showPowerCheckDialog", "") + screenshotViaName(sut, screenShotName) + } } } } diff --git a/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt b/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt index 6b7d24426f12..29499e3fe358 100644 --- a/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ScreenshotsIT.kt @@ -101,8 +101,8 @@ class ScreenshotsIT : AbstractIT() { } } + // @ScreenshotTest disabled for now @Test - @ScreenshotTest fun davdroidScreenshot() { launchActivity().use { onView(withText(R.string.prefs_category_more)).perform(scrollTo()) From 2b8356d076502fd61c6cd535b2d001e145c26ad1 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Thu, 5 Mar 2026 10:21:37 +0100 Subject: [PATCH 13/16] last fix Signed-off-by: tobiasKaminsky --- .../android/ui/activity/ManageAccountsActivityIT.kt | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/app/src/androidTest/java/com/owncloud/android/ui/activity/ManageAccountsActivityIT.kt b/app/src/androidTest/java/com/owncloud/android/ui/activity/ManageAccountsActivityIT.kt index 2d5cbe41ab88..51687a5da5ab 100644 --- a/app/src/androidTest/java/com/owncloud/android/ui/activity/ManageAccountsActivityIT.kt +++ b/app/src/androidTest/java/com/owncloud/android/ui/activity/ManageAccountsActivityIT.kt @@ -56,11 +56,13 @@ class ManageAccountsActivityIT : AbstractIT() { sut.showUser(user, userInfo) } - val screenShotName = createName(testClassName + "_" + "open", "") + val screenShotName = createName(testClassName + "_" + "userInfoDetail", "") onView(isRoot()).check(matches(isDisplayed())) + val a = getCurrentActivity() + scenario.onActivity { - screenshotViaName(getCurrentActivity(), screenShotName) + screenshotViaName(a, screenShotName) } } } From 4c60a2710c8f8968c5bbc7cfd8c0294edcf4a0e0 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Fri, 8 May 2026 07:30:37 +0200 Subject: [PATCH 14/16] wip Signed-off-by: tobiasKaminsky --- app/build.gradle.kts | 128 ++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 125 insertions(+), 3 deletions(-) diff --git a/app/build.gradle.kts b/app/build.gradle.kts index bb4f5f7b28fd..5ca3f7c9e729 100644 --- a/app/build.gradle.kts +++ b/app/build.gradle.kts @@ -30,7 +30,7 @@ plugins { alias(libs.plugins.detekt) // needed to make renovate run without shot, as shot requires Android SDK // https://github.com/pedrovgs/Shot/issues/300 - if (System.getenv("SHOT_TEST") == "true") alias(libs.plugins.shot) + alias(libs.plugins.shot) id("checkstyle") id("pmd") } @@ -38,6 +38,129 @@ apply(from = "${rootProject.projectDir}/jacoco.gradle.kts") println("Gradle uses Java ${Jvm.current()}") +// Shot 6.1.0 is incompatible with AGP 9 - it tries to use the removed AppExtension API. +// Manually register Shot tasks using the new ApplicationExtension API. +run { + val androidExt = extensions.getByType(com.android.build.api.dsl.ApplicationExtension::class.java) + val shotExt by lazy { extensions.getByType(ShotExtension::class.java) } + + // Configure ShotTask properties via reflection (Scala var setters aren't accessible from Kotlin) + fun configureShotTask( + task: com.karumi.shot.tasks.ShotTask, + flavorOpt: Any, buildTypeName: String, appId: String, adbPath: String + ) { + val cls = com.karumi.shot.tasks.ShotTask::class.java + fun setField(name: String, value: Any?) { + cls.getDeclaredField(name).apply { isAccessible = true; set(task, value) } + } + setField("flavor", flavorOpt) + setField("buildTypeName", buildTypeName) + setField("appId", appId) + setField("orchestrated", false) + setField("projectPath", projectDir.absolutePath) + setField("buildPath", layout.buildDirectory.get().asFile.absolutePath) + setField("shotExtension", shotExt) + setField("directorySuffix", + if (project.hasProperty("directorySuffix")) + scala.Some(project.property("directorySuffix").toString()) + else scala.Option.empty()) + setField("recordScreenshots", project.hasProperty("record")) + setField("printBase64", project.hasProperty("printBase64")) + setField("projectName", project.name) + setField("adbPath", adbPath) + } + + afterEvaluate { + // Only register if Shot's own registration failed (no executeScreenshotTests task) + if (tasks.names.none { it == "executeScreenshotTests" }) { + val baseTask = tasks.register( + "executeScreenshotTests", + com.karumi.shot.tasks.ExecuteScreenshotTestsForEveryFlavor::class.java + ) + + val adbPath = try { + com.karumi.shot.AdbPathExtractor.extractPath(project) ?: "" + } catch (_: Throwable) { + val sdkDir = System.getenv("ANDROID_HOME") ?: System.getenv("ANDROID_SDK_ROOT") ?: "" + "$sdkDir/platform-tools/adb" + } + + val flavors = androidExt.productFlavors.map { it.name } + val buildTypes = androidExt.buildTypes.map { it.name } + + for (buildTypeName in buildTypes) { + val flavorList = flavors.ifEmpty { listOf("") } + for (flavorName in flavorList) { + val prefix = if (flavorName.isEmpty()) buildTypeName + else "$flavorName${buildTypeName.replaceFirstChar { it.uppercase() }}" + + val flavorOpt: Any = if (flavorName.isNotEmpty()) + scala.Some(flavorName) else scala.Option.empty() + val appId = (androidExt.defaultConfig.testApplicationId + ?: "${androidExt.defaultConfig.applicationId ?: androidExt.namespace}.test") + + val instrTaskName = + "connected${flavorName.replaceFirstChar { it.uppercase() }}${buildTypeName.replaceFirstChar { it.uppercase() }}AndroidTest" + + // Skip variants where the instrumentation task doesn't exist + val instrTask = try { tasks.named(instrTaskName) } catch (_: Throwable) { continue } + + val removeBefore = tasks.register( + "${prefix}RemoveScreenshotsBefore", + com.karumi.shot.tasks.RemoveScreenshotsTask::class.java + ) + removeBefore.configure(Action { + configureShotTask(this, flavorOpt, buildTypeName, appId, adbPath) + }) + + val removeAfter = tasks.register( + "${prefix}RemoveScreenshotsAfter", + com.karumi.shot.tasks.RemoveScreenshotsTask::class.java + ) + removeAfter.configure(Action { + configureShotTask(this, flavorOpt, buildTypeName, appId, adbPath) + }) + + val download = tasks.register( + "${prefix}DownloadScreenshots", + com.karumi.shot.tasks.DownloadScreenshotsTask::class.java + ) + download.configure(Action { + configureShotTask(this, flavorOpt, buildTypeName, appId, adbPath) + }) + + val execute = tasks.register( + "${prefix}ExecuteScreenshotTests", + com.karumi.shot.tasks.ExecuteScreenshotTests::class.java + ) + execute.configure(Action { + configureShotTask(this, flavorOpt, buildTypeName, appId, adbPath) + }) + + if (shotExt.runInstrumentation) { + execute.configure(Action { + dependsOn(instrTask) + dependsOn(download) + dependsOn(removeAfter) + }) + download.configure(Action { + mustRunAfter(instrTask) + }) + instrTask.configure { dependsOn(removeBefore) } + removeAfter.configure(Action { + mustRunAfter(download) + }) + } + + baseTask.configure(Action { + dependsOn(execute) + }) + } + } + } + } +} + configurations.configureEach { // via prism4j, already using annotations explicitly exclude(group = "org.jetbrains", module = "annotations-java5") @@ -115,8 +238,7 @@ android { buildConfigField("boolean", "RUNTIME_PERF_ANALYSIS", perfAnalysis.toString()) // arguments to be passed to functional tests - testInstrumentationRunner = if (shotTest) "com.karumi.shot.ShotTestRunner" - else "com.nextcloud.client.TestRunner" + testInstrumentationRunner = "com.karumi.shot.ShotTestRunner" versionCode = versionMajor * 10000000 + versionMinor * 10000 + versionPatch * 100 + versionBuild versionName = when { From fbe0f45c98ba659266f62da5cd5989c82e0742b8 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 1 Jul 2026 09:20:53 +0200 Subject: [PATCH 15/16] test Signed-off-by: tobiasKaminsky --- .github/workflows/QA_keystore.jks | Bin 2236 -> 0 bytes .github/workflows/QA_keystore.jks.license | 2 - .github/workflows/ai-policy.yml | 179 ------------------- .github/workflows/analysis.yml | 76 -------- .github/workflows/assembleFlavors.yml | 38 ---- .github/workflows/autoApproveSync.yml | 40 ----- .github/workflows/check.yml | 32 ---- .github/workflows/codeql.yml | 60 ------- .github/workflows/detectNewJavaFiles.yml | 43 ----- .github/workflows/detectWrongSettings.yml | 30 ---- .github/workflows/lint-translations.yml | 39 ---- .github/workflows/pr-feedback.yml | 55 ------ .github/workflows/qa.yml | 85 --------- .github/workflows/renovate-approve-merge.yml | 61 ------- .github/workflows/reuse.yml | 27 --- .github/workflows/scorecard.yml | 47 ----- .github/workflows/screenShotTest.yml | 2 +- .github/workflows/stale.yml | 35 ---- .github/workflows/unit-tests.yml | 64 ------- .github/workflows/uploadArtifact.sh | 44 ----- 20 files changed, 1 insertion(+), 958 deletions(-) delete mode 100644 .github/workflows/QA_keystore.jks delete mode 100644 .github/workflows/QA_keystore.jks.license delete mode 100644 .github/workflows/ai-policy.yml delete mode 100644 .github/workflows/analysis.yml delete mode 100644 .github/workflows/assembleFlavors.yml delete mode 100644 .github/workflows/autoApproveSync.yml delete mode 100644 .github/workflows/check.yml delete mode 100644 .github/workflows/codeql.yml delete mode 100644 .github/workflows/detectNewJavaFiles.yml delete mode 100644 .github/workflows/detectWrongSettings.yml delete mode 100644 .github/workflows/lint-translations.yml delete mode 100644 .github/workflows/pr-feedback.yml delete mode 100644 .github/workflows/qa.yml delete mode 100644 .github/workflows/renovate-approve-merge.yml delete mode 100644 .github/workflows/reuse.yml delete mode 100644 .github/workflows/scorecard.yml delete mode 100644 .github/workflows/stale.yml delete mode 100644 .github/workflows/unit-tests.yml delete mode 100755 .github/workflows/uploadArtifact.sh diff --git a/.github/workflows/QA_keystore.jks b/.github/workflows/QA_keystore.jks deleted file mode 100644 index 2b8fb9bc231219ab7954a6e0a5fea47b5f4c61f8..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 2236 zcmcgt`9IW)8lKg@kEN{RL?XslW*AFZ!%cRw-mGI^n^Bg8F(k_{UE4Sk8cQTmBn(A} zO7`r_ZH_IHIfJYnozMN@`~~-i=ktD^_xK2mCAPyh1C@*{GL|Jkudx-w>OKXC?vhk ziw{3S_>|W)AO_eS9k#-ENL^Aj;q|qfm$xxV3|t_)xS8*8(pw9~MVw-hX5j1z6+y}R zI)a(9WpRX|sN6xYedH!8^2>73CH<|q*Evl-aO@S4g18~$!DZ>dXA$F#?*UfA=ZXI$ z%+1&+SeQ?USmc;XvG4Fy3sChW_4^>n#j9Hfn|M{qpiX%EsXIU9K8hFHI6)uh-E}VZ z-+qI}k^8zz=*vMV)$ne{t)}-fKe7oPDnbfq z#i^F?#Hsnb$zWWkb1!D^$4KMSrlQeu!qLY39-f8|^*6NQC67D&X?mr&+W1*ZzWM0j z#Y(w+A59X}S)X*UB%iBJclT9iQFVvQkhb=y%N6KLz3pF|BE~AUaPmE@bdTvngaUs+ zWGi0_8!$G#p{LF>UUT9wNAAZ@H=kYM`EaoI;#MzK`C)GO+X=F4G5HOHwvz?grUs_V1=f}u zGj*&z`X$aK-q?xDoK4mGcbj2esbkiPMzmsCQG9T(-x2OYi1(AG5)L@Km9<@rk&^s% zhngeJd=7WWW*$cIO3mbvZSIarYpZAdh-*xxFSO`-s~)=w!)Qt)yRhZ#Hf^TPEn5CK zX5~^R#AtF@5&lqRF#wlF`CM^&<)E8S4tvlo{acQJeUm;0LJ3#j-Sws2EfcT^Z58KS z=!{hh5~h{o&ICEF8E#qEs!$o*deZI2ZOHa@ijsW!m_JXx*PS)R(`Tet_Z@i7Mjd<% zi}tV-s$-k_tQnGe4(AcG=h?E}ciWV2Ewl%gdOdU(^leWxN!d0%El5C*UQIhy2G3cr zy5we;xLn?jKej|Of%GQ>I4avZU8O9jOG9VvK9i?fd?OtcKxx2QPT8T9iJQ|Z2J-y? z`gjo?|1MjF47P+JhWuv9hwfXN5aAd4lWr2E4t&w1srk7lE~9C6>>yCGKc5;YGG6}B z8BOmZOJPYq%-PQB(x%Ss!=bu7zqLS#*d5mZ7V7!JGbGDv;`gKhaS+@dF1sucAD8Gs za(Tr;%=i&QWQuFvyn%$h{^NB{X0|y;W`2MPbDnWe1y8h&QminbDWzz5t%ijQjhSeC zKvgapvTRjM_SwncWihMC9#~6=enRY8!QlM&3JfcHd5N4r$#QH%bO-NEtY;hhdG`<4 zj#yO3Eq$%ZPxIfwrEi~#;Yj{Q-xHEy2}oVF7<21!RG2deypsv-*42m@{POcrN>|vt z)W3vPZf-yqZS&EhQA}qn`iLM)y^?blv)QbON$oHUesj2xTL%3;m(frU*Dff(v^1!7 zn&vVFzENZ%^8NfUo;1R-GA`C8nOXbOFw`35y7jj!!kthUKnnzd-U5hFJV1oFmOvq3 z2n1#d3LF4<**KL_%u;rF!C>wa!wgj81~}QE4lp(Z#Q3tBFd+1ca3HviaghYPw|}r_ zsE?WuAn>cpj^MN-L=p&oo;L_;Vt~l69v6bo5*J1A4i1a-L7IkmnW>!uM1KvS2!8u8 zuK-Ux(%ds7AQT@I4M>aes%ZfjH4K2gfCexwV!Y^+0$~3~|F63c!N2`eij$mx62bf@ z0RrZN5W!$j{%p^^+JTu;J+}LdWFYm-&U+Jd)BCRZIj&$U%2)QcF9#Bo6%3#?3mqBP zrk;BVL>D0!seN1WS@X6Jtl4L#dn|3{qNFnbmk+g;T(fBuhDMKqsk;8t?EXy0jZXJI zCA((NMz0sn)9`npsLM~Q9qOk`S|*WXH-4EC+>ko`INs8d1Cd{7QY_)Bx%|?whSQKc zCD$)A_{m`L3@Or?JV?^6=O#SAH7X7s(2;9!4K4gbvSIgkc0H-F!k(@0BU6tgtr}H> z<{{1sY}a;~C{y@zhibG#wdfmldEsXx0eT`f+M~tIx9rUtNj|)u>+3h$sJaA|e>1 zE2XtjlFmws>Eoxe1O%&=x}eu|1=B7(Cz#TbsLA2Ja~CA_{Du%CKX+}sc+SzKif{HC zmAa@GJU*VWb!4o(8oOR1uu>JJu1U(BAxxY%*?g@lsQJ+s{U>`zjt8>s)R)3W^9*m% zy0(2ei3sV2Rb^E(^~S5LotF$nAH)oC+dvK=Ktlc&rHAWKMRXEaCG5{ zY*O!q6zS$`d5aba;ezKw6zPfFl@Iv3rs^uXX#BU6){Mr}lwDBQaHBjI)R@jp UT$x~>$nZXtB6{SH*t-|@7tCJSiU0rr diff --git a/.github/workflows/QA_keystore.jks.license b/.github/workflows/QA_keystore.jks.license deleted file mode 100644 index f070b8a4c019..000000000000 --- a/.github/workflows/QA_keystore.jks.license +++ /dev/null @@ -1,2 +0,0 @@ -SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors -SPDX-License-Identifier: AGPL-3.0-or-later diff --git a/.github/workflows/ai-policy.yml b/.github/workflows/ai-policy.yml deleted file mode 100644 index d5821194922c..000000000000 --- a/.github/workflows/ai-policy.yml +++ /dev/null @@ -1,179 +0,0 @@ -# This workflow is provided via the organization template repository -# -# https://github.com/nextcloud/.github -# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization -# -# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors -# SPDX-License-Identifier: MIT - -name: AI Policy - -on: - pull_request: - types: [opened, synchronize, reopened] - branches: [master, main] - -permissions: - contents: read - # Required to add the "AI assisted" label via `gh pr edit --add-label` - pull-requests: write - # Required to create the "AI assisted" label via the REST labels endpoint - # (labels are an issues-scoped resource in the GitHub API) - issues: write - -concurrency: - group: ai-policy-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - check-ai-trailers: - runs-on: ubuntu-latest - steps: - - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - fetch-depth: 0 - persist-credentials: false - - - name: Collect PR commit messages - id: collect - env: - BASE_REF: ${{ github.base_ref }} - run: | - set -euo pipefail - git fetch origin "${BASE_REF}" - MERGE_BASE=$(git merge-base "origin/${BASE_REF}" HEAD) - git log --format="%B" "${MERGE_BASE}..HEAD" > /tmp/pr_commits.txt - echo "--- PR commit messages ---" - cat /tmp/pr_commits.txt - echo "--------------------------" - - - name: Define shared agent detection patterns - run: | - set -euo pipefail - - # Email addresses known to be used by coding agents. - # These should never appear in Signed-off-by because the DCO can only be attested by a human. - EMAIL_PATTERN="copilot@github\.com\ - |noreply@anthropic\.com\ - |devin@cognition\.ai\ - |devin@cognition-labs\.com\ - |aider@aider\.chat\ - |noreply@aider\.chat\ - |codex@openai\.com\ - |cursor@anysphere\.com\ - |windsurf@codeium\.com\ - |codeium@codeium\.com\ - |amazon-q@amazon\.com\ - |codewhisperer@amazon\.com\ - |gemini-code-assist@google\.com\ - |openhands@all-hands\.dev\ - |swe-agent@princeton\.edu" - - # Strip embedded whitespace (used above only for readability) - EMAIL_PATTERN=$(echo "$EMAIL_PATTERN" | tr -d ' \n') - echo "AGENT_EMAIL_PATTERN=${EMAIL_PATTERN}" >> "$GITHUB_ENV" - - # Display-name prefixes used by known coding agents (shared by Signed-off-by and Co-Authored-By checks) - # shellcheck disable=SC2016 - echo 'AGENT_NAMES=GitHub Copilot|Claude( [A-Za-z0-9. -]+)?|Devin( AI)?|aider( \(.*\))?|OpenAI Codex|Cursor( AI)?|Windsurf|Amazon Q|CodeWhisperer|Gemini Code Assist|OpenHands|SWE-agent|AutoCodeRover|Tabnine' >> "$GITHUB_ENV" - - - name: Check for AI-assistant / Assisted-by trailers - id: ai_trailers - run: | - set -euo pipefail - AI_ASSISTED=false - if grep -qiE '^(AI-assistant|Assisted-by):' /tmp/pr_commits.txt; then - AI_ASSISTED=true - echo "Found AI-assistant/Assisted-by trailer(s):" - grep -iE '^(AI-assistant|Assisted-by):' /tmp/pr_commits.txt - fi - echo "ai_assisted=${AI_ASSISTED}" >> "$GITHUB_OUTPUT" - - - name: Check for coding-agent Signed-off-by trailers - id: agent_signoff - run: | - set -euo pipefail - - EMAIL_HITS=$(grep -iE "^Signed-off-by:.*<(${AGENT_EMAIL_PATTERN})>" /tmp/pr_commits.txt 2>/dev/null || true) - NAME_HITS=$(grep -iE "^Signed-off-by: *(${AGENT_NAMES}) *[<(]" /tmp/pr_commits.txt 2>/dev/null || true) - - AGENT_LINES=$(printf '%s\n%s' "$EMAIL_HITS" "$NAME_HITS" | sort -u | sed '/^[[:space:]]*$/d') - - AGENT_SIGNOFF=false - if [ -n "$AGENT_LINES" ]; then - AGENT_SIGNOFF=true - fi - - echo "agent_signoff=${AGENT_SIGNOFF}" >> "$GITHUB_OUTPUT" - { - echo "agent_lines<> "$GITHUB_OUTPUT" - - - name: Check for coding-agent Co-Authored-By trailers - id: co_authored - run: | - set -euo pipefail - - EMAIL_HITS=$(grep -iE "^Co-Authored-By:.*<(${AGENT_EMAIL_PATTERN})>" /tmp/pr_commits.txt 2>/dev/null || true) - NAME_HITS=$(grep -iE "^Co-Authored-By: *(${AGENT_NAMES}) *[<(]" /tmp/pr_commits.txt 2>/dev/null || true) - - CO_AUTHORED=false - if [ -n "$EMAIL_HITS" ] || [ -n "$NAME_HITS" ]; then - CO_AUTHORED=true - echo "Found coding-agent Co-Authored-By trailer(s):" - printf '%s\n%s' "$EMAIL_HITS" "$NAME_HITS" | sort -u | sed '/^[[:space:]]*$/d' - fi - - echo "co_authored=${CO_AUTHORED}" >> "$GITHUB_OUTPUT" - - - name: Create 'AI assisted' label if absent - if: steps.ai_trailers.outputs.ai_assisted == 'true' || steps.agent_signoff.outputs.agent_signoff == 'true' || steps.co_authored.outputs.co_authored == 'true' - env: - GH_TOKEN: ${{ github.token }} - run: | - gh api "repos/${{ github.repository }}/labels" \ - --method POST \ - -f name="AI assisted" \ - -f color="d93f0b" \ - -f description="This PR contains AI-assisted commits" \ - 2>/dev/null || true - - - name: Label PR as AI assisted - if: steps.ai_trailers.outputs.ai_assisted == 'true' || steps.agent_signoff.outputs.agent_signoff == 'true' || steps.co_authored.outputs.co_authored == 'true' - env: - GH_TOKEN: ${{ github.token }} - run: | - gh pr edit "${{ github.event.pull_request.number }}" \ - --repo "${{ github.repository }}" \ - --add-label "AI assisted" - echo "Added 'AI assisted' label to PR #${{ github.event.pull_request.number }}" - - - name: Fail on coding-agent Signed-off-by - if: steps.agent_signoff.outputs.agent_signoff == 'true' - env: - AGENT_LINES: ${{ steps.agent_signoff.outputs.agent_lines }} - AGENTS_MD_URL: https://github.com/${{ github.repository }}/blob/${{ github.base_ref }}/AGENTS.md - run: | - echo "::error title=Coding-agent sign-off detected::A Signed-off-by trailer from a known coding agent was found in one or more commits." - echo "" - echo "Offending trailer(s):" - echo "${AGENT_LINES}" - echo "" - echo "The 'Signed-off-by' trailer represents the Developer Certificate of Origin (DCO)" - echo "and must only be attested by a human contributor." - echo "Please amend the affected commit(s) to remove the coding-agent sign-off" - echo "and replace it with an 'Assisted-by' trailer, for example:" - echo "" - echo " Assisted-by: Claude Code:claude-sonnet-4-6" - echo "" - echo "References:" - echo " • AGENTS.md (this repository)" - echo " ${AGENTS_MD_URL}" - echo " • AI Contribution Policy" - echo " https://github.com/nextcloud/.github/blob/master/AI_POLICY.md" - echo " • Contribution Guidelines" - echo " https://github.com/nextcloud/.github/blob/master/CONTRIBUTING.md" - exit 1 diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml deleted file mode 100644 index 1336bd22c5e8..000000000000 --- a/.github/workflows/analysis.yml +++ /dev/null @@ -1,76 +0,0 @@ -# synced from @nextcloud/android-config - -# SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2025 Alper Ozturk -# SPDX-FileCopyrightText: 2023 Tobias Kaminsky -# SPDX-FileCopyrightText: 2023 Andy Scherzinger -# SPDX-FileCopyrightText: 2023 Josh Richards -# SPDX-FileCopyrightText: 2025 Marcel Hibbe -# SPDX-License-Identifier: GPL-3.0-or-later - -name: "Analysis" - -on: - pull_request: - branches: [ "master", "main", "stable-*" ] - push: - branches: [ "master", "main", "stable-*" ] - -permissions: - pull-requests: write - contents: write - -concurrency: - group: analysis-wrapper-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - analysis: - runs-on: ubuntu-latest - steps: - - name: Disabled on forks - if: ${{ github.event_name == 'pull_request' && github.event.pull_request.head.repo.full_name != github.repository }} - run: | - echo 'Can not analyze PRs from forks' - exit 1 - - name: Setup variables # zizmor: ignore[template-injection] - id: get-vars - run: | - if [ -z "$GITHUB_HEAD_REF" ]; then - # push - { - echo "branch=$GITHUB_REF_NAME" - echo "pr=$GITHUB_RUN_ID" - echo "repo=${{ github.repository }}" - } >> "$GITHUB_OUTPUT" - else - # pull request - { - echo "branch=$GITHUB_HEAD_REF" - echo "pr=${{ github.event.pull_request.number }}" - echo "repo=${{ github.event.pull_request.head.repo.full_name }}" - } >> "$GITHUB_OUTPUT" - fi - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - repository: ${{ steps.get-vars.outputs.repo }} - ref: ${{ steps.get-vars.outputs.branch }} - - name: Set up JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 - with: - distribution: "temurin" - java-version: 21 - - name: Install dependencies - run: | - sudo apt install python3-defusedxml - - name: Run analysis wrapper - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - mkdir -p "$HOME/.gradle" - { - echo "org.gradle.jvmargs=-Xmx1g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8" - echo "org.gradle.configureondemand=true" - } > "$HOME/.gradle/gradle.properties" - scripts/analysis/analysis-wrapper.sh "${{ steps.get-vars.outputs.branch }}" "${{ secrets.LOG_USERNAME }}" "${{ secrets.LOG_PASSWORD }}" "$GITHUB_RUN_NUMBER" "${{ steps.get-vars.outputs.pr }}" diff --git a/.github/workflows/assembleFlavors.yml b/.github/workflows/assembleFlavors.yml deleted file mode 100644 index 7daa593b8549..000000000000 --- a/.github/workflows/assembleFlavors.yml +++ /dev/null @@ -1,38 +0,0 @@ -# SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only - -name: "Assemble" - -on: - pull_request: - branches: [ master, stable-* ] - -# Declare default permissions as read only. -permissions: read-all - -concurrency: - group: assemble-flavors-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - flavor: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - flavor: [ Generic, Gplay, Huawei ] - steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - name: set up JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 - with: - distribution: "temurin" - java-version: 21 - - uses: gradle/actions/wrapper-validation@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0 - - name: Build ${{ matrix.flavor }} - run: | - echo "org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g" >> gradle.properties - echo "org.gradle.caching=true" >> gradle.properties - echo "org.gradle.parallel=true" >> gradle.properties - echo "org.gradle.configureondemand=true" >> gradle.properties - ./gradlew assemble${{ matrix.flavor }} diff --git a/.github/workflows/autoApproveSync.yml b/.github/workflows/autoApproveSync.yml deleted file mode 100644 index c215be0b3e89..000000000000 --- a/.github/workflows/autoApproveSync.yml +++ /dev/null @@ -1,40 +0,0 @@ -# synced from @nextcloud/android-config - -# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2023 Álvaro Brey -# SPDX-License-Identifier: GPL-3.0-or-later - -name: Auto approve sync -on: - pull_request_target: # zizmor: ignore[dangerous-triggers] - branches: - - master - - main - types: - - opened - - reopened - - synchronize - - labeled - -concurrency: - group: sync-approve-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -permissions: - pull-requests: write - -jobs: - auto-approve: - name: Auto approve sync - runs-on: ubuntu-latest - if: ${{ contains(github.event.pull_request.labels.*.name, 'sync') && github.actor == 'nextcloud-android-bot' }} - steps: - - name: Disabled on forks - if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} - run: | - echo 'Can not approve PRs from forks' - exit 1 - - - uses: hmarr/auto-approve-action@f0939ea97e9205ef24d872e76833fa908a770363 # v4.0.0 - with: - github-token: "${{ secrets.GITHUB_TOKEN }}" diff --git a/.github/workflows/check.yml b/.github/workflows/check.yml deleted file mode 100644 index 10291d65456a..000000000000 --- a/.github/workflows/check.yml +++ /dev/null @@ -1,32 +0,0 @@ -# SPDX-FileCopyrightText: 2020-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only - -name: Check - -on: - pull_request: - branches: [ master, stable-* ] - -# Declare default permissions as read only. -permissions: read-all - -concurrency: - group: check-kotlin-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - check: - runs-on: ubuntu-latest - strategy: - fail-fast: false - matrix: - task: [ detekt, spotlessKotlinCheck, lint ] - steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - name: Set up JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 - with: - distribution: "temurin" - java-version: 21 - - name: Check ${{ matrix.task }} - run: ./gradlew ${{ matrix.task }} diff --git a/.github/workflows/codeql.yml b/.github/workflows/codeql.yml deleted file mode 100644 index 3592a0d05519..000000000000 --- a/.github/workflows/codeql.yml +++ /dev/null @@ -1,60 +0,0 @@ -# synced from @nextcloud/android-config - -# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2023-2024 Andy Scherzinger -# SPDX-FileCopyrightText: 2022 Tobias Kaminsky -# SPDX-FileCopyrightText: 2022 Álvaro Brey -# SPDX-FileCopyrightText: 2025 Marcel Hibbe -# SPDX-License-Identifier: GPL-3.0-or-later - -name: "CodeQL" - -on: - push: - branches: [ "master", "main", "stable-*" ] - pull_request: - branches: [ "master", "main" ] - schedule: - - cron: '24 18 * * 3' - -permissions: - contents: read - -jobs: - analyze: - name: Analyze - runs-on: ubuntu-latest - permissions: - actions: read - contents: read - security-events: write - strategy: - fail-fast: false - matrix: - language: [ 'java' ] - steps: - - name: Checkout repository - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - - name: Set Swap Space - if: runner.environment == 'github-hosted' - uses: pierotofy/set-swap-space@49819abfb41bd9b44fb781159c033dba90353a7c # v1.0 - with: - swap-size-gb: 10 - - name: Initialize CodeQL - uses: github/codeql-action/init@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 - with: - languages: ${{ matrix.language }} - - name: Set up JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 - with: - distribution: "temurin" - java-version: 21 - - name: Assemble - run: | - mkdir -p "$HOME/.gradle" - echo "org.gradle.jvmargs=-Xmx3g -XX:MaxMetaspaceSize=512m -XX:+HeapDumpOnOutOfMemoryError" > "$HOME/.gradle/gradle.properties" - ./gradlew --no-daemon assembleDebug - - name: Perform CodeQL Analysis - uses: github/codeql-action/analyze@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 diff --git a/.github/workflows/detectNewJavaFiles.yml b/.github/workflows/detectNewJavaFiles.yml deleted file mode 100644 index 908e3fd288f8..000000000000 --- a/.github/workflows/detectNewJavaFiles.yml +++ /dev/null @@ -1,43 +0,0 @@ -# synced from @nextcloud/android-config - -# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2023 Andy Scherzinger -# SPDX-FileCopyrightText: 2022 Tobias Kaminsky -# SPDX-FileCopyrightText: 2022 Álvaro Brey -# SPDX-License-Identifier: GPL-3.0-or-later - -name: "Detect new java files" - -on: - pull_request: - branches: [ master, main, stable-* ] - -permissions: read-all - -concurrency: - group: detect-new-java-files-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - detectNewJavaFiles: - runs-on: ubuntu-latest - steps: - - id: file_changes - uses: trilom/file-changes-action@a6ca26c14274c33b15e6499323aac178af06ad4b # v1.2.4 - with: - output: ',' - - name: Detect new java files - run: | - if [ -z '${{ steps.file_changes.outputs.files_added }}' ]; then - echo "No new files added" - exit 0 - fi - new_java=$(echo '${{ steps.file_changes.outputs.files_added }}' | tr ',' '\n' | grep '\.java$' | cat) - if [ -n "$new_java" ]; then - # shellcheck disable=SC2016 - printf 'New java files detected:\n```\n%s\n```\n' "$new_java" | tee "$GITHUB_STEP_SUMMARY" - exit 1 - else - echo "No new java files detected" - exit 0 - fi diff --git a/.github/workflows/detectWrongSettings.yml b/.github/workflows/detectWrongSettings.yml deleted file mode 100644 index 185b9cc7f36e..000000000000 --- a/.github/workflows/detectWrongSettings.yml +++ /dev/null @@ -1,30 +0,0 @@ -# SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2023 Tobias Kaminsky -# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only - -name: "Detect wrong settings" - -on: - pull_request: - branches: [ master, stable-* ] - -# Declare default permissions as read only. -permissions: read-all - -concurrency: - group: detect-wrong-settings-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - detectWrongSettings: - runs-on: ubuntu-24.04 - - steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - name: Set up JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 - with: - distribution: "temurin" - java-version: 21 - - name: Detect SNAPSHOT - run: scripts/analysis/detectWrongSettings.sh diff --git a/.github/workflows/lint-translations.yml b/.github/workflows/lint-translations.yml deleted file mode 100644 index ec1e35f53db2..000000000000 --- a/.github/workflows/lint-translations.yml +++ /dev/null @@ -1,39 +0,0 @@ -# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors -# SPDX-License-Identifier: MIT - -name: Lint translation files - -on: - pull_request: - branches: [ master, main, stable-* ] - push: - branches: [ master, main, stable-* ] - -permissions: - contents: read - -concurrency: - group: lint-php-cs-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - lint: - runs-on: ubuntu-latest-low - - name: translations-string-xml - - steps: - - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - - - name: Check for new lines in translation strings - id: counter - run: | - grep -P '' | grep '^0$' - - - name: Output - if: failure() - run: | - grep -P '' diff --git a/.github/workflows/pr-feedback.yml b/.github/workflows/pr-feedback.yml deleted file mode 100644 index a3a2d1296c7a..000000000000 --- a/.github/workflows/pr-feedback.yml +++ /dev/null @@ -1,55 +0,0 @@ -# This workflow is provided via the organization template repository -# -# https://github.com/nextcloud/.github -# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization - -# SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2023 Marcel Klehr -# SPDX-FileCopyrightText: 2023 Joas Schilling <213943+nickvergessen@users.noreply.github.com> -# SPDX-FileCopyrightText: 2023 Daniel Kesselberg -# SPDX-FileCopyrightText: 2023 Florian Steffens -# SPDX-License-Identifier: MIT - -name: 'Ask for feedback on PRs' -on: - schedule: - - cron: '30 1 * * *' - -permissions: - contents: read - pull-requests: write - -jobs: - pr-feedback: - if: ${{ github.repository_owner == 'nextcloud' }} - runs-on: ubuntu-latest - steps: - - name: The get-github-handles-from-website action - uses: marcelklehr/get-github-handles-from-website-action@06b2239db0a48fe1484ba0bfd966a3ab81a08308 # v1.0.1 - id: scrape - with: - website: 'https://nextcloud.com/team/' - - - name: Get blocklist - id: blocklist - run: | - blocklist=$(curl https://raw.githubusercontent.com/nextcloud/.github/master/non-community-usernames.txt | paste -s -d, -) - echo "blocklist=$blocklist" >> "$GITHUB_OUTPUT" - - - uses: nextcloud/pr-feedback-action@5227c55be184087d0aef6338bee210d8620b6297 # main - with: - feedback-message: | - Hello there, - Thank you so much for taking the time and effort to create a pull request to our Nextcloud project. - - We hope that the review process is going smooth and is helpful for you. We want to ensure your pull request is reviewed to your satisfaction. If you have a moment, our community management team would very much appreciate your feedback on your experience with this PR review process. - - Your feedback is valuable to us as we continuously strive to improve our community developer experience. Please take a moment to complete our short survey by clicking on the following link: https://cloud.nextcloud.com/apps/forms/s/i9Ago4EQRZ7TWxjfmeEpPkf6 - - Thank you for contributing to Nextcloud and we hope to hear from you soon! - - (If you believe you should not receive this message, you can add yourself to the [blocklist](https://github.com/nextcloud/.github/blob/master/non-community-usernames.txt).) - days-before-feedback: 14 - start-date: '2024-04-30' - exempt-authors: '${{ steps.blocklist.outputs.blocklist }},${{ steps.scrape.outputs.users }}' - exempt-bots: true diff --git a/.github/workflows/qa.yml b/.github/workflows/qa.yml deleted file mode 100644 index 650c6b49759f..000000000000 --- a/.github/workflows/qa.yml +++ /dev/null @@ -1,85 +0,0 @@ -# SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2023 Andy Scherzinger -# SPDX-License-Identifier: MIT -name: "QA" - -on: - pull_request: - branches: [ main, master, stable-* ] - -permissions: - pull-requests: write - contents: read - -concurrency: - group: qa-build-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - qa: - runs-on: ubuntu-latest - steps: - - name: Check if secrets are available - run: echo "ok=${{ secrets.KS_PASS != '' }}" >> "$GITHUB_OUTPUT" - id: check-secrets - - - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - if: ${{ steps.check-secrets.outputs.ok == 'true' }} - with: - persist-credentials: false - - - name: set up JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 - if: ${{ steps.check-secrets.outputs.ok == 'true' }} - with: - distribution: "temurin" - java-version: 21 - - - name: Build QA - if: ${{ steps.check-secrets.outputs.ok == 'true' }} - env: - KS_PASS: ${{ secrets.KS_PASS }} - KEY_PASS: ${{ secrets.KEY_PASS }} - LOG_USERNAME: ${{ secrets.LOG_USERNAME }} - LOG_PASSWORD: ${{ secrets.LOG_PASSWORD }} - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: | - mkdir -p "$HOME/.gradle" - echo "org.gradle.jvmargs=-Xmx3g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g" > "$HOME/.gradle/gradle.properties" - echo "org.gradle.caching=true; org.gradle.parallel=true; org.gradle.configureondemand=true" >> "$HOME/.gradle/gradle.properties" - [ -e app/build.gradle ] && sed -i "/qa/,/\}/ s/versionCode .*/versionCode ${{github.event.number}} /" "app/build.gradle" - [ -e app/build.gradle ] && sed -i "/qa/,/\}/ s/versionName .*/versionName \"${{github.event.number}}\"/" "app/build.gradle" - [ -e app/build.gradle.kts ] && sed -i "/qa/,/\}/ s/versionCode .*/versionCode = ${{github.event.number}} /" "app/build.gradle.kts" - [ -e app/build.gradle.kts ] && sed -i "/qa/,/\}/ s/versionName .*/versionName = \"${{github.event.number}}\"/" "app/build.gradle.kts" - ./gradlew assembleQaDebug - $(find /usr/local/lib/android/sdk/build-tools/*/apksigner | sort | tail -n1) sign --ks-pass pass:"$KS_PASS" --key-pass pass:"$KEY_PASS" --ks-key-alias key0 --ks ".github/workflows/QA_keystore.jks" app/build/outputs/apk/qa/debug/*qa-debug*.apk - - - name: Upload APK - id: upload-apk - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f - with: - path: app/build/outputs/apk/qa/debug/*qa-debug*.apk - retention-days: 7 - archive: false - - - name: Create QR Code - run: | - sudo apt-get -y install qrencode - qrencode -o qr.png "${{ steps.upload-apk.outputs.artifact-url }}" - - - name: Upload QR - id: upload-qr - uses: actions/upload-artifact@bbbca2ddaa5d8feaa63e36b76fdaad77386f024f - with: - path: qr.png - retention-days: 7 - archive: false - - - name: Comment PR - uses: thollander/actions-comment-pull-request@e4a76dd2b0a3c2027c3fd84147a67c22ee4c90fa - with: - message: | - APK file: ${{ steps.upload-apk.outputs.artifact-url }} - To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app. - ![qrcode](${{ steps.upload-qr.outputs.artifact-url }}) (please click on link to get QR code displayed) diff --git a/.github/workflows/renovate-approve-merge.yml b/.github/workflows/renovate-approve-merge.yml deleted file mode 100644 index 004beab493ee..000000000000 --- a/.github/workflows/renovate-approve-merge.yml +++ /dev/null @@ -1,61 +0,0 @@ -# This workflow is provided via the organization template repository -# -# https://github.com/nextcloud/.github -# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization -# -# SPDX-FileCopyrightText: Nextcloud GmbH and Nextcloud contributors -# SPDX-License-Identifier: MIT - -name: Auto approve renovate PRs - -on: - pull_request_target: # zizmor: ignore[dangerous-triggers] - branches: - - main - - master - - stable* - -permissions: - contents: read - -concurrency: - group: renovate-approve-merge-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - auto-approve-merge: - if: github.event.pull_request.user.login == 'renovate[bot]' - runs-on: ubuntu-latest - permissions: - # for hmarr/auto-approve-action to approve PRs - pull-requests: write - - steps: - - name: Disabled on forks - if: ${{ github.event.pull_request.head.repo.full_name != github.repository }} - run: | - echo 'Can not approve PRs from forks' - exit 1 - - - uses: mdecoleman/pr-branch-name@55795d86b4566d300d237883103f052125cc7508 # v3.0.0 - id: branchname - with: - repo-token: ${{ secrets.GITHUB_TOKEN }} - - # GitHub actions bot approve - - uses: hmarr/auto-approve-action@f0939ea97e9205ef24d872e76833fa908a770363 # v4.0.0 - if: github.actor == 'renovate[bot]' - with: - github-token: ${{ secrets.GITHUB_TOKEN }} - - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - ref: ${{ github.head_ref }} - - # Enable GitHub auto merge - - name: Enable Pull Request Automerge - if: github.actor == 'renovate[bot]' - run: gh pr merge --merge --auto - env: - GH_TOKEN: ${{ secrets.AUTOMERGE }} - diff --git a/.github/workflows/reuse.yml b/.github/workflows/reuse.yml deleted file mode 100644 index 4e1a74194ecf..000000000000 --- a/.github/workflows/reuse.yml +++ /dev/null @@ -1,27 +0,0 @@ -# This workflow is provided via the organization template repository -# -# https://github.com/nextcloud/.github -# https://docs.github.com/en/actions/learn-github-actions/sharing-workflows-with-your-organization - -# SPDX-FileCopyrightText: 2022 Free Software Foundation Europe e.V. -# -# SPDX-License-Identifier: CC0-1.0 - -name: REUSE Compliance Check - -on: [pull_request] - -permissions: - contents: read - -jobs: - reuse-compliance-check: - runs-on: ubuntu-latest-low - steps: - - name: Checkout - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - - - name: REUSE Compliance Check - uses: fsfe/reuse-action@676e2d560c9a403aa252096d99fcab3e1132b0f5 # v6.0.0 diff --git a/.github/workflows/scorecard.yml b/.github/workflows/scorecard.yml deleted file mode 100644 index 14c6f9bca875..000000000000 --- a/.github/workflows/scorecard.yml +++ /dev/null @@ -1,47 +0,0 @@ -# synced from @nextcloud/android-config - -# SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2023 Andy Scherzinger -# SPDX-License-Identifier: GPL-3.0-or-later - -name: Scorecard supply-chain security -on: - branch_protection_rule: - schedule: - - cron: '32 23 * * 4' - push: - branches: [ "main", "master" ] - -# Declare default permissions as read only. -permissions: read-all - -concurrency: - group: scorecard-supply-chain-security-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - analysis: - name: Scorecard analysis - runs-on: ubuntu-latest - permissions: - # Needed to upload the results to code-scanning dashboard. - security-events: write - - steps: - - name: "Checkout code" - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - with: - persist-credentials: false - - - name: "Run analysis" - uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3 - with: - results_file: results.sarif - results_format: sarif - publish_results: false - - # Upload the results to GitHub's code scanning dashboard. - - name: "Upload to code-scanning" - uses: github/codeql-action/upload-sarif@8aad20d150bbac5944a9f9d289da16a4b0d87c1e # v4.36.2 - with: - sarif_file: results.sarif diff --git a/.github/workflows/screenShotTest.yml b/.github/workflows/screenShotTest.yml index 2e4277f6028c..9463f3ef3ac0 100644 --- a/.github/workflows/screenShotTest.yml +++ b/.github/workflows/screenShotTest.yml @@ -94,7 +94,7 @@ jobs: sdcard-path-or-size: 100M target: google_apis emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -skin 500x833 - script: ./gradlew uninstallAll genericDebugExecuteScreenshotTests -Dorg.gradle.jvmargs="--add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.nio.channels=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED" -Pandroid.testInstrumentationRunnerArguments.annotation=com.owncloud.android.utils.ScreenshotTest -Pandroid.testInstrumentationRunnerArguments.COLOR=${{ matrix.color }} -Pandroid.testInstrumentationRunnerArguments.DARKMODE=${{ matrix.scheme }} + script: SHOT_TEST=true ./gradlew uninstallAll app:executeScreenshotTests -Dorg.gradle.jvmargs="--add-opens java.base/java.nio=ALL-UNNAMED --add-opens java.base/java.nio.channels=ALL-UNNAMED --add-exports java.base/sun.nio.ch=ALL-UNNAMED" -Pandroid.testInstrumentationRunnerArguments.annotation=com.owncloud.android.utils.ScreenshotTest -Pandroid.testInstrumentationRunnerArguments.COLOR=${{ matrix.color }} -Pandroid.testInstrumentationRunnerArguments.DARKMODE=${{ matrix.scheme }} - name: upload failing results if: ${{ failure() }} env: diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml deleted file mode 100644 index 5f22d4a4cd21..000000000000 --- a/.github/workflows/stale.yml +++ /dev/null @@ -1,35 +0,0 @@ -# synced from @nextcloud/android-config - -# SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2023 Tobias Kaminsky -# SPDX-FileCopyrightText: 2022 Álvaro Brey -# SPDX-License-Identifier: GPL-3.0-or-later - -name: 'Close stale issues' -on: - schedule: - - cron: '0 0 * * *' - -# Declare default permissions as read only. -permissions: read-all - -jobs: - stale: - runs-on: ubuntu-latest - permissions: - issues: write - pull-requests: write - steps: - - uses: actions/stale@eb5cf3af3ac0a1aa4c9c45633dd1ae542a27a899 # v10.3.0 - with: - days-before-stale: 28 - days-before-close: 14 - days-before-pr-close: -1 - only-labels: 'bug,needs info' - exempt-issue-labels: 'no-stale' - stale-issue-message: >- - This bug report did not receive an update in the last 4 weeks. - Please take a look again and update the issue with new details, - otherwise the issue will be automatically closed in 2 weeks. Thank you! - exempt-all-pr-milestones: true - labels-to-remove-when-unstale: 'needs info' diff --git a/.github/workflows/unit-tests.yml b/.github/workflows/unit-tests.yml deleted file mode 100644 index cc9404ffcedb..000000000000 --- a/.github/workflows/unit-tests.yml +++ /dev/null @@ -1,64 +0,0 @@ -# SPDX-FileCopyrightText: 2022-2025 Nextcloud GmbH and contributors -# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only - -name: Unit tests - -on: - pull_request: - branches: [ master, stable-* ] - push: - branches: [ master, stable-* ] - -permissions: - contents: read - pull-requests: write - -concurrency: - group: unit-tests-${{ github.head_ref || github.run_id }} - cancel-in-progress: true - -jobs: - test: - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@9c091bb21b7c1c1d1991bb908d89e4e9dddfe3e0 # v7.0.0 - - - name: Set up JDK 21 - uses: actions/setup-java@ad2b38190b15e4d6bdf0c97fb4fca8412226d287 # v5.3.0 - with: - distribution: "temurin" - java-version: 21 - - - name: Delete old comments - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - if: ${{ always() }} - run: scripts/deleteOldComments.sh "test" "Unit" ${{github.event.number}} - - - name: Setup Gradle - uses: gradle/actions/setup-gradle@3f131e8634966bd73d06cc69884922b02e6faf92 # v6.2.0 - - - name: Run unit tests with coverage - run: ./gradlew jacocoTestGplayDebugUnitTest - - - name: Upload failing results - if: ${{ failure() }} - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - run: scripts/uploadReport.sh "${{ secrets.LOG_USERNAME }}" "${{ secrets.LOG_PASSWORD }}" ${{github.event.number}} "test" "Unit" ${{github.event.number}} - - - name: Upload coverage to codecov - uses: codecov/codecov-action@fb8b3582c8e4def4969c97caa2f19720cb33a72f # v7.0.0 - with: - token: ${{ secrets.CODECOV_TOKEN }} - flags: unit - fail_ci_if_error: true - files: app/build/reports/jacoco/jacocoTestGplayDebugUnitTestReport/jacoco.xml - - - name: Upload jacoco artifacts - if: ${{ failure() }} - uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1 - with: - name: test-results - path: app/build/reports/jacoco/jacocoTestGplayDebugUnitTestReport/html/ diff --git a/.github/workflows/uploadArtifact.sh b/.github/workflows/uploadArtifact.sh deleted file mode 100755 index bf96572045ab..000000000000 --- a/.github/workflows/uploadArtifact.sh +++ /dev/null @@ -1,44 +0,0 @@ -#!/usr/bin/env bash - -# -# SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors -# SPDX-FileCopyrightText: 2019-2022 Tobias Kaminsky -# SPDX-License-Identifier: AGPL-3.0-or-later -# - -#1: LOG_USERNAME -#2: LOG_PASSWORD -#3: DRONE_BUILD_NUMBER -#4: DRONE_PULL_REQUEST - - -PUBLIC_URL=https://www.kaminsky.me/nc-dev/android-artifacts -USER=$1 -PASS=$2 -BUILD=$3 -PR=$4 -GITHUB_TOKEN=$5 -DAV_URL=https://nextcloud.kaminsky.me/remote.php/dav/files/$USER/android-artifacts/ - -source .github/workflows/lib.sh -REPO=$(cat scripts/repo) - -if ! test -e app/build/outputs/apk/qa/debug/*qa-debug*.apk ; then - exit 1 -fi -echo "Uploaded artifact to $DAV_URL/$BUILD.apk" - -# delete all old comments, starting with "APK file:" -oldComments=$(curl_gh -X GET https://api.github.com/repos/nextcloud/$REPO/issues/$PR/comments | jq '.[] | (.id |tostring) + "|" + (.user.login | test("github-actions") | tostring) + "|" + (.body | test("APK file:.*") | tostring)' | grep "true|true" | tr -d "\"" | cut -f1 -d"|") - -echo $oldComments | while read comment ; do - curl_gh -X DELETE https://api.github.com/repos/nextcloud/$REPO/issues/comments/$comment -done - -sudo apt-get -y install qrencode - -qrencode -o $PR.png "$PUBLIC_URL/$BUILD.apk" - -curl -u $USER:$PASS -X PUT $DAV_URL/$BUILD.apk --upload-file app/build/outputs/apk/qa/debug/*qa-debug*.apk -curl -u $USER:$PASS -X PUT $DAV_URL/$BUILD.png --upload-file $PR.png -curl_gh -X POST https://api.github.com/repos/nextcloud/$REPO/issues/$PR/comments -d "{ \"body\" : \"APK file: $PUBLIC_URL/$BUILD.apk

![qrcode]($PUBLIC_URL/$BUILD.png)

To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app. \" }" From c5a1d2b20dbd93a64ab0199ed3c291fab2663100 Mon Sep 17 00:00:00 2001 From: tobiasKaminsky Date: Wed, 1 Jul 2026 12:39:50 +0200 Subject: [PATCH 16/16] x86_64 Signed-off-by: tobiasKaminsky --- .github/workflows/screenShotTest.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/screenShotTest.yml b/.github/workflows/screenShotTest.yml index 9463f3ef3ac0..08cc34de7372 100644 --- a/.github/workflows/screenShotTest.yml +++ b/.github/workflows/screenShotTest.yml @@ -90,7 +90,7 @@ jobs: with: api-level: ${{ matrix.api-level }} force-avd-creation: false - arch: x86 + arch: x86_64 sdcard-path-or-size: 100M target: google_apis emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -skin 500x833