feat(quality): validate appinfo/info.xml against the App Store schema (Nextcloud's lint-info-xml) - #383
Merged
Conversation
Nextcloud ships lint-info-xml.yml as a workflow template and every upstream app
runs it. This fleet ran no equivalent — quality.yml did not reference
appinfo/info.xml anywhere — so a malformed manifest was found at App Store
upload time, after the release had been built, tagged and published.
That matters more since the release path started reading info.xml for two things
it cannot get wrong: the version the tag must match, and the Nextcloud version
whose occ signs the package. A file that does not validate can still parse well
enough for a grep to return something plausible, which is exactly how an
unanchored min-version pattern resolved 8 from <php min-version="8.3"/> in 13
apps earlier today.
MEASURED BEFORE MERGING, against all 18 core apps: 5 pass, 13 fail.
doriath, opencatalogi <background-jobs> out of sequence
hermiq, portaliq, softwarecatalog <php> out of sequence
larpingapp, openbuild, scholiq <app> out of sequence
launchpad <types> out of sequence
nldesign <repair-steps> out of sequence
openconnector <category> out of sequence
openregister <documentation> out of sequence
zaakafhandelapp <summary> is 136 chars; the schema caps it
Twelve of those are element ORDER — the schema is an xs:sequence and these files
list valid elements in the wrong positions. The thirteenth is a real content
violation. All are pre-existing, all would fail Nextcloud's own lint-info-xml,
and all are a reorder away from passing.
The schema is fetched from nextcloud/appstore rather than vendored: a vendored
copy is a claim about what the App Store accepts that goes stale silently. The
fetch is asserted to have returned XML containing a schema element before any
validation result is trusted — a validator that could not get its schema has
validated nothing, and must say so rather than pass.
Two extra assertions cover what validity alone does not: that <version> and
<nextcloud min-version> are actually present. Their absence surfaces at release
time otherwise, long after the PR that removed them merged.
rubenvdlinde
added a commit
to ConductionNL/opencatalogi
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/portaliq
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/softwarecatalog
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/larpingapp
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. Top-level blocks are now repair-steps, settings, navigations; <php> and the <database> entries precede <nextcloud>; and inside <repair-steps>, <post-migration> precedes <install> (the schema's order is pre-migration, post-migration, live-migration, install, uninstall - it does not reflect execution order, which Nextcloud selects by event). Ordering alone was not sufficient here. The <dependencies><app> entry is not an ordering problem: the App Store schema has no <app> child under <dependencies> at any position, so it can never validate. It was also inert - OC\App\DependencyAnalyzer::analyze() handles only architecture, php, database, command, lib, os and the server version, and never looks at "app" - so it enforced nothing at install time. The dependency is now recorded as a comment in the same place. The <groups>larpers</groups> block was likewise not an ordering problem: the schema has no <groups> element, and Nextcloud never read one - OC_App's app listing sets $info['groups'] unconditionally from the app's 'enabled' appconfig value, overwriting whatever info.xml parsed. So the block restricted nothing. The requirement and the supported mechanism (app-level group restriction via occ or the Apps admin page) are documented in the comment that already stood above it. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/openbuild
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. Top-level blocks are now background-jobs, repair-steps, commands, settings, navigations; <php> precedes <nextcloud>; and inside <repair-steps>, <post-migration> precedes <install> (the schema's order is pre-migration, post-migration, live-migration, install, uninstall - it does not reflect execution order, which Nextcloud selects by event). Ordering alone was not sufficient here. The <dependencies><app> entry is not an ordering problem: the App Store schema has no <app> child under <dependencies> at any position, so it can never validate. It was also inert - OC\App\DependencyAnalyzer::analyze() handles only architecture, php, database, command, lib, os and the server version, and never looks at "app" - so it enforced nothing at install time. The dependency is now recorded as a comment in the same place. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/scholiq
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. Top-level blocks are now background-jobs, repair-steps, settings, navigations; <php> precedes <nextcloud>; and inside <repair-steps>, <post-migration> precedes <install> (the schema's order is pre-migration, post-migration, live-migration, install, uninstall - it does not reflect execution order, which Nextcloud selects by event). Ordering alone was not sufficient here. The <dependencies><app> entry is not an ordering problem: the App Store schema has no <app> child under <dependencies> at any position, so it can never validate. It was also inert - OC\App\DependencyAnalyzer::analyze() handles only architecture, php, database, command, lib, os and the server version, and never looks at "app" - so it enforced nothing at install time. The dependency is now recorded as a comment in the same place. Both entries (openregister and openconnector) were converted; the openregister version floor stays machine-readable as the constraint in lib/Settings/scholiq_register.json. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/launchpad
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. <commands> now precedes <settings>, and <navigations> follows <activity>; inside <repair-steps>, <post-migration> precedes <install> (the schema's order is pre-migration, post-migration, live-migration, install, uninstall - it does not reflect execution order, which Nextcloud selects by event). Two content fixes were unavoidable, as neither is an ordering problem. <types><search/></types> is not a valid app type at any position: the schema allows only prelogin, filesystem, authentication, extended_authentication, logging, dav, prevent_group_restriction and session, and Nextcloud does nothing with an unrecognised one. Unified search is already wired properly - Application.php calls registerSearchProvider(LaunchPadSearchProvider) - so the element was decorative. Replaced by a comment pointing at that registration. <activity><provider> had to be wrapped in <providers>. The direct child is what the schema rejects, and Nextcloud reads the provider list from $info['activity']['providers']['provider'], so the Activity provider (REQ-ACT-001) was in fact not being registered at all. The wrapping is therefore a behaviour change: OCA\LaunchPad\Activity\Extension now actually registers, which is what the requirement asked for. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/nldesign
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/openconnector
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. <category> was moved after <namespace> (the sequence is version, licence, author, namespace, types, documentation, category), and the <dependencies> children were put in php, database, lib, owncloud, nextcloud order. Ordering alone was not sufficient here. The <dependencies><app> entry is not an ordering problem: the App Store schema has no <app> child under <dependencies> at any position, so it can never validate. It was also inert - OC\App\DependencyAnalyzer::analyze() handles only architecture, php, database, command, lib, os and the server version, and never looks at "app" - so it enforced nothing at install time. The dependency is now recorded as a comment in the same place. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/openregister
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. <documentation> moved ahead of <category>; top-level blocks are now background-jobs, repair-steps, commands, settings, activity, navigations, contactsmenu; and <activity>'s children are in settings, filters, providers order. One content fix was unavoidable. <notification><service> is not an ordering problem - the App Store schema has no <notification> element at any position, and Nextcloud's InfoParser never read one, so the declaration registered nothing. The notifier is registered in PHP, via registerNotifierService(AnnotationNotifier::class) in lib/AppInfo/Application.php, which is unaffected. Replaced by a comment pointing at that registration. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/zaakafhandelapp
that referenced
this pull request
Aug 12, 2026
…:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant, and it caps <summary> at 128 characters. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml` on both counts. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. <settings> now precedes <navigations>, per the sequence. The English <summary> was 136 characters. Dropping the redundant "for Nextcloud" brings it to 122 and keeps the meaning intact - the domain (zaakgericht werken), the four capabilities and the OpenRegister foundation all survive. The Dutch <summary> was already within the cap and is unchanged. <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/doriath
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
to ConductionNL/hermiq
that referenced
this pull request
Aug 12, 2026
The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
that referenced
this pull request
Aug 12, 2026
…check Nextcloud ships phpunit-mariadb, phpunit-mysql, phpunit-oci and phpunit-sqlite as separate workflow templates, because database-portability bugs are invisible on a single backend. This fleet ran PostgreSQL only. The `database` input already accepted sqlite, pgsql and mysql, but the phpunit job wired exactly one of them: the postgres service was keyed off `inputs.database`, and the install block had a pgsql branch with everything else falling through to a bare `--database <x>` that works for sqlite and cannot work for mysql — no host, no port, no credentials, and no service container to connect to. So "mysql" was a value the input accepted and the job could not honour. WHAT CHANGED - `database-test-matrix`, a JSON array, joins the phpunit matrix beside php-version and nextcloud-ref. - A mysql:8.4 service sits beside postgres:16. Both are keyed off matrix.database rather than inputs.database, and a service whose image evaluates to an empty string is not started — which is how one job definition serves several backends. - The install block is a case statement with real host/port/credentials per backend, and an explicit failure on an unknown one. - pdo_mysql and mysqli join the extension list unconditionally. Conditional extensions would mean a mysql leg silently falling through and testing sqlite while its name said mysql. INERT UNTIL AN APP OPTS IN. The default is an empty array, which collapses to `[inputs.database]` — today's dimensions exactly. Both sides of that comparison go through fromJSON on purpose: a string test against '[]' accepts '[ ]' and '[""]' and then resolves to an EMPTY MATRIX VECTOR, and an empty vector does not skip a job, it deletes it from the run with no row, no annotation and no trace. Measured on this repo's own self-test for frontend-checks: 19 jobs instead of 21. Verified here against all three spellings of empty plus a real three-backend array. POSITIVE CONTROL IN THE JOB. `maintenance:install` can exit 0 having fallen back to another backend, and a suite passing on sqlite while its leg is labelled mysql is worse than no leg at all — it is a green cell asserting something about a database it never touched. The step reads `occ config:system:get dbtype` back and fails if it does not match the leg's own name. That completes the five checks Nextcloud runs and we did not: info.xml XSD (#383), app:check-code and REUSE (this branch), integrity:sign-app (#375), and multi-database PHPUnit.
rubenvdlinde
added a commit
that referenced
this pull request
Aug 12, 2026
#383 (info.xml XSD) and this branch (app:check-code, REUSE, multi-database PHPUnit) both insert jobs immediately before the Vue Quality group, so git saw four conflicts that are all pure additions rather than competing edits. Resolved by keeping both sides. Verified after resolving: 20 jobs, no duplicate job names, YAML parses, and all four of info-xml / app-check-code / reuse / phpunit are present. A keep-both resolution that silently dropped one side would look identical to a clean merge in the diff, so the job list is checked rather than assumed.
rubenvdlinde
added a commit
that referenced
this pull request
Aug 12, 2026
…, multi-DB PHPUnit (#385) * feat(quality): adopt occ app:check-code and REUSE, the last two Nextcloud checks Nextcloud runs five checks this fleet did not. #383 added the first (info.xml against the App Store XSD). This adds two more; multi-database PHPUnit is the remaining one and is a larger change to the phpunit job, tracked separately. occ app:check-code ------------------ Nextcloud's own tool for private and deprecated API usage. Our closest equivalent was ONE hand-written PHPCS sniff covering ONE symbol — \OC::$server, removed in NC 34 — written by hand precisely because static analysis could not see the removal while nextcloud/ocp sat a major below the declared min-version. app:check-code is the general form of that sniff: it knows the whole private surface of the server it ships with, needs no per-symbol maintenance, and moves forward when Nextcloud does. The server is fetched at the version the app DECLARES, anchored to the <nextcloud> element. Unanchored, the pattern returns 8 for thirteen fleet apps (from <php min-version="8.3"/>) and a plausible-but-wrong 28 for a fourteenth. REUSE ----- Nextcloud runs reuse.yml on every app. We had a PHPCS sniff checking @license and @copyright in PHP docblocks — a proxy for one file type that says nothing about images, JSON, YAML, or the LICENSES/ directory REUSE requires. It also closes a loop the coding-standard migration opened: the SPDX InvalidEndChar exception in the shared ruleset exists because a trailing full stop turns a machine-parsed SPDX expression into an invalid one. That exception is only worth having if something actually parses those expressions. BOTH ARE NON-BLOCKING BY DEFAULT, and that is a decision rather than timidity. Every app here reaches into server internals somewhere — OCA\DAV, OC_App and Doctrine\DBAL are all ignored by name in phpstan-base.neon — and only 2 of the 4 apps sampled ship a REUSE.toml at all. A gate that is red on arrival is a gate nobody turns on: that is how openregister ended up with an E2E job that had never once succeeded. Each carries a `*-blocking` input to flip per app once its findings are worked down. app:check-code carries a positive control. occ exits 0 on paths that inspect nothing — an app directory it cannot see, a command that bailed on the environment check — so the step asserts the log contains a recognisable verdict before treating any exit code as evidence. A silent exit 0 must not read as "no private API usage". * feat(quality): multi-database PHPUnit — the fifth and last Nextcloud check Nextcloud ships phpunit-mariadb, phpunit-mysql, phpunit-oci and phpunit-sqlite as separate workflow templates, because database-portability bugs are invisible on a single backend. This fleet ran PostgreSQL only. The `database` input already accepted sqlite, pgsql and mysql, but the phpunit job wired exactly one of them: the postgres service was keyed off `inputs.database`, and the install block had a pgsql branch with everything else falling through to a bare `--database <x>` that works for sqlite and cannot work for mysql — no host, no port, no credentials, and no service container to connect to. So "mysql" was a value the input accepted and the job could not honour. WHAT CHANGED - `database-test-matrix`, a JSON array, joins the phpunit matrix beside php-version and nextcloud-ref. - A mysql:8.4 service sits beside postgres:16. Both are keyed off matrix.database rather than inputs.database, and a service whose image evaluates to an empty string is not started — which is how one job definition serves several backends. - The install block is a case statement with real host/port/credentials per backend, and an explicit failure on an unknown one. - pdo_mysql and mysqli join the extension list unconditionally. Conditional extensions would mean a mysql leg silently falling through and testing sqlite while its name said mysql. INERT UNTIL AN APP OPTS IN. The default is an empty array, which collapses to `[inputs.database]` — today's dimensions exactly. Both sides of that comparison go through fromJSON on purpose: a string test against '[]' accepts '[ ]' and '[""]' and then resolves to an EMPTY MATRIX VECTOR, and an empty vector does not skip a job, it deletes it from the run with no row, no annotation and no trace. Measured on this repo's own self-test for frontend-checks: 19 jobs instead of 21. Verified here against all three spellings of empty plus a real three-backend array. POSITIVE CONTROL IN THE JOB. `maintenance:install` can exit 0 having fallen back to another backend, and a suite passing on sqlite while its leg is labelled mysql is worse than no leg at all — it is a green cell asserting something about a database it never touched. The step reads `occ config:system:get dbtype` back and fails if it does not match the leg's own name. That completes the five checks Nextcloud runs and we did not: info.xml XSD (#383), app:check-code and REUSE (this branch), integrity:sign-app (#375), and multi-database PHPUnit.
rubenvdlinde
added a commit
to ConductionNL/larpingapp
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 57 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame 6a673f0 touches 57 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. Top-level blocks are now repair-steps, settings, navigations; <php> and the <database> entries precede <nextcloud>; and inside <repair-steps>, <post-migration> precedes <install> (the schema's order is pre-migration, post-migration, live-migration, install, uninstall - it does not reflect execution order, which Nextcloud selects by event). Ordering alone was not sufficient here. The <dependencies><app> entry is not an ordering problem: the App Store schema has no <app> child under <dependencies> at any position, so it can never validate. It was also inert - OC\App\DependencyAnalyzer::analyze() handles only architecture, php, database, command, lib, os and the server version, and never looks at "app" - so it enforced nothing at install time. The dependency is now recorded as a comment in the same place. The <groups>larpers</groups> block was likewise not an ordering problem: the schema has no <groups> element, and Nextcloud never read one - OC_App's app listing sets $info['groups'] unconditionally from the app's 'enabled' appconfig value, overwriting whatever info.xml parsed. So the block restricted nothing. The requirement and the supported mechanism (app-level group restriction via occ or the Apps admin page) are documented in the comment that already stood above it. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
pushed a commit
that referenced
this pull request
Aug 12, 2026
#383's 5/13 was measured before it merged. Re-measured against every repo's live development tip with the same App Store XSD: 6 pass, 12 fail. The one-app difference is larpingapp, whose manifest was reordered by efa6aead at 11:28:48Z; validating that single file at both refs gives FAIL then PASS, so the difference is the world moving rather than the instrument drifting. Also records that the local validator reproduces the live CI message on openregister byte for byte, and that the count decays.
rubenvdlinde
added a commit
to ConductionNL/doriath
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 426 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame 8f2ab30 touches 426 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(ci): pin symfony/string back to the 8.3-compatible line and clear 2 over-length lines Every PHP job on this branch was red, phpcs included, and none of them had reached their tool. The phpcs job log stops at composer install: - symfony/string v8.1.2 requires php >=8.4.1 -> your php version (8.3; overridden via config.platform, actual: 8.3.33) does not satisfy that requirement. ##[error]Your lock file does not contain a compatible set of packages. composer.json pins config.platform.php to 8.3, but the lock regenerated in the previous commit was resolved without that platform in force, so it took symfony/string v8.1.2 — the first release of that package to require PHP 8.4.1. `composer update symfony/string --with-all-dependencies` under the declared platform downgrades it to v7.4.15; the lock diff is that one package and nothing else. With composer install succeeding, phpcs then reported 2 real errors, both Generic.Files.LineLength.MaxExceeded (185 and 166 characters) on the @return description of registerFanOutShares(). The description moves into the docblock body, where php-cs-fixer's phpdoc_align has no opinion about its column. Measured locally on php 8.3.33 with the branch's own vendor tree: `phpcs --standard=phpcs.xml` exits 0 (768 @SPEC warnings remain, which ignore_warnings_on_exit deliberately does not fail on), and `php-cs-fixer fix --dry-run` finds 0 of 425 files to fix. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command.
rubenvdlinde
added a commit
that referenced
this pull request
Aug 12, 2026
… and disable the dead app:check-code (#389) TWO DEFECTS, plus a third found on the way in. 1. quality.yml produced ZERO JOBS fleet-wide since 11:26:16Z. #385 merged from a branch written before #383; its hunks anchored on what had become info-xml's Checkout step, and the clean textual merge spliced two jobs into a third — app-check-code lost its steps:, reuse swallowed info-xml's body, a stray sparse-checkout landed inside a run: block, and the final upload-artifact ended up with two name: keys. Every core app consumes this file at @main, so both apps that pushed after 11:26 got a run with no jobs at all (openconnector 31592994170, larpingapp 31592027242). An unresolvable reusable workflow never goes red on its own; only this repo's resolve probe noticed. Note for future linting: PyYAML's safe_load parses the broken file happily and reports twenty jobs, so a generic YAML lint would have called it clean. 2. None of the three Nextcloud legs was in the Quality Report's needs:, which is the only meaningful required check across the fleet. Now 16 -> 19. That is three jobs, not five: multi-database PHPUnit is a matrix dimension of phpunit and was already covered, and integrity:sign-app lives in release.yml, which has no Quality Report to gate. 3. occ app:check-code WAS REMOVED FROM NEXTCLOUD AFTER v20, so that job cannot pass anywhere here. Extracting registered App-namespace commands from core/register_command.php, same expression, only the tag varying: v20 yields CheckCode alongside the others, v34 yields the others without it — v20 is the control proving the extraction can produce the token. Corroborated on a second artefact: core/Command/App/CheckCode.php is 200 at v20/v21 and 404 at v25 through v34, while ListApps.php is 200 at every one of those tags. Every app here declares min-version 31+, and the job's positive control carries an unconditional exit 1 that sits above the check-code-blocking branch — so merging it into needs: would have hard-failed all 18 PHP apps on an impossible check. enable-check-code now defaults false, with the job left wired and still in needs: (a skipped result is skipped, not failure) so the wiring is right when someone rebuilds the check. The positive control was correct throughout: it refused to certify a run that inspected nothing. BLAST RADIUS, re-measured rather than quoted. info-xml has no blocking flag and gates on arrival. Against every repo's live development tip: 6 pass, 12 fail — not #383's 5/13. The difference is larpingapp, reordered by efa6aead at 11:28:48Z; that one file validates FAIL at the old ref and PASS at the new one. Eleven of the twelve are xs:sequence element order; the twelfth is an over-length summary. All are a manifest edit, not a code change. That work is not filed anywhere yet. reuse and info-xml are both proven to work — reuse passes in this PR's own resolve probe, and info-xml produced a real schema error on openregister run 31591669849 that a local validator reproduces byte for byte. Only app-check-code was dead. From needs: all three looked identical. Also corrected: the queue was not held by a red guard. Six of the seven open PRs carry a Shared-workflow guard pass from BEFORE the break — stale greens that would flip red on any re-run. Only #378 is measurably blocked, by both defects. check-code-blocking and reuse-blocking are untouched. Neither was asked to move.
rubenvdlinde
added a commit
to ConductionNL/zaakafhandelapp
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 89 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame abd0dba touches 89 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): shorten summary and order info.xml per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant, and it caps <summary> at 128 characters. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml` on both counts. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. <settings> now precedes <navigations>, per the sequence. The English <summary> was 136 characters. Dropping the redundant "for Nextcloud" brings it to 122 and keeps the meaning intact - the domain (zaakgericht werken), the four capabilities and the OpenRegister foundation all survive. The Dutch <summary> was already within the cap and is unchanged. <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * fix(quality): pay off the #201 docblock/named-args debt the ruleset stub stopped demoting The phpcs job on this branch failed for two different reasons in succession, and only the second one is about this app's code. At 1ef084d the job never reached phpcs at all: - Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. - Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. ##[error]Process completed with exit code 4. 6e94b38 fixed the lock, composer install succeeded, and phpcs then ran for the first time on this branch — reporting 613 errors. Those are not new code. They are debt this app has always carried, and the old phpcs.xml said so out loud: <!-- LEGACY DEBT (tracked in #201): this app pre-dates the tightened Conduction PHPCS commenting / named-parameter rules. Until a dedicated docblock + named-args cleanup lands, the following sniffs are demoted from errors to advisory warnings ... --> Nine sniffs were demoted there, plus NamedParametersSniff. The migration replaces phpcs.xml with a 12-line stub over the shared ruleset, and a stub cannot carry an app-local demotion — so the whole of #201 promoted from warning to error in a single config commit. Nothing was measured wrong; the severity floor moved. Rather than re-demote them (a stub that argues with the fleet ruleset is the thing this migration exists to remove, and gate-65 would reject it), this commit does the cleanup #201 was waiting for. All 613, across 52 files: 186 CustomSniffs.Functions.NamedParameters.RequireNamedParameters 173 PEAR.Commenting.FunctionComment.MissingParamTag 75 PEAR.Commenting.FunctionComment.MissingReturn 72 PEAR.Commenting.FunctionComment.Missing 27 Squiz.PHP.DisallowInlineIf.Found 16 Squiz.Operators.ComparisonOperatorUsage.ImplicitTrue 15 Generic.Files.LineLength.MaxExceeded 14 Squiz.Commenting.InlineComment.NotCapital 12 Squiz.Commenting.VariableComment.Missing 10 PEAR.Commenting.FunctionComment.ParamNameNoMatch 7 Generic.Commenting.DocComment.ParamNotFirst 3 Squiz.Operators.ComparisonOperatorUsage.NotAllowed 3 (WrongStyle, MissingParamComment, SpacingBeforeShort) Two of these carry real risk and were not applied mechanically. ImplicitTrue's message says "use === TRUE instead", and taking that literally is a bug factory: `filter_var($id, FILTER_VALIDATE_URL)` returns the URL STRING, so `=== true` would have made that branch dead and passed every URL through unstripped. Each site got the predicate that is actually correct for its type. Where `empty()` was guarding a config string it was kept as `empty($x) === true` rather than narrowed to `$x === ''`, because `empty('0')` is true and a literal "0" register would otherwise have flipped from unconfigured to configured. A wrong named argument is a fatal Error at runtime that neither `php -l`, phpcs, psalm nor an untouched test can see. Every one of the 186 was written from the callee's real signature — `assertUuid(value: ...)` not `zaakId:`, `getObjects(sort: $params['order'])` not `order:` — and the whole tree was then re-checked by a tokenizer pass that resolves each `$this->`/`self::`/ `new` call to its declaration and compares labels: 276 named arguments, 0 mismatches. That check was shown to fail on an injected typo first. Measured on php 8.3.33 with this branch's own vendor tree: phpcs 613 errors -> 0 (270 warnings remain: @SPEC and the SPDX InvalidEndChar exemption, both non-blocking by design) php-cs-fixer 0 of 88 files to fix — the two tools are not arguing php -l clean over lib/ PHPUnit OK (268 tests, 825 assertions), unchanged from the baseline psalm 0 errors, same as the pre-change tree phpstan 0 errors, same as the pre-change tree Auth posture is unchanged and was counted, not assumed: NoAdminRequired 132 -> 132, NoCSRFRequired 138 -> 138, @no-admin-idor-exempt 3 -> 3. Where Generic.Commenting.DocComment.ParamNotFirst and the annotations' original position were mutually exclusive, @PARAM moved above the annotations within the same docblock; NC's ControllerMethodReflector scans the whole block, so position is not load-bearing. No sniff was suppressed and no @phpcs:ignore was added. Closes #201. * fix(quality): remove the 16 else branches the ternary rewrites introduced The previous commit rewrote 27 inline ternaries as if/else to satisfy Squiz.PHP.DisallowInlineIf. phpcs went green and phpmd went red: lib/Controller/ZakenController.php:264 ElseExpression The method destroy uses an else expression. Else clauses are basically not necessary and you can simplify the code by not using them. 16 of those, and phpmd was SUCCESS on the previous run (31586148039) — so this was mine, not pre-existing. Two gates in the same pipeline disagreed about the shape of a two-way choice and I only checked one of them before pushing. Rewritten as assign-default-then-override, or as an early `continue` where the branch sits in a loop. Same outcomes, same evaluation order, no ternary and no else. Measured on php 8.3.33 with this branch's vendor tree, all six gates that this commit could plausibly touch: phpmd 16 violations -> 0 (both phpmd.xml and phpmd-unusedparams.xml) phpcs 0 errors php-cs-fixer 0 of 88 files to fix PHPUnit OK (268 tests, 825 assertions) psalm 0 errors phpstan No errors * fix(quality): restore the #201 deviation in the stub instead of paying the debt here The migration to the shared semantics-only ruleset dropped this app's documented exemption. Its previous phpcs.xml demoted ten commenting and named-parameter sniffs from errors to warnings, with #201 tracking the cleanup; the stub replaced that wholesale and the app went red on debt it had been explicitly excused from. Reverts the two commits that tried to fix it the other way — paying the debt off inside this PR by rewriting docblocks and ternaries across the controllers, then removing the sixteen else branches those rewrites introduced. That work is #201's and it does not belong here: it puts real behaviour changes into a pull request whose central claim is that it changes no behaviour, and the diff stops being reviewable at exactly the moment reviewing it matters. The shared stub was designed to carry a deviation like this — "App-specific deviations go BELOW this line, each with a reason and a tracking issue" — so it is restored there, named and tracked, rather than suppressed centrally or paid off opportunistically. Structural rules still gate the build as errors: spacing, control structures, banned debug functions, and the removed-Nextcloud-API sniff. gate-65 permits this. It fails an app for declaring FORMATTING sniffs locally, or for pinning a shared package — not for a reasoned severity change on a semantic rule, which is exactly the escape hatch that keeps a shared standard adoptable. * style(stylelint): drop two empty <style> blocks the widened glob now checks The config commit quoted the stylelint glob. Unquoted, `src/**/*.vue` was expanded by the shell (no globstar) to a single level, so nothing under src/modals/<subdir>/ had ever been linted. Quoting it hands expansion to stylelint, which walks the tree and found two no-empty-source violations. Both files are untouched by this PR and carry the same empty block on development, so this is pre-existing debt the wider check exposed rather than anything the reformat introduced. An empty, non-scoped <style> block emits no CSS, so removing it is behaviour-neutral: 6 deletions, 0 insertions. no-empty-source is not auto-fixable, so this is a hand fix. The glob stays quoted.
rubenvdlinde
added a commit
to ConductionNL/openconnector
that referenced
this pull request
Aug 12, 2026
TWO DEFECTS, both of which made a job red rather than a finding. 1. composer.lock locked packages this app's own platform cannot run. `config.platform.php` is pinned to "8.3", and the lock carried symfony/string v8.1.2, symfony/finder v8.1.1 and symfony/process v8.1.0 — all three require php >=8.4.1. That is the signature of a regeneration run with a blanket `--ignore-platform-reqs`: the flag suppresses the PHP version constraint as well as the extension ones, so composer resolves against a platform that does not exist here and writes the result down as if it did. `composer validate` passes on such a lock — the content-hash still matches composer.json — so the defect is invisible to the check most likely to be run, and only surfaces at install time. In CI it took out NINE jobs, all with the same line and none of them naming a package this app requires directly: Your lock file does not contain a compatible set of packages. PHP Quality (lint / phpcs / phpmd / phpstan / psalm / phpmetrics) Security (composer), License (composer) PHPUnit (8.3 and 8.4), Integration Tests (Newman), E2E (Playwright) and it cascaded one gate further: gate-33 axe-core reported SKIPPED (structural) because the Playwright job that produces its report never ran. Re-resolved with the three packages named explicitly and `--ignore-platform- req=ext-*` — extension constraints only, so the PHP version stays enforced. They downgrade to the 7.4 line, which is where the rest of the symfony packages here already are: symfony/finder v8.1.1 -> v7.4.14 symfony/process v8.1.0 -> v7.4.13 symfony/string v8.1.2 -> v7.4.15 `nextcloud/ocp` is unaffected and still resolves to v34.0.2, which is the point of this PR. `composer install --dry-run` under the pinned 8.3 platform now completes, and a sweep of every locked package's `require.php` finds zero above 8.3 — the same sweep over the previous lock finds exactly those three, so it is a measurement and not a hopeful assertion. 2. appinfo/info.xml did not validate against the App Store schema. `info.xml lint` landed in the shared workflow today (ConductionNL/.github#383) and this is the first run that had it. The App Store's info.xsd declares repair-steps as an xs:sequence — pre-migration, post-migration, live-migration, install, uninstall — so `<install>` must come AFTER `<post-migration>`, which is the opposite of the order they run in and the opposite of how #1224 wrote them: appinfo/info.xml:115: element post-migration: Schemas validity error : Element 'post-migration': This element is not expected. Expected is ( uninstall ). Swapped, with the constraint written down next to it so the intuitive order does not come back. Nothing about which hooks run, or when, changes.⚠️ THE BASE BRANCH FAILS THIS CHECK TOO, and earlier: `origin/development`'s info.xml is rejected at line 28 with `Element 'category': This element is not expected. Expected is one of ( licence, author )`. This branch already fixed that half in d960a2f. Verified by running xmllint against the real appstore info.xsd over both files — head validates, base does not.
rubenvdlinde
added a commit
to ConductionNL/portaliq
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 96 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame 9a97095 touches 96 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * fix(ci): adopt NC 34 by ADDING it to the matrix, and unpin the admin-nav selector The config commit replaced `nextcloud-test-refs` with `["stable34"]`. That turned three jobs red, all three green on development (run 31574689088), so all three are this change's doing. It also silently dropped the stable32 and stable33 legs development had. 1. PHPUnit — AppInfoDependenciesTest::testFloorIsNotBelowTheOldestTestedVersion failed: "declares min-version=32 but the oldest Nextcloud this repo tests is 34 ... Either raise min-version to 34 or add the missing leg(s) to the matrix." Took the second option, because the first is a support-policy change and this is a formatting chore. The matrix is now ["stable34", "stable32", "stable33"] — every major inside the declared 32-34 range, which also satisfies testEveryTestedVersionIsInsideTheDeclaredRange from the other side. 2. E2E — "SettingsSection must contribute an entry to the admin navigation" was never true. The section registers fine; the locator was scoped to `#app-navigation`, which NC 34 does not render. Verified against nextcloud/server: apps/settings/templates/settings/frame.php is `<div id="app-navigation">` on stable32 and stable33, and on stable34 the same file is `<div id="settings-app"></div>` — the settings page became a Vue app, and apps/settings/src/views/SettingsNavigation.vue renders the list via `<NcAppNavigation>`, whose root is `id="app-navigation-vue"`. The selector now accepts either container, so it is honest on all three legs rather than on the two it happened to be written against. This is exactly why stable34 is first in the list: [0] is the server playwright gets. Not fixed here, on purpose: - gate-16 flags WooController::serve and ::servePath as changed methods missing @SPEC. They are pre-existing debt, not a regression: `git show origin/development:lib/Controller/WooController.php` has zero @SPEC tags in the file, and so does HEAD — the reformat only alphabetised one import and moved a brace (`git diff -w` on that file shows nothing else), which is enough to pull two long-untagged methods into a diff-scoped gate. gate-16 cannot be run on development for comparison — it reports NOT APPLICABLE with no diff by design (ADR-020) — so the base-tree read is the available evidence. Tagging them would be paying legacy debt inside a whitespace PR. - gate-48 is a known false positive fixed upstream in ConductionNL/.github#388 (merged, b745bf2), which apps pick up automatically via the floating hydra-gates ref. Measured here too: NoCSRFRequired count is 32 on origin/development and 32 on HEAD, identical per file, and the diff is 21 removals against 21 identical additions plus 6 against 6 in docblocks — every one a four-spaces-to-tab re-indent. No waiver added.
rubenvdlinde
added a commit
to ConductionNL/opencatalogi
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 195 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame 6a93c2c touches 195 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * style(stylelint): clear the lint debt the widened glob newly exposes The config commit quoted the previously-unquoted stylelint glob. Unquoted, /bin/sh (dash) expanded 'src/**/*.vue' as 'src/*/*.vue' — one directory deep — so every component nested two levels under src/ was silently never linted. Quoting it hands the pattern to stylelint, whose own glob engine recurses. These violations are pre-existing debt in newly-covered files, not regressions: every offending file sits at src/<a>/<b>/<file>.vue and was matched zero times by the old expansion. Fixed with stylelint --fix (rule-empty-line-before) plus one hand-removed verbatim duplicate selector where --fix could not. No hardcoded colours introduced; the glob is left widened. * ci: re-run against the repaired shared quality.yml The previous run hit a startup failure: quality.yml@main carried a duplicate 'name:' key and a job with no steps, spliced in by .github#385. Repaired by .github#389. A startup-failed run cannot be re-run, so this empty commit requests a fresh evaluation. * fix: drop an accidentally committed node_modules symlink Local tooling symlink picked up by 'git add -A'. It escaped .gitignore because the rule is 'node_modules/' with a trailing slash, which matches a DIRECTORY — a symlink of the same name is a blob (mode 120000), not a directory, so the rule never applied. It pointed at an absolute path outside the repo.
rubenvdlinde
added a commit
to ConductionNL/softwarecatalog
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 210 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame a78e00a touches 210 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * fix(static-analysis): repair what the nextcloud/ocp 31 -> 34 bump and the elseif normalisation surfaced PHPStan (5 errors), all from the OCP 31 -> 34 stub change: - IQueryBuilder::execute() is gone from the OCP 34 interface. The four call sites in OrganizationSyncService are all SELECTs, so they become executeQuery(); no behaviour change. - TemplateResponse's 4th constructor argument is $renderAs (a string enum), not the HTTP status; the 5th is int $status. The error branch in DashboardController passed '500' as $renderAs, so it rendered with an invalid layout and still returned HTTP 200. It now passes RENDER_AS_ERROR plus STATUS_INTERNAL_SERVER_ERROR. Psalm (2 ParadoxicalCondition errors): extractPropertyDefinitionMap in ArchiMateService and ArchiMateImportService each end with an elseif that repeats the opening if verbatim, so the third branch is unreachable. The duplicate is pre-existing (origin/development ArchiMateService.php:2437); what changed is that php-cs-fixer rewrote 'else if' to 'elseif', and Psalm reports the elseif form as ParadoxicalCondition but the 'else if' form as NoValue -- and psalm.xml suppresses NoValue. Verified with a two-file control. Removing the unreachable branch is behaviour-identical. * ci: re-trigger Code Quality The previous run produced zero jobs and concluded failure: it started inside the window where ConductionNL/.github@main carried the broken quality.yml splice from b745bf2f, repaired at 4118bca8. Nothing in this PR touches the workflow.
rubenvdlinde
added a commit
to ConductionNL/hermiq
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 397 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame b2af4be touches 397 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(quality): clear the 15 phpcs errors this branch's semantics-only ruleset surfaces composer install succeeds here, so unlike the other apps in this migration the phpcs job actually reached the tool and reported real findings: FOUND 10 ERRORS ... PEAR.Commenting.FunctionComment.ParamCommentAlignmentExceeded Line exceeds maximum limit of 150 characters; contains 160 / 153 / 210 / 182 / 182 Two distinct causes. 1. Five over-length lines, all the same shape: a long @return type whose description continues on the next line, aligned past column 150. The descriptions move into the docblock body. Nothing about the contract changes; the text stops being pushed off the right edge. 2. Ten ParamCommentAlignmentExceeded on RunTokenService::mint(). The shared ruleset switches PEAR's alignment codes off individually — including ParamCommentAlignment — because alignment is php-cs-fixer's job now. It does not switch off the sibling code PEAR emits when the comment is aligned too FAR right: ParamCommentAlignmentExceeded. This block's continuation lines sit at 33 spaces where the sniff computes 29, so the only app in the fleet with a wide param-comment block is the only one that trips it. Re-indented to 29. The gap in the shared ruleset is reported separately; this app does not work around it locally. Measured locally on php 8.3.33 with the branch's own vendor tree: `phpcs --standard=phpcs.xml` exits 0 (3 @SPEC warnings remain, which ignore_warnings_on_exit deliberately does not fail on), and `php-cs-fixer fix --dry-run` finds 0 of 396 files to fix — so the re-indent is stable and the two tools are not arguing. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * fix: repair the analysis stub and widen-exposed stylelint findings PHPStan (12 errors). OCP 34 rewrote OCP\Server::get()'s docblock: v31.0.9 carried a plain '@return T|mixed', which PHPStan resolves to mixed, so Server::get(self::BROKER_CLASS) produced an untyped object. v34.0.2 drops the plain @return and keeps only the conditional '@psalm-return ($serviceName is class-string<T> ? T : mixed)', so PHPStan now resolves the literal class-string constant to the real class and reads our own tests/Stubs CredentialBrokerService. Two stub-fidelity gaps then surfaced: - request() promised array{status: int, headers: ..., body: string} with all keys required, making the callers' '?? ' fallbacks look redundant. The keys are now optional. The broker is a SOFT boundary reached through a class_exists() probe, so hermiq runs against whatever openregister version is installed and cannot promise a key is present; the callers defend each one, and the stub should not contradict them. - resolveInjectable() was missing entirely. Added with the signature ProviderFactory::resolveCliToken() already documents (string|null, where null is a routing signal rather than a denial). No application code changed; both fixes are in the analysis stub. stylelint: 16 rule-empty-line-before errors, all auto-fixed. They were never linted before because the glob was unquoted, so the shell expanded 'src/**/*.vue' to 'src/*/*.vue' and never reached src/components/<dir>/<file>.vue. The check script was quoted in the config commit; the stylelint-fix script is now quoted to match, so fix and check cover the same set.
rubenvdlinde
added a commit
to ConductionNL/nldesign
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 128 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame 8c0f6b8 touches 128 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. Nothing was added, removed or reworded; <version> and the <nextcloud> min/max-version declaration are unchanged. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * fix(ci): make the NC 34 move honest — test both ends of the declared range The config commit moved `nextcloud-test-refs` to `["stable34"]` and pointed stylelint at a directory this app does not have. Five jobs went red, all five green on development (run 31573122447), so all five are this change's doing. 1. PHPUnit — ClaimAccuracyTest::testDeclaredNextcloudRangeMatchesTheTestedMatrix failed: "declares min-version=32, but the lowest ref CI tests is stable34". That guard exists because this attribute already drifted from the matrix twice (#241/#242). Resolved by testing the range rather than shrinking it: `["stable34", "stable32"]`. The stable34 leg is the only thing that can catch a symbol REMOVED in 33/34 — the stated reason for this migration — and the stable32 leg is the only thing that can catch a symbol that does not exist yet at the declared floor. Raising the floor to 34 instead would have been a support-policy change smuggled into a formatting chore, and it would have falsified six ALLOWED reasons in selector-liveness that read "kept for older servers". 2. E2E — selector-liveness reported eight selectors matching nothing. Not a flake and not a regression in the CSS: stable34 is the FIRST survey this spec has ever taken above NC 32, and NC 32/33 header markup (app-menu-entry__*, app-menu-icon, unified-search-menu — several added by #260 one commit ago) genuinely does not exist there. They are the mirror image of the SINCE list, which meanwhile did its job perfectly: every selector it deferred came back live on 34, so the expiry assertion passed unattended. Recorded in ALLOWED with both measurements behind them, and the file's stale "CI pins ["stable32"]" note corrected. 3. stylelint — the glob became `src/**/*.{vue,scss,css}`, which is a template from an app with Vue components. nldesign has no `src` CSS at all (`lint` is literally `echo 'No JavaScript to lint - nldesign is CSS/PHP only'`), so stylelint exited 1 with NoFilesFoundError and linted nothing. Now `"css/**/*.{css,scss}"` — quoted, so stylelint expands it rather than the shell, and verified a superset: 110 files under the old `'css/**/*.css'`, the same 110 under the new one, none dropped. Verified locally: the shipped glob reproduces NoFilesFoundError and the new one exits 0; the two claim-accuracy assertions now hold (min 32 == lowest 32, max 34 >= highest 34); vitest 81/81; tsc reports nothing in the edited spec. appinfo/info.xml keeps min-version=32 — only its prose is corrected, since it claimed CI pinned stable32.
rubenvdlinde
added a commit
to ConductionNL/launchpad
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 476 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame 46e028e touches 476 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. <commands> now precedes <settings>, and <navigations> follows <activity>; inside <repair-steps>, <post-migration> precedes <install> (the schema's order is pre-migration, post-migration, live-migration, install, uninstall - it does not reflect execution order, which Nextcloud selects by event). Two content fixes were unavoidable, as neither is an ordering problem. <types><search/></types> is not a valid app type at any position: the schema allows only prelogin, filesystem, authentication, extended_authentication, logging, dav, prevent_group_restriction and session, and Nextcloud does nothing with an unrecognised one. Unified search is already wired properly - Application.php calls registerSearchProvider(LaunchPadSearchProvider) - so the element was decorative. Replaced by a comment pointing at that registration. <activity><provider> had to be wrapped in <providers>. The direct child is what the schema rejects, and Nextcloud reads the provider list from $info['activity']['providers']['provider'], so the Activity provider (REQ-ACT-001) was in fact not being registered at all. The wrapping is therefore a behaviour change: OCA\LaunchPad\Activity\Extension now actually registers, which is what the requirement asked for. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * fix(deps): pin nextcloud/ocp to ^34.0 instead of dev-master dev-master has advanced to the Nextcloud 35 development stubs, where ISchemaWrapper::createTable()/getTable() return the new OCP\DB\Schema\ITable (@SInCE 35.0.0) rather than being documented as returning \Doctrine\DBAL\Schema\Table. That made PHPStan report 17 genuine parameter-type mismatches in the Migration table builders, which type-hint Doctrine\DBAL\Schema\Table. The app declares <nextcloud min-version="32" max-version="34"/>, so analysing against NC 35 development stubs was wrong regardless. Pinning to ^34.0 matches the constraint used by every other app in this migration (softwarecatalog, hermiq, pipelinq) and by the merged reference larpingapp#313. PHPStan is now clean; no application code changes. * ci: re-trigger Code Quality The previous run produced zero jobs and concluded failure: it started inside the window where ConductionNL/.github@main carried the broken quality.yml splice from b745bf2f, repaired at 4118bca8. Nothing in this PR touches the workflow. * fix(tests): make the ICache test doubles match the real interface OCP\ICache is untyped on every Nextcloud version this app supports — 'get($key)', 'set($key, $value, $ttl = 0)', 'hasKey($key)', 'remove($key)', 'clear($prefix = "")' — identical in server stable32 and stable34. The three in-test fakes narrowed every parameter to string/int, which PHP rejects as an incompatible declaration: PHP Fatal error: Declaration of Unit\Activity\FakeDebounceCache::get( string $key) must be compatible with OCP\ICache::get($key) They only ever loaded because the app resolved nextcloud/ocp at dev-master, which has advanced to the NC 35 development stubs where ICache::get() IS typed. Pinning ocp to ^34.0 lines the stub up with the servers this app actually declares support for, and the fakes then have to line up too. Return types are left in place — widening a parent's absent return type is covariant and legal. Parameter types only; no test behaviour changes. The three affected files run green: OK (39 tests, 80 assertions). * fix(ci): test the whole declared Nextcloud range, not only the ceiling appinfo/info.xml declares <nextcloud min-version="32" max-version="34"/>, but nextcloud-test-refs was '["stable34"]' — so the declared floor and the middle major were advertised to the App Store with no job touching either. This is the coding-standard migration's own defect: its rollout REPLACED the ref list instead of extending it. The programme opened by reporting that nothing was tested on NC 34 and, in fixing that, made 32 and 33 the untested end. Same drift, other direction. stable34 stays first because newman, playwright and journeydoc-capture all read fromJSON(inputs.nextcloud-test-refs)[0] as their single server. Verified green on all three refs against nextcloud/ocp ^34 on portaliq (run 31599055849, six PHPUnit legs: 32/33/34 x PHP 8.3/8.4).
rubenvdlinde
added a commit
to ConductionNL/openconnector
that referenced
this pull request
Aug 12, 2026
) * chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 712 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame 0a5295c touches 712 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. <category> was moved after <namespace> (the sequence is version, licence, author, namespace, types, documentation, category), and the <dependencies> children were put in php, database, lib, owncloud, nextcloud order. Ordering alone was not sufficient here. The <dependencies><app> entry is not an ordering problem: the App Store schema has no <app> child under <dependencies> at any position, so it can never validate. It was also inert - OC\App\DependencyAnalyzer::analyze() handles only architecture, php, database, command, lib, os and the server version, and never looks at "app" - so it enforced nothing at install time. The dependency is now recorded as a comment in the same place. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * docs(ci): say why the test matrix is stable34, and that it is a narrowing The comment above `nextcloud-test-refs` explained a choice of `["stable32", "stable33"]` while the value directly below it read `["stable34"]` — the config commit changed the value and left the reasoning describing the old one. A comment that contradicts the line it sits on is worse than no comment: the next reader trusts it. Records the actual reason (ocp ^34 stubs and the tested server should be the same server) and, more importantly, records what the change COSTS: info.xml still declares `min-version="32" max-version="34"`, so the app claims three server versions and CI now exercises one. NC32 and NC33 are unmeasured from here, not known-good. Names both ways the gap can be closed so it is a tracked trade rather than an accident. No behaviour change — comment only. * fix: a lock regenerated with --ignore-platform-reqs cannot be installed TWO DEFECTS, both of which made a job red rather than a finding. 1. composer.lock locked packages this app's own platform cannot run. `config.platform.php` is pinned to "8.3", and the lock carried symfony/string v8.1.2, symfony/finder v8.1.1 and symfony/process v8.1.0 — all three require php >=8.4.1. That is the signature of a regeneration run with a blanket `--ignore-platform-reqs`: the flag suppresses the PHP version constraint as well as the extension ones, so composer resolves against a platform that does not exist here and writes the result down as if it did. `composer validate` passes on such a lock — the content-hash still matches composer.json — so the defect is invisible to the check most likely to be run, and only surfaces at install time. In CI it took out NINE jobs, all with the same line and none of them naming a package this app requires directly: Your lock file does not contain a compatible set of packages. PHP Quality (lint / phpcs / phpmd / phpstan / psalm / phpmetrics) Security (composer), License (composer) PHPUnit (8.3 and 8.4), Integration Tests (Newman), E2E (Playwright) and it cascaded one gate further: gate-33 axe-core reported SKIPPED (structural) because the Playwright job that produces its report never ran. Re-resolved with the three packages named explicitly and `--ignore-platform- req=ext-*` — extension constraints only, so the PHP version stays enforced. They downgrade to the 7.4 line, which is where the rest of the symfony packages here already are: symfony/finder v8.1.1 -> v7.4.14 symfony/process v8.1.0 -> v7.4.13 symfony/string v8.1.2 -> v7.4.15 `nextcloud/ocp` is unaffected and still resolves to v34.0.2, which is the point of this PR. `composer install --dry-run` under the pinned 8.3 platform now completes, and a sweep of every locked package's `require.php` finds zero above 8.3 — the same sweep over the previous lock finds exactly those three, so it is a measurement and not a hopeful assertion. 2. appinfo/info.xml did not validate against the App Store schema. `info.xml lint` landed in the shared workflow today (ConductionNL/.github#383) and this is the first run that had it. The App Store's info.xsd declares repair-steps as an xs:sequence — pre-migration, post-migration, live-migration, install, uninstall — so `<install>` must come AFTER `<post-migration>`, which is the opposite of the order they run in and the opposite of how #1224 wrote them: appinfo/info.xml:115: element post-migration: Schemas validity error : Element 'post-migration': This element is not expected. Expected is ( uninstall ). Swapped, with the constraint written down next to it so the intuitive order does not come back. Nothing about which hooks run, or when, changes.⚠️ THE BASE BRANCH FAILS THIS CHECK TOO, and earlier: `origin/development`'s info.xml is rejected at line 28 with `Element 'category': This element is not expected. Expected is one of ( licence, author )`. This branch already fixed that half in d960a2f. Verified by running xmllint against the real appstore info.xsd over both files — head validates, base does not. * fix: clear the two quality legs the new ruleset and the reformat turned red phpstan — ONE error, and the reformat is what created it. Deprecated in PHP 8.1: Required parameter $flowToken follows optional parameter $synchronization. lib/Service/SynchronizationService.php `synchronizeContract()` reads the same on both branches, but not to PHP. On `development` the parameter is written `array $synchronization=null`, which PHP treats as IMPLICITLY NULLABLE and therefore exempt from the 8.1 "required after optional" deprecation. php-cs-fixer's `nullable_type_declaration_for_default_null_value` rewrites that to `?array $synchronization = null` — now genuinely optional, and the required `FlowToken &$flowToken` behind it becomes a deprecation. The signature did not change meaning; it changed CATEGORY. Fixed by moving `$flowToken` ahead of the optional parameters rather than by undoing the rule, because the rule is the standard this PR adopts and `cs:fix` would rewrite it back. All four call sites pass every argument by NAME, and the test suite only ever mocks the method with `willReturn` — no `->with()` positional assertion anywhere — so the position is free to move. A scan of every signature in lib/ for a required parameter after an optional one now returns nothing; the same scan over the previous commit returns exactly this one, so it is a measurement. phpcs — 21 errors, all from the ruleset switch, all now zero. phpcs.xml moved to the shared semantics-only ruleset in this PR, so the tree is being read by a different set of sniffs than the one `development` passes under. It is a different question, not a regression, and the answer was 21: 1 missing docblock #1233 inserted `dispatchesThroughBroker()`'s docblock BETWEEN `resolveBrokeredDispatch()`'s docblock and its signature, orphaning the first and leaving the second undocumented. Moved the docblock back onto its own function; no code moved. 11 param alignment one BankfeedSyncService docblock indented its continuation lines to a column no @PARAM sits at. 9 line length over 150 characters.⚠️ THE OBVIOUS FIX FOR THE LONG LINES DOES NOT HOLD, and this is the part worth knowing before the next app in the migration hits it. Five of them are `@return <very wide array shape> <description>`, and php-cs-fixer's `phpdoc_align` re-indents the continuation under the type column. Manually re-wrapping them at a sane indent makes `cs:fix` put them straight back — the two tools genuinely disagree, and phpcs is the one that fails the build. Moved the prose OUT of the tag and into the docblock body instead, which leaves no continuation line for either tool to have an opinion about. Two more were over-long signatures, wrapped one parameter per line. Verified in the same container CI uses (php:8.3-cli, this repo's own vendor): php-cs-fixer Fixed 0 of 714 files (stable — cs:fix is a fixpoint) phpcs 0 ERRORS AND 277 WARNINGS (the job passes on warnings) phpstan [OK] No errors * fix(ci): test the whole declared Nextcloud range, not only the ceiling appinfo/info.xml declares <nextcloud min-version="32" max-version="34"/>, but nextcloud-test-refs was '["stable34"]' — so the declared floor and the middle major were advertised to the App Store with no job touching either. This is the coding-standard migration's own defect: its rollout REPLACED the ref list instead of extending it. The programme opened by reporting that nothing was tested on NC 34 and, in fixing that, made 32 and 33 the untested end. Same drift, other direction. stable34 stays first because newman, playwright and journeydoc-capture all read fromJSON(inputs.nextcloud-test-refs)[0] as their single server. Verified green on all three refs against nextcloud/ocp ^34 on portaliq (run 31599055849, six PHPUnit legs: 32/33/34 x PHP 8.3/8.4).
rubenvdlinde
added a commit
to ConductionNL/scholiq
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 386 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame 2fd6f31 touches 386 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. Top-level blocks are now background-jobs, repair-steps, settings, navigations; <php> precedes <nextcloud>; and inside <repair-steps>, <post-migration> precedes <install> (the schema's order is pre-migration, post-migration, live-migration, install, uninstall - it does not reflect execution order, which Nextcloud selects by event). Ordering alone was not sufficient here. The <dependencies><app> entry is not an ordering problem: the App Store schema has no <app> child under <dependencies> at any position, so it can never validate. It was also inert - OC\App\DependencyAnalyzer::analyze() handles only architecture, php, database, command, lib, os and the server version, and never looks at "app" - so it enforced nothing at install time. The dependency is now recorded as a comment in the same place. Both entries (openregister and openconnector) were converted; the openregister version floor stays machine-readable as the constraint in lib/Settings/scholiq_register.json. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * style(stylelint): clear the lint debt the widened glob newly exposes The config commit quoted the previously-unquoted stylelint glob. Unquoted, /bin/sh (dash) expanded 'src/**/*.vue' as 'src/*/*.vue' — one directory deep — so every component nested two levels under src/ was silently never linted. Quoting it hands the pattern to stylelint, whose own glob engine recurses. These violations are pre-existing debt in newly-covered files, not regressions: every offending file sits at src/<a>/<b>/<file>.vue and was matched zero times by the old expansion. Fixed with stylelint --fix (rule-empty-line-before) plus one hand-removed verbatim duplicate selector where --fix could not. No hardcoded colours introduced; the glob is left widened. * ci: re-run against the repaired shared quality.yml The previous run hit a startup failure: quality.yml@main carried a duplicate 'name:' key and a job with no steps, spliced in by .github#385. Repaired by .github#389. A startup-failed run cannot be re-run, so this empty commit requests a fresh evaluation. * fix: drop an accidentally committed node_modules symlink Local tooling symlink picked up by 'git add -A'. It escaped .gitignore because the rule is 'node_modules/' with a trailing slash, which matches a DIRECTORY — a symlink of the same name is a blob (mode 120000), not a directory, so the rule never applied. It pointed at an absolute path outside the repo. * fix(ci): test the whole declared Nextcloud range, not only the ceiling appinfo/info.xml declares <nextcloud min-version="32" max-version="34"/>, but nextcloud-test-refs was '["stable34"]' — so the declared floor and the middle major were advertised to the App Store with no job touching either. This is the coding-standard migration's own defect: its rollout REPLACED the ref list instead of extending it. The programme opened by reporting that nothing was tested on NC 34 and, in fixing that, made 32 and 33 the untested end. Same drift, other direction. stable34 stays first because newman, playwright and journeydoc-capture all read fromJSON(inputs.nextcloud-test-refs)[0] as their single server. Verified green on all three refs against nextcloud/ocp ^34 on portaliq (run 31599055849, six PHPUnit legs: 32/33/34 x PHP 8.3/8.4).
rubenvdlinde
added a commit
to ConductionNL/openbuild
that referenced
this pull request
Aug 12, 2026
* chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 236 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame e78eb70 touches 236 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. Top-level blocks are now background-jobs, repair-steps, commands, settings, navigations; <php> precedes <nextcloud>; and inside <repair-steps>, <post-migration> precedes <install> (the schema's order is pre-migration, post-migration, live-migration, install, uninstall - it does not reflect execution order, which Nextcloud selects by event). Ordering alone was not sufficient here. The <dependencies><app> entry is not an ordering problem: the App Store schema has no <app> child under <dependencies> at any position, so it can never validate. It was also inert - OC\App\DependencyAnalyzer::analyze() handles only architecture, php, database, command, lib, os and the server version, and never looks at "app" - so it enforced nothing at install time. The dependency is now recorded as a comment in the same place. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * fix(ci): test the whole declared Nextcloud range, not only the ceiling appinfo/info.xml declares <nextcloud min-version="32" max-version="34"/>, but nextcloud-test-refs was '["stable34"]' — so the declared floor and the middle major were advertised to the App Store with no job touching either. This is the coding-standard migration's own defect: its rollout REPLACED the ref list instead of extending it. The programme opened by reporting that nothing was tested on NC 34 and, in fixing that, made 32 and 33 the untested end. Same drift, other direction. stable34 stays first because newman, playwright and journeydoc-capture all read fromJSON(inputs.nextcloud-test-refs)[0] as their single server. Verified green on all three refs against nextcloud/ocp ^34 on portaliq (run 31599055849, six PHPUnit legs: 32/33/34 x PHP 8.3/8.4). * fix(deps): require symfony/http-foundation for the NC 34 DownloadResponse nextcloud/ocp v34's OCP\AppFramework\Http\DownloadResponse references Symfony\Component\HttpFoundation\HeaderUtils, which was not in the dependency tree. Three ExportsControllerTest download cases errored with 'Class "Symfony\Component\HttpFoundation\HeaderUtils" not found'. Add symfony/http-foundation ^6.4 to require-dev so the class resolves under static analysis and PHPUnit. * fix(stubs): type GenericAdminSettings::$initialState as the AppFramework service The stub declared OCP\IInitialState, but OpenRegister's real AppHost\Settings\GenericAdminSettings takes OCP\AppFramework\Services\IInitialState. Application::register() correctly passes the AppFramework service, so PHPStan reported a false type mismatch at AppInfo/Application.php:322 against the inaccurate stub. Align the stub with the class it stands in for. * style(vue): add the blank lines stylelint requires before adjacent rules The quoted stylelint glob widened coverage to .vue files that had never been linted, surfacing 69 pre-existing rule-empty-line-before violations across ten components. Whitespace only; no selector, declaration or template changes. Also quote the glob in the stylelint-fix script so --fix covers the same file set the stylelint check does.
rubenvdlinde
added a commit
to ConductionNL/openregister
that referenced
this pull request
Aug 12, 2026
) * chore: adopt nextcloud/coding-standard, .editorconfig and NC 34 Configuration only. The reformat is the next commit on purpose, so .git-blame-ignore-revs can name a revision containing nothing but whitespace. - .php-cs-fixer.dist.php + conduction/coding-standard, which extends nextcloud/coding-standard and can only ADD to it — enforced by that package's invariant test, not by review. - cs:check / cs:fix now run php-cs-fixer. They were aliases for phpcs/phpcbf, so the documented Nextcloud command reformatted code AWAY from Nextcloud's standard. - nextcloud/coding-standard dropped as a direct dependency. It arrives transitively at a version conduction/coding-standard has tested against; declared directly it was a dead dependency with no config and no invocation. - phpcs.xml is now a stub over the shared semantics-only ruleset, and the local phpcs-custom-sniffs/ copy is gone. The fleet was carrying six divergent versions of NamedParametersSniff.php — a custom RULE, not a setting. - .editorconfig, verbatim from nextcloud/server. No fleet app had one, so an editor configured by someone's previous Nextcloud work defaulted to tabs, which the old ruleset then rejected. - nextcloud/ocp -> ^34.0 and PHPUnit -> stable34. This app declared support for NC 34 while being analysed against 31, so a symbol REMOVED in 32/33/34 was invisible to the type checker. That is why the NC 34 removal of \OC::$server needed a hand-written PHPCS sniff. - the stylelint glob is quoted, so stylelint expands it rather than the shell. Unquoted, src/**/ matches exactly one directory level and nested components are silently unlinted. gate-65 (coding-standard-adoption) enforces all of the above from ConductionNL/.github@main. This app failed it; with this commit it passes. * style: reformat with nextcloud/coding-standard — whitespace only Applied by php-cs-fixer with conduction/coding-standard. Tabs, same-line braces, (int)$x, single-space concatenation, ordered imports — Nextcloud's dialect, which this app now passes unchanged. 2574 file(s), no behaviour change. Isolated from the configuration change so .git-blame-ignore-revs can name a revision that touches nothing but formatting. Reviewing it line by line is not a useful activity; the previous commit is the review. * chore: ignore the reformat commit in git blame a34f528 touches 2574 files and changes no behaviour. Without this, every line it reflowed attributes to it and the real author is one --skip away. GitHub honours the file automatically; locally it needs `git config blame.ignoreRevsFile .git-blame-ignore-revs` once. * fix: regenerate composer.lock for the new constraints The previous commit changed composer.json without touching the lock, so `composer install` refused with exit 4 and EVERY PHP job failed: Required (in require-dev) package "conduction/coding-standard" is not present in the lock file. Required (in require-dev) package "conduction/hydra-gates" is not present in the lock file. Required (in require-dev) package "nextcloud/ocp" is in the lock file as "v31.0.9" but that does not satisfy your constraint "^34.0". Nothing was wrong with the reformat or the ruleset — the jobs never got as far as running a tool. Measured on larpingapp#313 before this fix: phpcs, psalm, phpstan and both PHPUnit legs red, all of them at `composer install`. Hydra Gates passed in the same run, because it does not install composer dependencies. Now locked at conduction/coding-standard v1.0.0, conduction/hydra-gates v1.7.0, nextcloud/ocp v34.0.2 — the last of which is the point of the exercise: this app declares support for NC 34 and is now analysed against it. * fix(appinfo): order info.xml elements per the App Store xs:sequence The App Store's info.xsd declares <info> and its children as xs:sequence, so element ORDER is significant. This file was rejected by `xmllint --noout --schema info.xsd appinfo/info.xml`. Nextcloud's lint-info-xml workflow validates against exactly that schema, and ConductionNL/.github#383 adds the same check to the shared pipeline. Elements were moved into the schema's order. <version> and the <nextcloud> min/max-version declaration are unchanged. <documentation> moved ahead of <category>; top-level blocks are now background-jobs, repair-steps, commands, settings, activity, navigations, contactsmenu; and <activity>'s children are in settings, filters, providers order. One content fix was unavoidable. <notification><service> is not an ordering problem - the App Store schema has no <notification> element at any position, and Nextcloud's InfoParser never read one, so the declaration registered nothing. The notifier is registered in PHP, via registerNotifierService(AnnotationNotifier::class) in lib/AppInfo/Application.php, which is unaffected. Replaced by a comment pointing at that registration. Verified: `xmllint --noout --schema info.xsd appinfo/info.xml` reports "validates" (libxml2 2.12.10). The pre-change file failed the same command. * fix: make phpcs, psalm and phpstan pass under the new ruleset and NC 34 Three separate causes, all of them this branch's doing, none of them a defect in the code being reformatted. phpcs (26 errors -> 0) The stub ruleset enforces a 150-character line limit. php-cs-fixer's phpdoc_align aligns a wrapped `@return` continuation to the column after the type on the FIRST line, so a long array shape pushes its own description past 150 — the formatter mechanically creates the violation the linter then reports. Measured: `git show origin/development:<file>` has ZERO over-long lines in every file flagged here. The fix is to stop hanging prose off a long `@return` and put it in the description, where it reads better anyway. AggregationRunner keeps its wrapped union and gains an `AggValues` alias instead. Joining that union onto one line makes PHPStan resolve it properly for the first time, which surfaces unrelated pre-existing type debt two thousand lines away — not this commit's business. SettingsService::convertToBytes() loses its switch fall-through. php-cs-fixer's no_break_comment requires the marker to read exactly `no break`; PHPCS's Squiz.Commenting.InlineComment.NotCapital requires a capital. No spelling satisfies both, so the fall-through goes and each case states its own multiplier. Same arithmetic. psalm (5 errors -> 0), baseline regenerated Two of the three drifted entries drifted for a reason worth naming: psalm baselines match on a CODE SNIPPET, and the reformat moved the opening brace onto the declaration line, so `public function __construct(Entity $entity, string $systemSlug)` stopped matching `... $systemSlug) {`. Any app in this fleet with a snippet-matched psalm baseline will drift the same way on reformat. The third, allowEvalScript, is an NC 34 removal. phpstan (21 errors -> 0), baselined in phpstan-baseline-nc34-ocp.neon All 21 come from analysing against ocp 34 instead of 31. Pre-existing code; the analyser just got the API the app claims to support. Four are real NC 34 removals that will fatal at runtime. Baselined rather than fixed because porting to NC 34 is not a reformat, and because several of the rest are constant-false comparisons where the always-false predicate may be the only thing suppressing a wrong code path. Every entry is diagnosed in openregister#2450. phpmd was already clean on the merged tree; no change needed. * fix(ci): test the whole declared Nextcloud range, not only the ceiling appinfo/info.xml declares <nextcloud min-version="32" max-version="34"/>, but nextcloud-test-refs was '["stable34"]' — so the declared floor and the middle major were advertised to the App Store with no job touching either. This is the coding-standard migration's own defect: its rollout REPLACED the ref list instead of extending it. The programme opened by reporting that nothing was tested on NC 34 and, in fixing that, made 32 and 33 the untested end. Same drift, other direction. stable34 stays first because newman, playwright and journeydoc-capture all read fromJSON(inputs.nextcloud-test-refs)[0] as their single server. Verified green on all three refs against nextcloud/ocp ^34 on portaliq (run 31599055849, six PHPUnit legs: 32/33/34 x PHP 8.3/8.4). * fix(phpmd): import RegistryStepDispatcher instead of instantiating it FQN phpmd's MissingImport fired on the `new` in the FlowStepDispatcher factory. The rule only looks at instantiation, so the two `::class` references beside it are untouched and stay fully qualified. Pre-existing rather than new: the same violation is red on development (run 31604485669, job 94139819972, Application.php:571) — it arrived with the fan-out commit abb9556 and this branch merely inherited it in the merge. Fixed here rather than left behind because it lands in a file this merge already touches, and this repo fixes quality issues it encounters. Verified: phpmd exits 0 on lib/AppInfo with the repo's own ruleset and baseline, and a control that restores the FQN reproduces the CI finding (MissingImport, exit 2). php-cs-fixer reports 0 of 61 files needing change, so the added import sits where the coding standard wants it. --------- Co-authored-by: Ruben van der Linde <juan.claude@conduction.nl>
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adopts the first of the five checks Nextcloud runs and we did not.
quality.ymlnever referencedappinfo/info.xmlat all, so a malformed manifest was discovered at App Store upload time — after the release was built, tagged and published.It matters more now: the release path reads
info.xmlfor the version the tag must match and the Nextcloud version whoseoccsigns the package. A file that doesn't validate can still parse well enough for a grep to return something plausible — which is how an unanchored pattern resolved8from<php min-version="8.3"/>in 13 apps earlier today.Measured before merging — 5 pass, 13 fail
<background-jobs>out of sequence<php>out of sequence<app>out of sequence<types>out of sequence<repair-steps>out of sequence<category>out of sequence<documentation>out of sequence<summary>is 136 chars; the schema caps itTwelve are element order — the schema is an
xs:sequence. The thirteenth is a real content violation. All pre-existing, all would fail Nextcloud's ownlint-info-xml, all a reorder away from passing.Design notes
<version>and<nextcloud min-version>exist. Their absence otherwise surfaces at release time.Correction to the table above (2026-08-12)
"Twelve are element order" was wrong. Only seven were. The other six carried elements that do not exist in the App Store XSD at any position and could never be reordered into validity:
<dependencies><app>DependencyAnalyzer::analyze()handles only architecture, php, database, command, lib, os and server version. It never readsapp.<groups>OC_Appsets$info['groups']unconditionally from theenabledappconfig, overwriting whatever info.xml parsed.<notification>InfoParserhas no handling for it; the notifier is registered in PHP viaregisterNotifierService().<types><search/>registerSearchProvider().The measurement was at fault, not the schema.
xmllintstops reporting once an earlier error appears, so the "first error" column I built the table from masked everything behind it. A one-line-per-app summary of a validator that short-circuits is not an inventory of that app's problems — it is an inventory of each app's first problem.Also hidden that way:
<install>had to move after<post-migration>in six apps — the single most common violation in the fleet, absent from the original table entirely.One real behaviour change came out of it. launchpad's
<activity><provider>was an invalid direct child, and NC reads providers fromactivity.providers.provider— soOCA\LaunchPad\Activity\Extensionhad never been registered. Wrapping it in<providers>satisfies the schema and makes that feature work for the first time. Every other removal was verified inert against the Nextcloud server source before being touched.All 13 now validate, verified by re-downloading each file from its remote branch and re-running
xmllint. The fixes are commits on the existingchore/nextcloud-coding-standardPRs.