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 d91fdeed2bfc..4da327c6a57b 100644 --- a/.drone.yml +++ b/.drone.yml @@ -1,48 +1,81 @@ +--- kind: pipeline -name: generic +type: docker +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-48 + - 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 + GITHUB_TOKEN: + from_secret: GIT_TOKEN commands: - - ./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 - 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 -name: gplay +type: docker +name: tests-master steps: - name: gplay - image: nextcloudci/android:android-48 + image: ghcr.io/nextcloud/continuous-integration-android16:latest privileged: true environment: LOG_USERNAME: @@ -51,72 +84,76 @@ steps: from_secret: LOG_PASSWORD GIT_USERNAME: from_secret: GIT_USERNAME - GIT_TOKEN: + GITHUB_TOKEN: from_secret: GIT_TOKEN - ORG_GRADLE_PROJECT_coverage: '' commands: - - ./gradlew assembleGplay - - emulator -avd android-27 -no-window -no-audio & - - ./wait_for_emulator.sh - - ./gradlew assembleGplayDebug - - ./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 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-3 + 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" + - 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 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 --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 --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 -name: analysis +type: docker +name: allScreenshots steps: - - name: analysis - image: nextcloudci/android:android-48 + - 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: - - 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: @@ -138,41 +175,18 @@ steps: - failure branch: - master - + - stable-* trigger: - branch: - - master event: - - push - - pull_request + - cron + cron: + - allscreenshots --- -kind: pipeline -name: qa - -steps: - - name: qa - image: nextcloudci/android:android-48 - 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: - - 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 8aa4377dd23a..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 @@ -34,3 +40,12 @@ trim_trailing_whitespace=false [.drone.yml] 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 +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 0540f9084776..000000000000 --- a/.github/ISSUE_TEMPLATE/bug_report.md +++ /dev/null @@ -1,41 +0,0 @@ ---- -name: Bug report -about: Create a report to help us improve -labels: bug - ---- - -### Actual behaviour -- Tell us what happens - -### Expected behaviour -- Tell us what should happen - -### Steps to reproduce -1. -2. -3. - - -### 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 new file mode 100644 index 000000000000..4901055376bc --- /dev/null +++ b/.github/pull_request_template.md @@ -0,0 +1,19 @@ + +### ðŸ–¼ï¸ 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 f3acdb140866..000000000000 --- a/.github/stale.yml +++ /dev/null @@ -1,21 +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 -# Issues with these labels will never be considered stale -exemptLabels: - - 1. developing - - 2. to review - - 3. to release - - approved - - enhancement - - overview -# 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 request 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/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. + ![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 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

![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. \" }" diff --git a/.gitignore b/.gitignore index 55eafe2d77cb..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,19 +22,74 @@ 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 + +# deliver temporary files +**/fastlane/Preview.html + +# snapshot generated screenshots +**/fastlane/screenshots + +# 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 7cd663d7e01d..23a6687d1074 100644 --- a/.idea/codeStyles/Project.xml +++ b/.idea/codeStyles/Project.xml @@ -27,17 +27,11 @@ - - +