Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
46 changes: 46 additions & 0 deletions .github/workflows/lint-stylelint.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
# This workflow is based on the Nextcloud organization template repository.
# SPDX-FileCopyrightText: 2021-2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT

name: Lint stylelint

on: pull_request

permissions:
contents: read

concurrency:
group: lint-stylelint-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
lint:
runs-on: ubuntu-latest
name: stylelint

steps:
- name: Checkout
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Read package.json node and npm engines version
uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
id: versions
with:
fallbackNode: '^24'
fallbackNpm: '^11.3'

- name: Set up node ${{ steps.versions.outputs.nodeVersion }}
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ steps.versions.outputs.nodeVersion }}

- name: Set up npm ${{ steps.versions.outputs.npmVersion }}
run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'

- name: Install dependencies
run: npm install --no-package-lock

- name: Lint
run: npm run stylelint
25 changes: 14 additions & 11 deletions .github/workflows/node-test.yml
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
# Based on the Nextcloud organization workflow template.
# SPDX-FileCopyrightText: 2022-2024 Nextcloud GmbH and Nextcloud contributors
# SPDX-FileCopyrightText: 2022-2026 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT

name: Node tests
Expand All @@ -21,21 +21,24 @@ jobs:
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Read package engines
uses: skjnldsv/read-package-engines-version-actions@06d6baf7d8f41934ab630e97d9e6c0bc9c9ac5e4 # v3
uses: nextcloud-libraries/parse-package-engines-action@122ae05d4257008180a514e1ddeb0c1b9d094bdd # v0.1.0
id: versions
with:
fallbackNode: '^24'
fallbackNpm: '^11.3'

- name: Set up node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: ${{ steps.versions.outputs.nodeVersion }}
node-version: ${{ steps.versions.outputs.node-version }}

- name: Set up npm
run: npm i -g 'npm@${{ steps.versions.outputs.npmVersion }}'
run: npm i -g 'npm@${{ steps.versions.outputs.package-manager-version }}'

- name: Install dependencies
run: npm install --no-package-lock
- name: Run Node checks
run: |
npm run lint
npm run ts:check

- name: Run unit tests
run: npm run test:coverage

- name: Build frontend
run: npm run build
128 changes: 128 additions & 0 deletions .github/workflows/playwright.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,128 @@
# Based on the Nextcloud organization workflow template.
# SPDX-FileCopyrightText: 2026 Nextcloud GmbH and Nextcloud contributors
# SPDX-License-Identifier: MIT

name: Playwright tests

on: pull_request

permissions:
contents: read

concurrency:
group: playwright-${{ github.head_ref || github.run_id }}
cancel-in-progress: true

jobs:
matrix:
runs-on: ubuntu-latest
outputs:
php-min: ${{ steps.versions.outputs.php-min }}
branches-max: ${{ steps.versions.outputs.branches-max }}

steps:
- name: Checkout app
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false

- name: Get version matrix
id: versions
uses: nextcloud-libraries/nextcloud-version-matrix@cd0211ffcef1065e2020cd579e4843b8746e7a58 # v1.3.3

playwright:
needs: matrix
runs-on: ubuntu-latest
timeout-minutes: 30
env:
APP_NAME: usage_statistics_server
PLAYWRIGHT_BASE_URL: http://127.0.0.1:8080

steps:
- name: Checkout server
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
submodules: true
repository: nextcloud/server
ref: ${{ needs.matrix.outputs.branches-max }}

- name: Checkout app
uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
with:
persist-credentials: false
path: apps/${{ env.APP_NAME }}

- name: Set up node
uses: actions/setup-node@820762786026740c76f36085b0efc47a31fe5020 # v7.0.0
with:
node-version: '24'

- name: Set up npm
run: npm i -g 'npm@^11.3'

- name: Set up PHP ${{ needs.matrix.outputs.php-min }}
uses: shivammathur/setup-php@f3e473d116dcccaddc5834248c87452386958240 # v2.37.2
with:
php-version: ${{ needs.matrix.outputs.php-min }}
extensions: bz2, ctype, curl, dom, fileinfo, gd, iconv, intl, json, libxml, mbstring, openssl, pcntl, posix, session, simplexml, sockets, sqlite, pdo_sqlite, xmlreader, xmlwriter, zip, zlib
coverage: none
ini-file: development
ini-values: disable_functions=

