diff --git a/.codecov.yml b/.codecov.yml
index b0f249ec41f4..bc7cbef7732b 100644
--- a/.codecov.yml
+++ b/.codecov.yml
@@ -1,7 +1,11 @@
+# SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
codecov:
branch: master
ci:
- drone.nextcloud.com
+ notify:
+ after_n_builds: 2
coverage:
precision: 2
@@ -15,7 +19,12 @@ coverage:
comment:
layout: "header, diff, changes, uncovered, tree"
behavior: default
+ require_changes: true
+ after_n_builds: 2
+
+github_checks:
+ annotations: false
ignore:
- - "src/main/res/values*/*"
-
+ - "app/src/main/res/values*/*"
+
diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile
new file mode 100644
index 000000000000..152027db4f00
--- /dev/null
+++ b/.devcontainer/Dockerfile
@@ -0,0 +1,19 @@
+FROM ubuntu:noble@sha256:84e77dee7d1bc93fb029a45e3c6cb9d8aa4831ccfcc7103d36e876938d28895b
+
+ARG DEBIAN_FRONTEND=noninteractive
+ENV ANDROID_HOME=/usr/lib/android-sdk
+
+RUN apt-get update -y
+RUN apt-get install -y unzip wget openjdk-21-jdk vim
+
+RUN wget https://dl.google.com/android/repository/commandlinetools-linux-6858069_latest.zip -O /tmp/commandlinetools.zip
+RUN cd /tmp && unzip commandlinetools.zip
+RUN mkdir -p /usr/lib/android-sdk/cmdline-tools/
+RUN cd /tmp/ && mv cmdline-tools/ latest/ && mv latest/ /usr/lib/android-sdk/cmdline-tools/
+RUN mkdir /usr/lib/android-sdk/licenses/
+RUN chmod -R 755 /usr/lib/android-sdk/
+RUN mkdir -p "$HOME/.gradle" && \
+ echo "org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g" > "$HOME/.gradle/gradle.properties" && \
+ echo "org.gradle.caching=true" >> "$HOME/.gradle/gradle.properties" && \
+ echo "org.gradle.parallel=true" >> "$HOME/.gradle/gradle.properties" && \
+ echo "org.gradle.configureondemand=true" >> "$HOME/.gradle/gradle.properties"
diff --git a/.devcontainer/Dockerfile.license b/.devcontainer/Dockerfile.license
new file mode 100644
index 000000000000..d078384126a1
--- /dev/null
+++ b/.devcontainer/Dockerfile.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
diff --git a/.devcontainer/README.md b/.devcontainer/README.md
new file mode 100644
index 000000000000..60bcf908c5b7
--- /dev/null
+++ b/.devcontainer/README.md
@@ -0,0 +1,9 @@
+
+# Instructions
+
+1. Start a DevContainer either on GitHub Codespaces or locally in VSCode.
+2. Accept all licenses by running `yes | /usr/lib/android-sdk/cmdline-tools/latest/bin/sdkmanager --licenses`.
+3. You can now build the app using `./gradlew clean build`.
diff --git a/.devcontainer/devcontainer.env b/.devcontainer/devcontainer.env
new file mode 100644
index 000000000000..369163cf4fcf
--- /dev/null
+++ b/.devcontainer/devcontainer.env
@@ -0,0 +1,3 @@
+ANDROID_HOME=/usr/lib/android-sdk
+JAVA_OPTS="-Xmx8192M"
+GRADLE_OPTS="-Dorg.gradle.daemon=true"
diff --git a/.devcontainer/devcontainer.env.license b/.devcontainer/devcontainer.env.license
new file mode 100644
index 000000000000..d078384126a1
--- /dev/null
+++ b/.devcontainer/devcontainer.env.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
diff --git a/.devcontainer/devcontainer.json b/.devcontainer/devcontainer.json
new file mode 100644
index 000000000000..a13d6f9ee4e8
--- /dev/null
+++ b/.devcontainer/devcontainer.json
@@ -0,0 +1,4 @@
+{
+ "name": "NextcloudAndroid",
+ "dockerFile": "Dockerfile",
+}
diff --git a/.devcontainer/devcontainer.json.license b/.devcontainer/devcontainer.json.license
new file mode 100644
index 000000000000..d078384126a1
--- /dev/null
+++ b/.devcontainer/devcontainer.json.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
diff --git a/.drone.yml b/.drone.yml
index b88c3fba2c44..4da327c6a57b 100644
--- a/.drone.yml
+++ b/.drone.yml
@@ -1,60 +1,81 @@
+---
kind: pipeline
type: docker
-name: generic
+name: tests-stable
+
+# SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
+
steps:
- - name: generic
- image: nextcloudci/android:android-49
+ - name: gplay
+ image: ghcr.io/nextcloud/continuous-integration-android16:latest
+ privileged: true
environment:
+ LOG_USERNAME:
+ from_secret: LOG_USERNAME
+ LOG_PASSWORD:
+ from_secret: LOG_PASSWORD
GIT_USERNAME:
from_secret: GIT_USERNAME
- GIT_TOKEN:
+ GITHUB_TOKEN:
from_secret: GIT_TOKEN
commands:
- - scripts/checkIfRunDrone.sh $GIT_USERNAME $GIT_TOKEN $DRONE_PULL_REQUEST || exit 0
- - ./gradlew assembleGeneric
+ - scripts/checkIfRunDrone.sh $DRONE_PULL_REQUEST || exit 0
+ - emulator -avd android -no-snapshot -gpu swiftshader_indirect -no-window -no-audio -skin 500x833 &
+ - sed -i s'#false#true#'g app/src/main/res/values/setup.xml
+ - ./gradlew assembleGplayDebugAndroidTest
+ - scripts/wait_for_emulator.sh
+ - ./gradlew installGplayDebugAndroidTest
+ - scripts/wait_for_server.sh "server"
+ - scripts/deleteOldComments.sh "stable" "IT" $DRONE_PULL_REQUEST
+ - ./gradlew createGplayDebugCoverageReport -Pcoverage -Pandroid.testInstrumentationRunnerArguments.notAnnotation=com.owncloud.android.utils.ScreenshotTest || scripts/uploadReport.sh $LOG_USERNAME $LOG_PASSWORD $DRONE_BUILD_NUMBER "stable" "IT" $DRONE_PULL_REQUEST
- - name: notify
- image: drillster/drone-email
- settings:
- port: 587
- from: nextcloud-drone@kaminsky.me
- recipients_only: true
- username:
- from_secret: EMAIL_USERNAME
- password:
- from_secret: EMAIL_PASSWORD
- recipients:
- from_secret: EMAIL_RECIPIENTS
- host:
- from_secret: EMAIL_HOST
- GIT_USERNAME:
- from_secret: GIT_USERNAME
- GIT_TOKEN:
- from_secret: GIT_TOKEN
- when:
- event:
- - push
- status:
- - failure
- branch:
- - master
+services:
+ - name: server
+ image: ghcr.io/nextcloud/continuous-integration-shallow-server:latest # also change in updateScreenshots.sh
+ environment:
+ EVAL: true
+ SERVER_VERSION: 'stable30'
+ commands:
+ - BRANCH="$SERVER_VERSION" /usr/local/bin/initnc.sh
+ - echo 127.0.0.1 server >> /etc/hosts
+ - rm /etc/apt/sources.list.d/php.list
+ - apt-get update && apt-get install -y composer
+ - su www-data -c "OC_PASS=user1 php /var/www/html/occ user:add --password-from-env --display-name='User One' user1"
+ - su www-data -c "OC_PASS=user2 php /var/www/html/occ user:add --password-from-env --display-name='User Two' user2"
+ - su www-data -c "OC_PASS=user3 php /var/www/html/occ user:add --password-from-env --display-name='User Three' user3"
+ - su www-data -c "php /var/www/html/occ user:setting user2 files quota 1G"
+ - su www-data -c "php /var/www/html/occ group:add users"
+ - su www-data -c "php /var/www/html/occ group:adduser users user1"
+ - su www-data -c "php /var/www/html/occ group:adduser users user2"
+ - su www-data -c "git clone --depth 1 -b $SERVER_VERSION https://github.com/nextcloud/activity.git /var/www/html/apps/activity/"
+ - su www-data -c "php /var/www/html/occ app:enable activity"
+ - su www-data -c "git clone --depth 1 -b $SERVER_VERSION https://github.com/nextcloud/text.git /var/www/html/apps/text/"
+ - su www-data -c "php /var/www/html/occ app:enable text"
+ - su www-data -c "git clone --depth 1 -b $SERVER_VERSION https://github.com/nextcloud/end_to_end_encryption.git /var/www/html/apps/end_to_end_encryption/"
+ - su www-data -c "php /var/www/html/occ app:enable end_to_end_encryption"
+ - su www-data -c "git clone --depth 1 -b $SERVER_VERSION https://github.com/nextcloud/photos.git /var/www/html/apps/photos/"
+ - su www-data -c "cd /var/www/html/apps/photos; composer install --no-dev"
+ - su www-data -c "php /var/www/html/occ app:enable -f photos"
+ - su www-data -c "php /var/www/html/occ config:system:set ratelimit.protection.enabled --value false --type bool"
+ - /usr/local/bin/run.sh
trigger:
branch:
- master
+ - stable-*
event:
- - pull_request
- push
-
+ - pull_request
---
kind: pipeline
type: docker
-name: gplay
+name: tests-master
steps:
- name: gplay
- image: nextcloudci/android:android-49
+ image: ghcr.io/nextcloud/continuous-integration-android16:latest
privileged: true
environment:
LOG_USERNAME:
@@ -63,50 +84,24 @@ steps:
from_secret: LOG_PASSWORD
GIT_USERNAME:
from_secret: GIT_USERNAME
- GIT_TOKEN:
+ GITHUB_TOKEN:
from_secret: GIT_TOKEN
- ORG_GRADLE_PROJECT_coverage: ''
commands:
- - scripts/checkIfRunDrone.sh $GIT_USERNAME $GIT_TOKEN $DRONE_PULL_REQUEST || exit 0
- - emulator-headless -avd android-27 -no-snapshot -gpu swiftshader_indirect -no-window -no-audio -skin 500x833 &
- - sed -i s'#false#true#'g src/main/res/values/setup.xml
- - ./gradlew assembleGplay
- - ./gradlew assembleGplayDebug
- - scripts/wait_for_emulator.sh
- - ./gradlew jacocoTestGplayDebugUnitTestReport || scripts/uploadReport.sh $LOG_USERNAME $LOG_PASSWORD $DRONE_BUILD_NUMBER "Unit" $DRONE_PULL_REQUEST $GIT_USERNAME $GIT_TOKEN
- - ./gradlew installGplayDebugAndroidTest
- - ./gradlew createGplayDebugCoverageReport || scripts/uploadReport.sh $LOG_USERNAME $LOG_PASSWORD $DRONE_BUILD_NUMBER "IT" $DRONE_PULL_REQUEST $GIT_USERNAME $GIT_TOKEN
- - ./gradlew executeScreenshotTests || scripts/uploadReport.sh $LOG_USERNAME $LOG_PASSWORD $DRONE_BUILD_NUMBER "Screenshot" $DRONE_PULL_REQUEST $GIT_USERNAME $GIT_TOKEN
- - ./gradlew combinedTestReport
- - curl -o codecov.sh https://codecov.io/bash
- - bash ./codecov.sh -t fc506ba4-33c3-43e4-a760-aada38c24fd5
- - name: notify
- image: drillster/drone-email
- settings:
- port: 587
- from: nextcloud-drone@kaminsky.me
- recipients_only: true
- username:
- from_secret: EMAIL_USERNAME
- password:
- from_secret: EMAIL_PASSWORD
- recipients:
- from_secret: EMAIL_RECIPIENTS
- host:
- from_secret: EMAIL_HOST
- when:
- event:
- - push
- status:
- - failure
- branch:
- - master
+ - scripts/checkIfRunDrone.sh $DRONE_PULL_REQUEST || exit 0
+ - emulator -avd android -no-snapshot -gpu swiftshader_indirect -no-window -no-audio -skin 500x833 &
+ - sed -i s'#false#true#'g app/src/main/res/values/setup.xml
+ - scripts/runCombinedTest.sh $DRONE_PULL_REQUEST $LOG_USERNAME $LOG_PASSWORD $DRONE_BUILD_NUMBER
services:
- name: server
- image: nextcloudci/server:server-17 # also change in updateScreenshots.sh
+ image: ghcr.io/nextcloud/continuous-integration-shallow-server:latest # also change in updateScreenshots.sh
+ environment:
+ EVAL: true
commands:
- /usr/local/bin/initnc.sh
+ - echo 127.0.0.1 server >> /etc/hosts
+ - rm /etc/apt/sources.list.d/php.list
+ - apt-get update && apt-get install -y composer
- su www-data -c "OC_PASS=user1 php /var/www/html/occ user:add --password-from-env --display-name='User One' user1"
- su www-data -c "OC_PASS=user2 php /var/www/html/occ user:add --password-from-env --display-name='User Two' user2"
- su www-data -c "OC_PASS=user3 php /var/www/html/occ user:add --password-from-env --display-name='User Three' user3"
@@ -114,47 +109,51 @@ services:
- su www-data -c "php /var/www/html/occ group:add users"
- su www-data -c "php /var/www/html/occ group:adduser users user1"
- su www-data -c "php /var/www/html/occ group:adduser users user2"
- - su www-data -c "git clone -b master https://github.com/nextcloud/activity.git /var/www/html/apps/activity/"
+ - su www-data -c "git clone --depth 1 -b master https://github.com/nextcloud/activity.git /var/www/html/apps/activity/"
- su www-data -c "php /var/www/html/occ app:enable activity"
- - su www-data -c "git clone -b master https://github.com/nextcloud/text.git /var/www/html/apps/text/"
+ - su www-data -c "git clone --depth 1 -b main https://github.com/nextcloud/text.git /var/www/html/apps/text/"
- su www-data -c "php /var/www/html/occ app:enable text"
- - su www-data -c "git clone -b master https://github.com/nextcloud/circles.git /var/www/html/apps/circles/"
- - apt-get update; apt-get -y install composer
- - su www-data -c "cd /var/www/html/apps/circles; composer install"
- - su www-data -c "php /var/www/html/occ app:enable -f circles"
- - su www-data -c "php /var/www/html/occ config:app:set circles --value 1 allow_non_ssl_links"
- - su www-data -c "php /var/www/html/occ config:app:set circles --value 1 local_is_non_ssl"
- - su www-data -c "php /var/www/html/occ circles:manage:create test public publicCircle"
+ - su www-data -c "git clone --depth 1 -b master https://github.com/nextcloud/end_to_end_encryption/ /var/www/html/apps/end_to_end_encryption/"
+ - su www-data -c "php /var/www/html/occ app:enable end_to_end_encryption"
+ - su www-data -c "git clone --depth 1 https://github.com/nextcloud/photos.git /var/www/html/apps/photos/"
+ - su www-data -c "cd /var/www/html/apps/photos; composer install --no-dev"
+ - su www-data -c "php /var/www/html/occ app:enable -f photos"
+ - su www-data -c "php /var/www/html/occ config:system:set ratelimit.protection.enabled --value false --type bool"
- /usr/local/bin/run.sh
trigger:
branch:
- master
+ - stable-*
event:
- push
- pull_request
+
---
kind: pipeline
type: docker
-name: analysis
+name: allScreenshots
steps:
- - name: analysis
- image: nextcloudci/android:android-49
+ - name: runAllScreenshots
+ image: ghcr.io/nextcloud/continuous-integration-android16:latest
+ privileged: true
environment:
GIT_USERNAME:
from_secret: GIT_USERNAME
- GIT_TOKEN:
+ GITHUB_TOKEN:
from_secret: GIT_TOKEN
LOG_USERNAME:
from_secret: LOG_USERNAME
LOG_PASSWORD:
from_secret: LOG_PASSWORD
commands:
- - scripts/checkIfRunDrone.sh $GIT_USERNAME $GIT_TOKEN $DRONE_PULL_REQUEST || exit 0
- - export BRANCH=$(scripts/analysis/getBranchName.sh $GIT_USERNAME $GIT_TOKEN $DRONE_PULL_REQUEST)
- - scripts/analysis/analysis-wrapper.sh $GIT_USERNAME $GIT_TOKEN $BRANCH $LOG_USERNAME $LOG_PASSWORD $DRONE_BUILD_NUMBER $DRONE_PULL_REQUEST
-
+ - emulator -avd android -no-snapshot -gpu swiftshader_indirect -no-window -no-audio -skin 500x833 &
+ - sed -i s'#false#true#'g app/src/main/res/values/setup.xml
+ - sed -i s'#showOnlyFailingTestsInReports = ciBuild#showOnlyFailingTestsInReports = false#' build.gradle.kts
+ - scripts/wait_for_emulator.sh
+ - scripts/runAllScreenshotCombinations noCI false
+ - scripts/screenshotSummary.sh
- name: notify
image: drillster/drone-email
settings:
@@ -176,43 +175,18 @@ steps:
- failure
branch:
- master
-
+ - stable-*
trigger:
- branch:
- - master
event:
- - push
- - pull_request
+ - cron
+ cron:
+ - allscreenshots
---
-kind: pipeline
-type: docker
-name: qa
-
-steps:
- - name: qa
- image: nextcloudci/android:android-49
- privileged: true
- environment:
- LOG_USERNAME:
- from_secret: LOG_USERNAME
- LOG_PASSWORD:
- from_secret: LOG_PASSWORD
- GIT_USERNAME:
- from_secret: GIT_USERNAME
- GIT_TOKEN:
- from_secret: GIT_TOKEN
- KS_PASS:
- from_secret: KS_PASS
- KEY_PASS:
- from_secret: KEY_PASS
- commands:
- - scripts/checkIfRunDrone.sh $GIT_USERNAME $GIT_TOKEN $DRONE_PULL_REQUEST || exit 0
- - sed -i "/qa/,/\}/ s/versionCode .*/versionCode $DRONE_BUILD_NUMBER/" build.gradle
- - sed -i "/qa/,/\}/ s/versionName .*/versionName \"$DRONE_BUILD_NUMBER\"/" build.gradle
- - ./gradlew assembleQaDebug
- - /opt/android-sdk-linux/build-tools/*/apksigner sign --ks-pass pass:$KS_PASS --key-pass pass:$KEY_PASS --ks-key-alias key0 --ks scripts/QA_keystore.jks build/outputs/apk/qa/debug/qa-debug-*.apk
- - scripts/uploadArtifact.sh $LOG_USERNAME $LOG_PASSWORD $DRONE_BUILD_NUMBER $DRONE_PULL_REQUEST $GIT_USERNAME $GIT_TOKEN
+kind: secret
+name: GIT_TOKEN
+data: XIoa9IYq+xQ+N5iln8dlpWv0jV6ROr7HuE24ioUr4uQ8m8SjyH0yognWYLYLqnbTKrFWlFZiEMQTH/sZiWjRFvV1iL0=
+---
+kind: signature
+hmac: de23b70b660e9f78e936d89699fd24777a83c8caaad97d086bbc0c8a0373aa91
-trigger:
- event:
- - pull_request
+...
diff --git a/.editorconfig b/.editorconfig
index 10cf82d2f242..67e5fa3c2eae 100644
--- a/.editorconfig
+++ b/.editorconfig
@@ -2,6 +2,9 @@
# see http://EditorConfig.org
+# SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
+
# This is the file in the root of the project.
# For sub folders you can have other files that override only some settings.
# For these, this settings should be false.
@@ -13,6 +16,9 @@ max_line_length=120
indent_style=space
indent_size=4
+[*.yml]
+max_line_length=150
+
charset=utf-8
# Trimming is good for consistency
@@ -36,5 +42,10 @@ trim_trailing_whitespace=false
indent_size=2
[*.{kt,kts}]
+ktlint_code_style = android_studio
# IDE does not follow this Ktlint rule strictly, but the default ordering is pretty good anyway, so let's ditch it
-disabled_rules=import-ordering
+ktlint_standard_import-ordering = disabled
+ktlint_standard_no-consecutive-comments = disabled
+ktlint_function_naming_ignore_when_annotated_with = Composable
+ij_kotlin_allow_trailing_comma = false
+ij_kotlin_allow_trailing_comma_on_call_site = false
diff --git a/.github/.config.yml b/.github/.config.yml
index 3f2ff8572b7a..001818407138 100644
--- a/.github/.config.yml
+++ b/.github/.config.yml
@@ -1,4 +1,3 @@
firstPRMergeComment: >
Thanks for your first pull request and welcome to the community!
Feel free to keep them coming! If you are looking for issues to tackle then have a look at this selection: https://github.com/nextcloud/android/issues?utf8=%E2%9C%93&q=is%3Aissue+is%3Aopen+label%3A%22good+first+issue%22
- Most developers hang out on IRC. So join \#nextcloud-mobile on Freenode for a chat!
diff --git a/.github/.config.yml.license b/.github/.config.yml.license
new file mode 100644
index 000000000000..f6133f557dce
--- /dev/null
+++ b/.github/.config.yml.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2018-2024 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
index 378acfdbcc15..c7799c74190c 100644
--- a/.github/FUNDING.yml
+++ b/.github/FUNDING.yml
@@ -1,2 +1,4 @@
+# SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
# You can add one username per supported platform and one custom link
-custom: https://www.bountysource.com/teams/nextcloud/issues?tracker_ids=38838206
+custom: https://nextcloud.com/include/
diff --git a/.github/ISSUE_TEMPLATE/bug_report.md b/.github/ISSUE_TEMPLATE/bug_report.md
deleted file mode 100644
index 7b86ab226a6c..000000000000
--- a/.github/ISSUE_TEMPLATE/bug_report.md
+++ /dev/null
@@ -1,45 +0,0 @@
----
-name: Bug report
-about: Create a report to help us improve
-labels: bug
-
----
-
-### Steps to reproduce
-1.
-2.
-3.
-
-### Expected behaviour
-- Tell us what should happen
-
-### Actual behaviour
-- Tell us what happens
-
-### Can you reproduce this problem on https://try.nextcloud.com?
-- Please create a test demo account and see if this still happens there.
-- If yes, please open up a bug report
-- If not, please verify server setup and ask for help on forum
-
-### Environment data
-Android version:
-
-Device model:
-
-Stock or customized system:
-
-Nextcloud app version:
-
-Nextcloud server version:
-
-### Logs
-#### Web server error log
-```
-Insert your webserver log here
-```
-
-#### Nextcloud log (data/nextcloud.log)
-```
-Insert your Nextcloud log here
-```
-**NOTE:** Be super sure to remove sensitive data like passwords, note that everybody can look here! You can use the Issue Template application to prefill some of the required information: https://apps.nextcloud.com/apps/issuetemplate
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 000000000000..84acb9771770
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,132 @@
+name: "🐛 Bug report: Nextcloud Android Client"
+description: "Submit a report and help us improve the Nextcloud Android Client"
+labels: ["bug", "0. Needs triage"]
+body:
+ - type: checkboxes
+ id: before-posting
+ attributes:
+ label: "⚠️ Before posting ⚠️"
+ description: All conditions are **required**. Your issue can be closed if these are checked incorrectly.
+ options:
+ - label: This is a **bug**, not a question or an enhancement.
+ required: true
+ - label: I've [searched for similar issues](https://github.com/nextcloud/android/issues) and didn't find a duplicate.
+ required: true
+ - label: I've written a clear and descriptive title for this issue, not just "Bug" or "Crash".
+ required: true
+ - label: I agree to follow Nextcloud's [Code of Conduct](https://nextcloud.com/contribute/code-of-conduct/).
+ required: true
+ - type: textarea
+ id: repro-steps
+ attributes:
+ label: Steps to reproduce
+ description: |
+ What are the steps to reproduce this issue? Please be as specific as possible.
+ If you can't reproduce it, please add an explanation.
+ placeholder: |
+ 1.
+ 2.
+ 3.
+ validations:
+ required: true
+ - type: textarea
+ id: expected-behaviour
+ attributes:
+ label: Expected behaviour
+ description: Tell us what should happen.
+ validations:
+ required: true
+ - type: textarea
+ id: actual-behaviour
+ attributes:
+ label: Actual behaviour
+ description: Tell us what happens instead, as detailed as possible.
+ validations:
+ required: true
+# disabled because try.nextcloud.com is not working
+# - type: dropdown
+# id: repro-on-try
+# attributes:
+# label: Can you reproduce this problem on try.nextcloud.com?
+# description: |
+# 1. Create a demo account in [try.nextcloud.com](https://try.nextcloud.com). You'll be logged in automatically.
+# 2. Got to Settings -> Security and create a new app password
+# 3. Log in to this account with this app password by choosing "Alternative login with app token" during the login process.
+# options:
+# - "Yes"
+# - "No"
+# - Not applicable (explain in "additional information")
+# validations:
+# required: true
+ - type: markdown
+ attributes:
+ value: "## Environment information"
+ - type: input
+ id: android-version
+ attributes:
+ label: Android version
+ validations:
+ required: true
+ - type: input
+ id: device-model
+ attributes:
+ label: Device brand and model
+ validations:
+ required: true
+ - type: dropdown
+ id: stock-or-custom
+ attributes:
+ label: Stock or custom OS?
+ options:
+ - Stock
+ - Custom (explain in "additional information")
+ validations:
+ required: true
+ - type: input
+ id: app-version
+ attributes:
+ label: Nextcloud android app version
+ description: Check the _About_ section in the Settings screen
+ validations:
+ required: true
+ - type: input
+ id: server-version
+ attributes:
+ label: Nextcloud server version
+ description: Check _About_ in the top web menu (top right corner)
+ validations:
+ required: true
+ - type: dropdown
+ id: reverse-proxy
+ attributes:
+ label: Using a reverse proxy?
+ options:
+ - "I don't know"
+ - "Yes"
+ - "No"
+ validations:
+ required: true
+ - type: markdown
+ attributes:
+ value: "## Logs"
+ - type: textarea
+ id: android-logs
+ attributes:
+ label: Android logs
+ description: |
+ Please **drop a log file** here.
+ Log file can be obtained:
+ - At `storage/emulated/0/data/nextcloud.log` on beta or dev versions
+ - By using [`logcat`](https://github.com/nextcloud/android#getting-debug-info-via-logcat-mag) otherwise
+ If you are unable to post logs, explain why in "Additional information"
+ - type: textarea
+ id: server-logs
+ attributes:
+ label: Server error logs
+ description: Paste your server error logs here if available. Will be automatically formatted.
+ render: bash
+ - type: textarea
+ id: additional-info
+ attributes:
+ label: Additional information
+ description: Enter any additional information here
diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml.license b/.github/ISSUE_TEMPLATE/bug_report.yml.license
new file mode 100644
index 000000000000..8dae4293a3ac
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml
new file mode 100644
index 000000000000..f7550392d92b
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml
@@ -0,0 +1,16 @@
+# SPDX-FileCopyrightText: 2020 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later
+contact_links:
+ - name: 🚨 Report a security or privacy issue
+ url: https://hackerone.com/nextcloud
+ about: Report security and privacy related issues privately to the Nextcloud team, so we can coordinate the fix and release without potentially exposing all Nextcloud servers and users in the meantime.
+ - name: 🚨 报告安全或隐私问题
+ url: https://hackerone.com/nextcloud
+ about: 请以私密方式向 Nextcloud 团队报告安全和隐私相关问题,以便我们能够协调修复工作并安排发布计划,避免在此期间可能暴露所有 Nextcloud 服务器和用户的风险。
+ - name: ❓ Community Support and Help
+ url: https://help.nextcloud.com/
+ about: Configuration, webserver/proxy or performance issues and other questions
+ - name: 💼 Nextcloud Enterprise
+ url: https://portal.nextcloud.com/
+ about: If you are a Nextcloud Enterprise customer, or need Professional support, so it can be resolved directly by our dedicated engineers more quickly
+blank_issues_enabled: false
diff --git a/.github/ISSUE_TEMPLATE/config.yml.license b/.github/ISSUE_TEMPLATE/config.yml.license
new file mode 100644
index 000000000000..8dae4293a3ac
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/config.yml.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md b/.github/ISSUE_TEMPLATE/feature_request.md
index 13d19caad38f..468572c9b6a6 100644
--- a/.github/ISSUE_TEMPLATE/feature_request.md
+++ b/.github/ISSUE_TEMPLATE/feature_request.md
@@ -1,20 +1,48 @@
---
-name: Feature request
+name: 🚀 Feature request
about: Suggest an idea for this project
-labels: enhancement
-
+labels: enhancement, 0. Needs triage
---
-### Is your feature request related to a problem? Please describe.
+
+
+
+
+
+### How to use GitHub
+
+* Please use the 👍 [reaction](https://blog.github.com/2016-03-10-add-reactions-to-pull-requests-issues-and-comments/) to show that you are interested into the same feature.
+* Please don't comment if you have no relevant information to add. It's just extra noise for everyone subscribed to this issue.
+* Subscribe to receive notifications on status change and new comments.
+
+
+**Is your feature request related to a problem? Please describe.**
A clear and concise description of what the problem is. Ex. I'm always frustrated when [...]
-### Describe the solution you'd like
+**Describe the solution you'd like**
A clear and concise description of what you want to happen.
-### Describe alternatives you've considered
+**Describe alternatives you've considered**
A clear and concise description of any alternative solutions or features you've considered.
-### Additional context
+**Additional context**
Add any other context or screenshots about the feature request here.
-
-**NOTE:** Be super sure to remove sensitive data like passwords, note that everybody can look here! You can use the Issue Template application to prefill some of the required information: https://apps.nextcloud.com/apps/issuetemplate
diff --git a/.github/ISSUE_TEMPLATE/feature_request.md.license b/.github/ISSUE_TEMPLATE/feature_request.md.license
new file mode 100644
index 000000000000..8dae4293a3ac
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/feature_request.md.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
index edbe3ac19abc..4901055376bc 100644
--- a/.github/pull_request_template.md
+++ b/.github/pull_request_template.md
@@ -1,9 +1,19 @@
-### Testing
+
+### 🖼️ Screenshots
+
+🏚️ Before | 🏡 After
+---|---
+B | A
+### 🏁 Checklist
+
- [ ] Tests written, or not not needed
diff --git a/.github/pull_request_template.md.license b/.github/pull_request_template.md.license
new file mode 100644
index 000000000000..44275b2b58eb
--- /dev/null
+++ b/.github/pull_request_template.md.license
@@ -0,0 +1,3 @@
+SPDX-FileCopyrightText: 2023-2024 Nextcloud GmbH and Nextcloud contributors
+SPDX-FileCopyrightText: 2023 Marcel Hibbe
+SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
diff --git a/.github/stale.yml b/.github/stale.yml
deleted file mode 100644
index 64dd03e3f755..000000000000
--- a/.github/stale.yml
+++ /dev/null
@@ -1,19 +0,0 @@
-# Number of days of inactivity before an issue becomes stale
-daysUntilStale: 28
-# Number of days of inactivity before a stale issue is closed
-daysUntilClose: 14
-# Only issues or pull requests with all of these labels are check if stale. Defaults to `[]` (disabled)
-onlyLabels:
- - bug
- - "needs info/discussion"
-# Issues with these labels will never be considered stale
-exemptLabels: []
-# Label to use when marking an issue as stale
-staleLabel: stale
-# Comment to post when marking an issue as stale. Set to `false` to disable
-markComment: >
- 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!
-# Comment to post when closing a stale issue. Set to `false` to disable
-closeComment: false
diff --git a/scripts/QA_keystore.jks b/.github/workflows/QA_keystore.jks
similarity index 100%
rename from scripts/QA_keystore.jks
rename to .github/workflows/QA_keystore.jks
diff --git a/.github/workflows/QA_keystore.jks.license b/.github/workflows/QA_keystore.jks.license
new file mode 100644
index 000000000000..f070b8a4c019
--- /dev/null
+++ b/.github/workflows/QA_keystore.jks.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2019-2024 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/.github/workflows/analysis.yml b/.github/workflows/analysis.yml
new file mode 100644
index 000000000000..39aebc63a2e5
--- /dev/null
+++ b/.github/workflows/analysis.yml
@@ -0,0 +1,76 @@
+# 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ 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@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.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
new file mode 100644
index 000000000000..bf44361cc250
--- /dev/null
+++ b/.github/workflows/assembleFlavors.yml
@@ -0,0 +1,38 @@
+# 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: set up JDK 21
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
+ with:
+ distribution: "temurin"
+ java-version: 21
+ - uses: gradle/actions/wrapper-validation@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.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
new file mode 100644
index 000000000000..c215be0b3e89
--- /dev/null
+++ b/.github/workflows/autoApproveSync.yml
@@ -0,0 +1,40 @@
+# 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
new file mode 100644
index 000000000000..a08122a435e0
--- /dev/null
+++ b/.github/workflows/check.yml
@@ -0,0 +1,32 @@
+# 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Set up JDK 21
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.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
new file mode 100644
index 000000000000..a6ef19196628
--- /dev/null
+++ b/.github/workflows/codeql.yml
@@ -0,0 +1,60 @@
+# 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ 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@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
+ with:
+ languages: ${{ matrix.language }}
+ - name: Set up JDK 21
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.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@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
diff --git a/.github/workflows/detectNewJavaFiles.yml b/.github/workflows/detectNewJavaFiles.yml
new file mode 100644
index 000000000000..908e3fd288f8
--- /dev/null
+++ b/.github/workflows/detectNewJavaFiles.yml
@@ -0,0 +1,43 @@
+# 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
new file mode 100644
index 000000000000..ebc50bc54bcc
--- /dev/null
+++ b/.github/workflows/detectWrongSettings.yml
@@ -0,0 +1,30 @@
+# 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ - name: Set up JDK 21
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
+ with:
+ distribution: "temurin"
+ java-version: 21
+ - name: Detect SNAPSHOT
+ run: scripts/analysis/detectWrongSettings.sh
diff --git a/.github/workflows/gradle-wrapper-validation.yml b/.github/workflows/gradle-wrapper-validation.yml
deleted file mode 100644
index 628503225078..000000000000
--- a/.github/workflows/gradle-wrapper-validation.yml
+++ /dev/null
@@ -1,10 +0,0 @@
-name: "Validate Gradle Wrapper"
-on: [push, pull_request]
-
-jobs:
- validation:
- name: "Validation"
- runs-on: ubuntu-latest
- steps:
- - uses: actions/checkout@v2
- - uses: gradle/wrapper-validation-action@v1
diff --git a/.github/workflows/lib.sh b/.github/workflows/lib.sh
new file mode 100644
index 000000000000..3bb8b10f7930
--- /dev/null
+++ b/.github/workflows/lib.sh
@@ -0,0 +1,27 @@
+#!/usr/bin/env bash
+#
+# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
+# SPDX-FileCopyrightText: 2022 Álvaro Brey
+# SPDX-License-Identifier: AGPL-3.0-or-later
+#
+
+## This file is intended to be sourced by other scripts
+
+
+function err() {
+ echo >&2 "$@"
+}
+
+
+function curl_gh() {
+ if [[ -n "$GITHUB_TOKEN" ]]
+ then
+ curl \
+ --silent \
+ --header "Authorization: token $GITHUB_TOKEN" \
+ "$@"
+ else
+ err "WARNING: No GITHUB_TOKEN found. Skipping API call"
+ fi
+
+}
diff --git a/.github/workflows/lib.sh.license b/.github/workflows/lib.sh.license
new file mode 100644
index 000000000000..23bad5cb8a9c
--- /dev/null
+++ b/.github/workflows/lib.sh.license
@@ -0,0 +1,2 @@
+SPDX-FileCopyrightText: 2019-2025 Nextcloud GmbH and Nextcloud contributors
+SPDX-License-Identifier: AGPL-3.0-or-later
diff --git a/.github/workflows/pr-feedback.yml b/.github/workflows/pr-feedback.yml
new file mode 100644
index 000000000000..a3a2d1296c7a
--- /dev/null
+++ b/.github/workflows/pr-feedback.yml
@@ -0,0 +1,55 @@
+# 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
new file mode 100644
index 000000000000..cca30141ac60
--- /dev/null
+++ b/.github/workflows/qa.yml
@@ -0,0 +1,85 @@
+# 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ if: ${{ steps.check-secrets.outputs.ok == 'true' }}
+ with:
+ persist-credentials: false
+
+ - name: set up JDK 21
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.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.
+  (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
new file mode 100644
index 000000000000..b92491bf3215
--- /dev/null
+++ b/.github/workflows/renovate-approve-merge.yml
@@ -0,0 +1,61 @@
+# 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ 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
new file mode 100644
index 000000000000..3f485f875f7e
--- /dev/null
+++ b/.github/workflows/reuse.yml
@@ -0,0 +1,27 @@
+# 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ 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
new file mode 100644
index 000000000000..9a1c554023ab
--- /dev/null
+++ b/.github/workflows/scorecard.yml
@@ -0,0 +1,47 @@
+# 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+ 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@c10b8064de6f491fea524254123dbe5e09572f13 # v4.35.1
+ with:
+ sarif_file: results.sarif
diff --git a/.github/workflows/screenShotTest.yml b/.github/workflows/screenShotTest.yml
new file mode 100644
index 000000000000..cf748ae4e842
--- /dev/null
+++ b/.github/workflows/screenShotTest.yml
@@ -0,0 +1,109 @@
+# SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
+
+name: "Screenshot Test"
+
+on:
+ pull_request:
+ branches: [ master, stable-* ]
+
+permissions:
+ contents: read
+ pull-requests: write
+
+concurrency:
+ group: screenshot-test-${{ github.head_ref || github.run_id }}
+ cancel-in-progress: true
+
+jobs:
+ screenshot:
+ runs-on: ubuntu-24.04
+ strategy:
+ fail-fast: false
+ matrix:
+ scheme: [ Light ]
+ color: [ blue ]
+ api-level: [ 28 ]
+ steps:
+ - uses: actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Gradle cache
+ uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
+ with:
+ path: |
+ ~/.gradle/caches
+ ~/.gradle/wrapper
+ key: gradle-${{ runner.os }}-${{ hashFiles('**/*.gradle*') }}-${{ hashFiles('**/gradle/wrapper/gradle-wrapper.properties') }}
+ - name: AVD cache
+ uses: actions/cache@668228422ae6a00e4ad889ee87cd7109ec5666a7 # v5.0.4
+ id: avd-cache
+ with:
+ path: |
+ ~/.android/avd/*
+ ~/.android/adb*
+ key: avd-${{ matrix.api-level }}
+
+ - uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.0
+ with:
+ distribution: "temurin"
+ java-version: 21
+
+ - name: Enable KVM group perms
+ run: |
+ echo 'KERNEL=="kvm", GROUP="kvm", MODE="0666", OPTIONS+="static_node=kvm"' | sudo tee /etc/udev/rules.d/99-kvm4all.rules
+ sudo udevadm control --reload-rules
+ sudo udevadm trigger --name-match=kvm
+
+ - name: create AVD and generate snapshot for caching
+ if: steps.avd-cache.outputs.cache-hit != 'true'
+ uses: reactivecircus/android-emulator-runner@b530d96654c385303d652368551fb075bc2f0b6b # v2.35.0
+ with:
+ api-level: ${{ matrix.api-level }}
+ force-avd-creation: false
+ arch: x86
+ sdcard-path-or-size: 100M
+ target: google_apis
+ emulator-options: -no-window -gpu swiftshader_indirect -no-snapshot -noaudio -no-boot-anim -skin 500x833
+ script: echo "Generated AVD snapshot for caching."
+
+ - name: Configure gradle daemon
+ run: |
+ mkdir -p $HOME/.gradle
+ echo "org.gradle.jvmargs=-Xmx6g -XX:+HeapDumpOnOutOfMemoryError -Dfile.encoding=UTF-8 -XX:+UseParallelGC -XX:MaxMetaspaceSize=1g" > $HOME/.gradle/gradle.properties
+ echo "org.gradle.caching=true" >> $HOME/.gradle/gradle.properties
+ echo "org.gradle.parallel=true" >> $HOME/.gradle/gradle.properties
+ echo "org.gradle.configureondemand=true" >> $HOME/.gradle/gradle.properties
+
+ - name: Build generic flavor
+ run: ./gradlew assembleGenericDebug
+
+ - name: Delete old comments
+ env:
+ GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+ if: ${{ always() }}
+ run: scripts/deleteOldComments.sh "${{ matrix.color }}-${{ matrix.scheme }}" "Screenshot" ${{github.event.number}}
+
+ - name: Run screenshot tests
+ env:
+ SHOT_TEST: "true"
+ uses: reactivecircus/android-emulator-runner@b530d96654c385303d652368551fb075bc2f0b6b # v2.35.0
+ with:
+ api-level: ${{ matrix.api-level }}
+ force-avd-creation: false
+ arch: x86
+ 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 }}
+ - 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}} "${{ matrix.color }}-${{ matrix.scheme }}" "Screenshot" ${{github.event.number}}
+ - name: Archive Espresso results
+ uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
+ if: ${{ always() }}
+ with:
+ name: Report-${{ matrix.color }}-${{ matrix.scheme }}
+ path: app/build/reports
+ retention-days: 4
diff --git a/.github/workflows/stale.yml b/.github/workflows/stale.yml
new file mode 100644
index 000000000000..478c094b0e30
--- /dev/null
+++ b/.github/workflows/stale.yml
@@ -0,0 +1,35 @@
+# 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@b5d41d4e1d5dceea10e7104786b73624c18a190f # v10.2.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
new file mode 100644
index 000000000000..4b3dc2f50ca4
--- /dev/null
+++ b/.github/workflows/unit-tests.yml
@@ -0,0 +1,64 @@
+# 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@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6.0.2
+
+ - name: Set up JDK 21
+ uses: actions/setup-java@be666c2fcd27ec809703dec50e508c2fdc7f6654 # v5.2.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@50e97c2cd7a37755bbfafc9c5b7cafaece252f6e # v6.1.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@57e3a136b779b570ffcdbf80b3bdc90e7fab3de2 # v6.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
new file mode 100755
index 000000000000..bf96572045ab
--- /dev/null
+++ b/.github/workflows/uploadArtifact.sh
@@ -0,0 +1,44 @@
+#!/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

To test this change/fix you can simply download above APK file and install and test it in parallel to your existing Nextcloud app. \" }"
diff --git a/.gitignore b/.gitignore
index 6ee303ee6b0f..51120b52fc6c 100644
--- a/.gitignore
+++ b/.gitignore
@@ -1,6 +1,9 @@
+# SPDX-FileCopyrightText: 2016-2024 Nextcloud GmbH and Nextcloud contributors
+# SPDX-License-Identifier: AGPL-3.0-or-later OR GPL-2.0-only
# built application files
*.apk
*.ap_
+*.aab
# files for the dex VM
*.dex
@@ -19,23 +22,59 @@ target/
local.properties
tests/local.properties
+# Signing & secrets
+*.jks
+*.keystore
+keystore.properties
+release.properties
+google-services.json
+GoogleService-Info.plist
+*.p12
+*.pem
+secrets.properties
+.env
+.env.*
+
+# Windows
+Thumbs.db
+desktop.ini
+
# Mac .DS_Store files
.DS_Store
+# Linux/editor temp files
+*~
+*.swp
+*.swo
+.vscode/
+
# Proguard README
proguard-project.txt
tests/proguard-project.txt
# Android Studio and Gradle specific entries
.gradle
-.idea
-*.iml
+.idea/*
+!.idea/codeStyles/
build
/gradle.properties
.attach_pid*
fastlane/Fastfile
*.hprof
+# NDK / C++
+*.so
+obj/
+*.o
+*.a
+
+# Testing & coverage
+.kotlin/
+*.lcov
+test-results/
+jacoco/
+*.exec
+
# fastlane specific
**/fastlane/report.xml
@@ -47,3 +86,10 @@ fastlane/Fastfile
# scan temporary files
**/fastlane/test_output
+/fastlane/vendor/
+/.bundle/
+/fastlane/.bundle
+
+# python
+**/__pycache__/
+/gradle/verification-keyring.gpg
diff --git a/.idea/codeStyles/Project.xml b/.idea/codeStyles/Project.xml
index 596b62e9d636..23a6687d1074 100644
--- a/.idea/codeStyles/Project.xml
+++ b/.idea/codeStyles/Project.xml
@@ -28,10 +28,10 @@
-