An experiment to help with identifying usage of private Nextcloud APIs by the community and official apps
  • Rust 89.1%
  • HTML 10.2%
  • Shell 0.5%
  • Dockerfile 0.2%
Find a file
2026-10-27 20:26:50 +01:00
portal_auto_rebuild Add script to build new aneba web portal 2026-09-26 13:27:23 +02:00
src Show shipped apps in search portal 2026-10-27 20:16:52 +01:00
.gitignore First commit 2026-09-20 12:09:44 +02:00
Cargo.lock Extract shipped apps 2026-10-27 12:19:13 +01:00
Cargo.toml Extract shipped apps 2026-10-27 12:19:13 +01:00
deploy.sh Deploy 2026-09-26 13:48:11 +02:00
README.md Describe how shipped apps are handled 2026-10-27 20:26:50 +01:00
rust-toolchain Add script to build new aneba web portal 2026-09-26 13:27:23 +02:00

ANEBA: Avoid Nextcloud Ecosystem BreakAge

This repo is an experiment to help with identifying usage of internal or deprecated Nextcloud APIs by the community and official apps.

Different teams can use this information to increase the robustness of the ecosystem and avoid breaking apps blocking platform updates.

You can read more about the motivation of this work in this blog post.

How to use

To run it from source, install Rust then run these commands:

  1. cargo run --release -- download-apps --server-versions 35 34 33 --prune --output data/apps to download the last release of all apps compatible with the versions 35, 34 or 33. This will download all the ".tar.gz" release files. Note that, at this time, no signature is checked.

  2. cargo run --release -- analyse-nextcloud ../server data/server-35.json --tag stable35 to analyse Nextcloud server repository that is checked out in another folder

  3. cargo run --release -- analyse-apps data/apps/35 data/apps-35.sqlite --server data/server-35.json to analyse all their PHP source files. This will create an SQLite database file with these tables:

    • apps: information about all extracted apps
      • app_id: int primary key
      • name: text, the English name of the app
      • slug: text, the identifier of the app
      • download: text, null if the app is shipper with the server
      • version: text
      • created: text, when this app version was created
      • has_errors: bool, whether any PHP source file failed to be analysed
    • files: information about all PHP source files
      • file_id: int primary key
      • app_id: int, null if the file is part of the server code
      • file: text, the path to the file inside the archive
      • error: text, if the file failed to be analysed, the error message
    • items: all declared classes, traits, interfaces, functions, constants, static methods and static constants. Note: some items may be declared in multiple distinct places.
      • item_id: int primary key
      • name: text, the resolved global name of the item
      • file_id: int, the file that declares this item
      • line: int, the line of the file where this is declared
      • deprecated: text, not null when this item is marked deprecated
      • internal: text, not null when this item is marked internal
    • refs: all references used by the apps
      • ref_id: int primary key
      • app_id: int
      • name: int
      • file_id: int
      • line: int, line of the file where this item was first referenced
    • declared_ocas: the list of all OCA\ namespaces declared by each app
      • declared_oca_id: int primary key
      • app_id: int
      • declared_oca: text
      • file_id: int, one of the files that declare this OCA
      • line: int
    • ref_ocas: the list of all OCA\ namespaces referenced by each app
      • ref_oca_id: int primary key
      • app_id: int
      • ref_oca: text
      • file_id: int, one of the files that reference this OCA
      • line: int

    You can then explore the database using sqlite3 data/apps-35.sqlite. Install it with sudo apt-get install sqlite3 if needed.

  4. cargo run --release -- build-search-portal data/apps-35.sqlite data/apps-35.html to create the search portal

You can run cargo run -- --help to see all commands available.

Shipped apps

Some apps installed in a Nextcloud instance are not obtained through the app store, but instead are provided as part of the server release. Those apps are called "shipped apps" and are listed here.

These apps are also analysed by ANEBA. For this, the subcommand download-apps downloads the latest release of each analysed server major version from. For example, for version 35 it is loaded from https://download.nextcloud.com/server/releases/latest-35.tar.bz2. Then, the archive is read and each app present in the nextcloud/apps folder is extracted as its own app. Their "version" is set to be the server version.

On the search webpage, these apps will be annotated with the "(shipped)" marked in their names. Due to lack of more precise metadata, the link to their sources may not work and redirect to a non-existing page.

Deploy

Set git alias with:

git config alias.deploy '!git push && ssh -4 sitegui@ssh.sitegui.dev ./deploy sitegui/nextcloud-aneba'

then simply run git deploy to push and deploy.

Future ideas

  • detect changed symbols in the UI
  • "bubble up" the breaking changes from method to class, etc
  • for the moment, I'm ignoring breaking changes that can happen from "protected" items, because it opens a harder can of worms: we'll have to track exact usage of the items. For example, just referencing the class is okay, but extending it may be not.