- name: Install app dependencies
working-directory: apps/${{ env.APP_NAME }}
run: |
composer remove nextcloud/ocp --dev --no-scripts
composer install --no-dev --no-scripts
npm install --no-package-lock
npm run build

- name: Install Playwright browser
working-directory: apps/${{ env.APP_NAME }}
run: npm run playwright:install-ci

- name: Set up Nextcloud
run: |
mkdir data
./occ maintenance:install \
--database=sqlite \
--database-name=nextcloud \
--admin-user admin \
--admin-pass admin
./occ app:enable --force $APP_NAME
./occ config:system:set auth.bruteforce.protection.enabled --value false --type boolean
./occ config:system:set ratelimit.protection.enabled --value false --type boolean

- name: Start Nextcloud
env:
PHP_CLI_SERVER_WORKERS: 8
run: |
php -S 127.0.0.1:8080 -t . > /tmp/nextcloud-server.log 2>&1 &
for attempt in {1..30}; do
if curl --fail --silent http://127.0.0.1:8080/status.php > /dev/null; then
exit 0
fi
sleep 1
done
cat /tmp/nextcloud-server.log
exit 1

- name: Run Playwright tests
working-directory: apps/${{ env.APP_NAME }}
run: npm run playwright

- name: Show server logs
if: failure()
run: |
cat /tmp/nextcloud-server.log || true
cat data/nextcloud.log || true

- name: Upload Playwright report
if: ${{ !cancelled() }}
uses: actions/upload-artifact@043fb46d1a93c77aae656e7c1c64a875d1fc6a0a # v7.0.1
with:
name: playwright-report
path: apps/${{ env.APP_NAME }}/playwright-report/
if-no-files-found: ignore
retention-days: 7
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
/var/
/.phpunit.cache/
/.env.local
/node_modules/
18 changes: 6 additions & 12 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,21 +37,15 @@ The ingestion protocol is application-agnostic. Metric values are typed and sche

The server does not treat submitted data as an audited census. Reports come from software running on infrastructure controlled by the sender, so aggregated results should be described as statistics reported by participating installations.

Server administrators can configure data retention from the Nextcloud administration settings or with the `usage-statistics-server:retention:*` OCC commands.

## Documentation

Start here if you want to integrate another Nextcloud app:

- [Protocol v1](docs/protocol-v1.md) report format, validation rules, and ingestion behavior.
- [Application schemas](docs/application-schemas.md) how applications define metrics and evolve schemas.
- [Administrative API](docs/admin-api.md) endpoints for querying aggregated statistics.
- [Retention](docs/retention.md) historical data retention and cleanup behavior.
- [Protocol v1](docs/protocol-v1.md): report format, validation rules, and ingestion behavior.
- [Application schemas](docs/application-schemas.md): how applications define metrics and evolve schemas.
- [Administrative API](docs/admin-api.md): endpoints for querying aggregated statistics.
- [Retention](docs/retention.md): historical data retention and cleanup behavior.

The OpenAPI specifications are generated from the Nextcloud controller contracts and are kept in the repository for API consumers and generated types.

## Current support

The app currently targets Nextcloud 35 and 36 and is tested with SQLite, MySQL, MariaDB, and PostgreSQL.

## License

Usage Statistics Server is licensed under the GNU Affero General Public License v3 or later. See [COPYING](COPYING).
8 changes: 8 additions & 0 deletions appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -26,4 +26,12 @@ A generic Nextcloud app for receiving, storing, aggregating, and exposing privac
<background-jobs>
<job>OCA\UsageStatisticsServer\BackgroundJob\CleanupOldData</job>
</background-jobs>
<commands>
<command>OCA\UsageStatisticsServer\Command\RetentionGet</command>
<command>OCA\UsageStatisticsServer\Command\RetentionSet</command>
</commands>
<settings>
<admin>OCA\UsageStatisticsServer\Settings\AdminSettings</admin>
<admin-section>OCA\UsageStatisticsServer\Settings\AdminSection</admin-section>
</settings>
</info>
Loading
Loading