Release: merge development into beta - #45
Conversation
Quality Report
Summary
PHP Quality
Vue Quality
Security
License Compliance
composer dependencies (100 total)
npm dependencies (7 total)
PHPUnit Tests
Code coverage: 0% (0 / 24 statements) Integration Tests (Newman)Newman integration tests were not enabled for this run. Generated automatically by the Quality workflow.
|
Quality Report
Summary
PHP Quality
Vue Quality
Security
License Compliance
composer dependencies (100 total)
npm dependencies (7 total)
PHPUnit Tests
Code coverage: 0% (0 / 24 statements) Integration Tests (Newman)Newman integration tests were not enabled for this run. Generated automatically by the Quality workflow.
|
Quality Report
Summary
PHP Quality
Vue Quality
Security
License Compliance
composer dependencies (100 total)
npm dependencies (7 total)
PHPUnit Tests
Code coverage: 0% (0 / 24 statements) Integration Tests (Newman)Newman integration tests were not enabled for this run. Generated automatically by the Quality workflow.
|
Quality Report
Summary
PHP Quality
Vue Quality
Security
License Compliance
composer dependencies (100 total)
npm dependencies (7 total)
PHPUnit Tests
Code coverage: 0% (0 / 24 statements) Integration Tests (Newman)Newman integration tests were not enabled for this run. E2E Tests (Playwright)Playwright E2E tests were not enabled for this run. Generated automatically by the Quality workflow.
|
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-01 11:51 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-07 20:51 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-07 21:25 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-12 22:09 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-12 22:29 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-13 09:26 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-17 07:45 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-18 18:09 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-18 18:54 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-18 19:16 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-18 20:47 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-18 20:59 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-18 21:17 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-19 02:56 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-19 03:08 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ⏭️ | ||||
| phpcs | ⏭️ | ||||
| phpmd | ⏭️ | ||||
| psalm | ⏭️ | ||||
| phpstan | ⏭️ | ||||
| phpmetrics | ⏭️ | ||||
| eslint | ⏭️ | ||||
| stylelint | ⏭️ | ||||
| composer | ⏭️ | ⏭️ | |||
| npm | ⏭️ | ⏭️ | |||
| PHPUnit | ❌ | ||||
| Newman | ❌ | ||||
| Playwright | ❌ |
Quality workflow — 2026-05-19 05:05 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-19 05:07 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ❌ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-19 05:21 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-19 05:24 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-19 07:42 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-19 08:13 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-19 08:23 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/24 statements)
Quality workflow — 2026-05-19 08:35 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ❌ | ✅ 100/100 | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-21 20:32 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ❌ | ||||
| phpcs | ❌ | ||||
| phpmd | ❌ | ||||
| psalm | ❌ | ||||
| phpstan | ❌ | ||||
| phpmetrics | ❌ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ❌ | ❌ | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-22 07:13 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ❌ | ||||
| phpcs | ❌ | ||||
| phpmd | ❌ | ||||
| psalm | ❌ | ||||
| phpstan | ❌ | ||||
| phpmetrics | ❌ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ❌ | ❌ | |||
| npm | ✅ | ✅ 7/7 | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-05-23 07:26 UTC
Download the full PDF report from the workflow artifacts.
…the document (#195) CustomCssValidator flagged a document as having an external url() by asking two DOCUMENT-GLOBAL questions — "is there a data: URI anywhere?" and "is there an http(s)/protocol-relative reference anywhere?" — rather than asking them of the occurrence it had just matched. One legitimate data: URI therefore satisfied the first question, and unless a second, http(s)-specific match also existed, no error was recorded: url(ftp://…), url(chrome-extension://…), url(file:///…) and every other custom scheme were accepted for the rest of the stylesheet. Replaced with a per-occurrence scan (firstDisallowedUrlScheme()): preg_match_all over every url( target's scheme, and only `data:` is permitted to carry one. Relative and root-relative references carry no scheme, so they never match and stay usable — the fix does not tighten what legitimate theming can express. The rule the spec already stated ("any other absolute-scheme or protocol- relative URL ... MUST be rejected") now actually holds. Verified in a container (PHP 8.3/8.5): the two new bypass tests FAIL on the pre-fix code and pass after; a 20-case truth-table probe run against both revisions shows 5 BLOCK cases flipping from ALLOW to BLOCK while every ALLOW case (single/multiple data: URIs, data: + relative paths, data: woff2 @font-face) is byte-identical across both. 451 unit tests green, psalm and phpstan clean; the four phpmd findings the discarded $m carried on CustomCssValidator::validate() are gone. Fixes #193 Co-authored-by: Ruben van der Linde <release-bot@conduction.nl>
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ❌ | ||||
| stylelint | ❌ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ❌ | ❌ | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-08-02 20:58 UTC
Download the full PDF report from the workflow artifacts.
test:unit and test:all ended in '|| echo Tests require Nextcloud environment, skipping...', discarding phpunit's exit status unconditionally. Every other tool in check:strict passes here, so the whole command was green with the test gate switched off. The excuse in that message is actually TRUE for this repo - with a freshly installed vendor/ the suite still dies on 'Class OC\Mail\EMailTemplate not found' - but the mask was not conditional on it, so a genuine failure inside CI looked identical to 'no Nextcloud here'. Guarded on the real precondition instead, plus --no-coverage. Positive control (PHP 8.3.32 container, app mounted at /nc/apps-extra/nldesign): no server tree -> exit 0, loud SKIPPED, test:all not named server tree present -> exit 1, check:strict NAMES test:all (code 255) old composer.json -> same phpunit failure, test:all never named Tooling only.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ❌ | ||||
| stylelint | ❌ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ❌ | ❌ | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-08-02 23:12 UTC
Download the full PDF report from the workflow artifacts.
…paced code (#197) Every Conduction repo enables rulesets/design.xml/DevelopmentCodeFragment, and it has never reported anything in any of them. The cause is a config gap, not a phpmd bug: PDepend resolves an unqualified call inside a namespaced file to the current-namespace-qualified image, so `var_dump($x)` written inside `namespace OCA\MyApp\Service;` reaches the rule as `OCA\MyApp\Service\var_dump` and never matches the `unwanted-functions` list. All of our production PHP is namespaced, so with the default the rule is dead. The rule's own `ignore-namespaces` property is the switch. This mirrors the configuration already merged in openregister (ConductionNL/openregister#2286). Proof, phpmd 2.15.0 / PHP 8.3.32, against this repo's own phpmd.xml: namespaced probe class calling var_dump() -> exit 2, DevelopmentCodeFragment same class with the call removed -> exit 0, no finding Before the change the identical namespaced probe exited 0. Blast radius on this repo: measured 0 new findings over the scanned path on the base branch, with a per-run positive control (dropping the namespaced probe into the same extracted tree does produce exit 2, so the zero is a true zero). Nothing is baselined or suppressed here.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ❌ | ||||
| stylelint | ❌ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ❌ | ❌ | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-08-03 08:58 UTC
Download the full PDF report from the workflow artifacts.
…-> 2026-08-01) (#198) The lockfile pinned roave/security-advisories to a commit from 2026-03-11, so the metapackage's conflict rules — and therefore the protection against installing known-vulnerable dependency versions — were frozen at that date. Refreshed to the 2026-08-01 tip. composer audit --locked: clean before and after.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ❌ | ||||
| stylelint | ❌ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ❌ | ❌ | |||
| PHPUnit | ⏭️ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-08-03 10:39 UTC
Download the full PDF report from the workflow artifacts.
…npm ci (#200) * chore(deps): pin @conduction/nextcloud-vue 2.1.0-vue3.17 and unblock npm ci nldesign has no Vue frontend — @conduction/nextcloud-vue is a build-only devDependency that scripts/build-icons.js reads three data-URI icon catalogues from (src/icons/{rvo,openGemeenten,denHaag}.js). Those three modules are BYTE-IDENTICAL between 1.0.0-beta.218 and 2.1.0-vue3.17, and re-running `npm run build:icons` reproduces all 1488 committed icons with a clean `git status`, so the bump cannot change any shipped asset. It aligns nldesign with the rest of the fleet and takes it off the Vue 2 beta line. Two pre-existing faults had to be fixed to get there, because `npm ci` could not run at all: 1. `@gouvfr/dsfr` was declared TWICE in devDependencies (a duplicate JSON key — valid JSON, last-one-wins, but malformed). 2. `@gouvfr/dsfr`'s published dependency tree is broken upstream: @gouvfr/dsfr@1.15.1 -> @gouvfr/dsfr-nexus -> @gouvfr/dsfr-roller -> @gouvfr/dsfr-publisher, which is NOT on the registry (E404), as is @gouvfr/dsfr-token. Reproduced standalone: `npm install @gouvfr/dsfr@1.15.1` fails on a bare package.json. Declaring it as a devDependency therefore made `npm ci` impossible, and every npm-dependent Code Quality job died at install: Vue Quality (eslint), Vue Quality (stylelint), Security (npm), License (npm), Frontend Tests (unit) and SBOM have ALL been failing on `development` for this one reason (run 30804159878, push, 896af77). Moving it to `optionalDependencies` keeps the declaration and its provenance while letting npm skip the unresolvable subtree. Verified with a COLD npm cache: `npm ci` exits 0 and installs 678 packages. scripts/build-icons.js already falls back to .dsfr-src/ and prints "0 is expected/harmless when @gouvfr/dsfr is not installed", so nothing regresses; the dsfr pack under img/icons/dsfr/ is committed output and is untouched. tests/Unit/IconAssetsTest.php asserted the dependency must live in devDependencies. That assertion is not weakened — it now asserts the package is still declared (in optionalDependencies) AND that it is not back in devDependencies, with the upstream reason recorded inline. 3. stylelint: a duplicate selector in css/systems/nldesign/theme.css (`[data-v-48234338].login-box__wrapper` repeats `.login-box__wrapper[data-v-48234338]` one line up). Pre-existing; it was invisible only because the job never got past `npm ci`. Local verification (npm 11 generate -> npm 10 normalise -> npm 10 ci): lockfile @conduction/nextcloud-vue = 2.1.0-vue3.17 (exact, no caret) lockfile vue3-apexcharts = 1.8.0 (below the proprietary 1.9.0 line) npm run test:unit -> 7 files, 76 tests, all pass npm run stylelint -> exit 0 npm run check:manifest -> Ajv PASS (0 errors) npm run build:icons -> rvo 1163 / open-gemeenten 256 / den-haag 69, no diff * fix(tests): repair the two PHPUnit failures that unblocking npm ci exposed Making `npm ci` work re-enabled the PHPUnit legs, which had been SKIPPED on every one of the last 25 code-quality runs because they are gated behind the frontend jobs that were dying at install. nldesign's 556-test suite therefore ran for the first time in the recorded history of this workflow, and surfaced two things. 1. MarianneFontTest::testDsfrIsABuildOnlyDevDependency — MY REGRESSION. A SECOND test file also pins @gouvfr/dsfr's location in package.json. I only found tests/Unit/IconAssetsTest.php because I scoped the search to that file instead of the tests/ tree. Updated to match: it now asserts the package is declared under optionalDependencies and is NOT under devDependencies or runtime dependencies. The property this test exists to protect — that dsfr is build-only and nothing in lib/ or js/ references it — is unchanged and still asserted. 2. ConfigBundleServiceTest — 11 errors, PRE-EXISTING, one cause. Trying to configure method "getEnabledApps" which cannot be configured because it does not exist, has not been specified, is final, or is static tests/Unit/Service/ConfigBundleServiceTest.php:117 `getEnabledApps` is not on OCP\App\IAppManager in the supported Nextcloud versions, so createMock() refuses to configure it and setUp() errors for every test in the class. Not caused by this branch: `git diff origin/development -- lib/ tests/Unit/Service/` was empty before this commit, and the failure has no npm involvement at all. ConfigBundleService calls exactly ONE IAppManager method — getAppVersion(). The stub was configuring a method the service never uses and the interface no longer declares, so it is removed rather than replaced. A double must mirror the real signature, never invent one.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 2/2 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/11 statements)
Quality workflow — 2026-08-03 11:58 UTC
Download the full PDF report from the workflow artifacts.
The nightly token-sync job had no timeout-minutes, so a hung clone or a stalled composer install would burn the 6h GitHub default before the run was reclaimed. Observed over 11 runs in 2026: max 1.9 min, median 0.3 min. Bounded at 15 minutes - deliberately loose, so normal runner contention can never turn a slow run into a phantom failure. Every other workflow in this repo delegates to a reusable workflow in ConductionNL/.github, whose jobs already carry their own timeout-minutes; a caller job that uses 'uses:' cannot declare timeout-minutes at all. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 2/2 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/11 statements)
Quality workflow — 2026-08-03 13:01 UTC
Download the full PDF report from the workflow artifacts.
docs/features.json was last regenerated on 2026-06-18 (e4f4f95), one week before openspec/features.overlay.json was added on 2026-06-25 (2a699c8). The commercial overlay is the authoritative source for the generator, so every run since has produced a different file than the one committed and 'quality / Features Check' has failed on every pull request. It never self-healed because the push-side 'Features Extract' job cannot land its auto-commit on development: ! [remote rejected] development -> development (push declined due to repository rule violations) That push failure is swallowed by a '|| echo ::warning' so the job still reports success (ConductionNL/.github#61). Regenerated verbatim with scripts/extract-features.py from ConductionNL/.github@main. Output verified deterministic (byte-identical on a second run) and --check now exits 0. Co-authored-by: Ruben van der Linde <juan.claude@conduction.nl>
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 2/2 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Coverage: 0% (0/11 statements)
Quality workflow — 2026-08-03 14:17 UTC
Download the full PDF report from the workflow artifacts.
Pin the build-only devDependency @conduction/nextcloud-vue from 2.1.0-vue3.17 to 3.0.0-vue3.4 (exact pin, no range). nldesign has zero .vue files and ships no runtime JS dependency on the package: it is consumed only by scripts/build-icons.js, which decodes the rvo / openGemeenten / denHaag data-URI icon packs into img/icons/. Verified no-op for committed build output: rebuilding img/icons/ against 3.0.0-vue3.4 reproduces all 2526 SVGs byte-identically, and the rvo (1163), open-gemeenten (256) and den-haag (69) pack counts are unchanged. Lockfile carries only the pin plus incidental floating transitive bumps (dompurify 3.4.12 -> 3.4.13, ws 8.21.1 -> 8.21.2). vue3-apexcharts stays at 1.8.0, below the 1.9.0 proprietary-licence boundary. Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ❌ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 2/2 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-08-03 22:18 UTC
Download the full PDF report from the workflow artifacts.
… route (#208) `HealthController extends OCA\OpenRegister\AppHost\Controller\ GenericHealthController`. Nextcloud's router `ReflectionClass()`es every file in `lib/Controller/` while MATCHING a route, so with openregister absent that unresolvable parent makes EVERY nldesign route return HTTP 500 — not just `/api/health`. nldesign does not declare `<app>openregister</app>`, so this is reachable on any instance without OpenRegister. `extends` is resolved by the autoloader, not the DI container, so lazy registration cannot rescue it. Fix by composition (mirrors decidesk#388): `extends OCP\AppFramework\ Controller`, resolve ManifestLoader + HealthCheckExecutor out of the container by FQCN string at dispatch time. The `#[PublicPage]` + `#[NoCSRFRequired]` posture previously inherited from the generic is now declared explicitly, and the `{status, app, version, checks}` envelope, the engine status-code policy and the manifest-gated CORS headers are reproduced exactly. With openregister absent it degrades to `status: degraded` at HTTP 200 instead of fatalling. Co-authored-by: Ruben van der Linde <release-bot@conduction.nl>
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ❌ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 2/2 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ⏭️ |
Quality workflow — 2026-08-04 06:21 UTC
Download the full PDF report from the workflow artifacts.
* ci(e2e): enable the shared Playwright job for nldesign nldesign is the one app in the fleet whose entire product surface is runtime CSS. It ships zero .vue files, so nothing here is reachable from a unit test — a design token, a token set, dark mode, high contrast and the NL Design System variable mapping onto Nextcloud's theming only exist once a browser has resolved the cascade against a live server. tests/e2e/spec-coverage/ already holds 31 specs that assert exactly that, and they have never run in CI: enable-playwright was unset, so the shared workflow reported the E2E job as 'skipped' — an absence that reads identically to a pass. workers stays at 1. These specs mutate global admin theming state, so they are deliberately not parallelised. * fix(build): stop npm run build failing on every clean checkout build:icons exited 1 on any checkout where @gouvfr/dsfr is absent — which is EVERY clean checkout, including every CI runner. Frontend Build has been red on development as a result. The pack's own docblock already records that @gouvfr/dsfr 'currently cannot be npm-installed (broken optional dependencies upstream)', which is why it sits in optionalDependencies, and the documented fallback .dsfr-src/icons/ is gitignored. So neither of the two candidate source directories can exist on a fresh clone, and the script had no viable path at all — it only worked on a developer box that had manually pre-fetched the source. Worse, resetDir() wipes img/icons/ before the packs are rebuilt, so the failing run first DESTROYED all 1038 committed dsfr icons and then exited 1. Snapshot the committed artefacts before the wipe and reuse them when the upstream source is unavailable, mirroring how the sibling scripts/build-fonts-marianne.js already handles the same optional dependency. This is deliberately not a skip: the pack stays fully materialized, so ICONS.md keeps its inventory and its Etalab-2.0 attribution row. Skipping would silently drop 1038 icons and a licence attribution out of a committed file. Glob-pack icons are now also sorted by id. listSvgFilesRecursive returns upstream category-directory order, which leaked into the committed ICONS.md sample; the materialized pack is flat, so that order is not reconstructible from the committed artefacts and the fallback path can only produce sorted order. Sorting both paths keeps ICONS.md identical whether or not the optional source is installed, instead of flip-flopping the committed file. Verified against a local reproduction (node_modules present, dsfr absent, .dsfr-src absent — identical to CI): before, exit 1 with img/icons/dsfr emptied to 0 files; after, exit 0, all four packs byte-identical to the committed tree, ICONS.md stable across repeated runs. * docs(icons): regenerate ICONS.md with the now-deterministic dsfr sample order Ordering-only. No icon added or removed: the dsfr count stays 1038 and every enumerated bullet still resolves to a file under img/icons/dsfr/, so tests/Unit/IconAssetsTest.php's count and existence assertions are unaffected. The 20-name sample now starts at account-* rather than arrow-* because the inventory is sorted by id instead of following the upstream category-directory walk. * ci(e2e): install OpenRegister for the nldesign E2E job The first E2E run showed 'Front-controller check: /apps/nldesign/ -> HTTP 500'. The Nextcloud log gives the cause: Class 'OCA\OpenRegister\AppHost\Controller\GenericHealthController' not found, from lib/Controller/HealthController.php. HealthController EXTENDS that class. Its docblock claims 'OpenRegister is a soft dependency; the parent class autoloads only on route dispatch, not at bootstrap' — this run disproves it. Nextcloud's router reflects over every registered controller while MATCHING a route, so the missing parent 500s every nldesign route, not merely /api/health. The visible symptom was global-setup timing out on input[name="user"], i.e. an error naming the login form while the actual fault was an unrelated controller's parent class. Installing OpenRegister lets the suite run. It does not fix the coupling — nldesign is broken standalone today, and an 'extends' cannot be deferred by DI because the autoloader resolves it, not the container. * ci(quality): three checks named after analysers were reporting their absence as success nldesign's caller passed enable-psalm/phpstan/phpcs: false. The shared workflow builds one matrix leg per tool regardless, and a disabled leg prints "<tool> is disabled — skipping." and `exit 0`. The job completes successfully, so GitHub publishes `quality / PHP Quality (psalm)` with a green tick for a run in which psalm never ran. On the previous run of this PR that leg finished in ~13s with no psalm output. A gate's absence and a gate's success were the same pixel. Turning the three on rather than dressing up the skip, because all three already pass here. phpcs.xml, phpstan.neon (level 5) and psalm.xml are present and complete; only the caller had them switched off. Measured on 9a0fbac under PHP 8.4: phpcs exit 0 0 errors, 5 warnings phpstan exit 0 [OK] No errors psalm exit 0 No errors found The 5 phpcs warnings were real and are fixed here, not silenced: the federated-config type and its listener carried @SPEC on the FILE docblock but not on the class docblock or on getId()/getDisplayName()/getTopic(). phpcs is now 0 errors / 0 warnings. Every one of those zeros was positive-controlled first, because a tool that cannot START looks exactly like a tool that found nothing — the first local phpcs attempt exited 255 inside vendor/composer/platform_check.php (host PHP 8.2 vs the required 8.3) and printed no findings at all. Injecting one deliberately broken class into lib/Service/ (wrong return type, undefined class, undefined method, no licence header) turned all three red: phpcs exit 2 with 10 errors, phpstan exit 1 with 3 errors, psalm exit 2 with UndefinedClass. The control file was removed before this commit. No baseline was added or extended, and no suppression annotation was used. * fix: the first real execution of the E2E suite found a 500 in production code The suite ran for the first time (run 30889958278, job 91929658882): 73 passed / 19 failed / 13 did not run in 9.5 min. None of the 19 is caused by this PR — these 31 specs were written and then never executed, so every one of these was already true on development. ## The production bug `AppThemingService::getThemableApps()` called `IAppManager::getEnabledApps()`. That method does not exist on `OC\App\AppManager` before Nextcloud 34, and appinfo/info.xml claims support for 28-34. On stable31 it throws Call to undefined method OC\App\AppManager::getEnabledApps() so `GET /settings/app-theming` returns a 500 HTML page and the per-app theming admin panel is DEAD on every supported server older than 34. The dev container runs 34, which is the only reason nobody had seen it. The browser symptom was a console error naming JSON: "Error loading app theming: SyntaxError: Unexpected token '<'". Fixed by calling `getInstalledApps()`, which despite its name returns the enabled ids and exists across the whole 28-34 range. The unit test made this unfindable. `AppThemingServiceTest` declared a test-only `interface IAppManagerWithEnabledApps extends IAppManager` that RE-DECLARED `getEnabledApps()`, with the comment "the OCP 31 IAppManager stub no longer types getEnabledApps(), but the real OC\App\AppManager still implements it". The stub was right and the production call was wrong. The mock manufactured the method under test, so the suite passed on precisely the versions where the panel 500'd. It now mocks the real OCP interface, which makes that class of mistake impossible to repeat. ## Test-infrastructure defects, each a wrong answer rather than a weaker one - `/custom_apps/nldesign/...` was hardcoded in icon-assets-ncvue.spec.ts and workflows/_helpers.ts. That prefix only exists on the docker dev image; CI checks the app out into `apps/nldesign`, so the URL matched nothing, fell through to index.php, matched no route and returned an HTML 404 — which `expect(status).toBe(200)` reported as "the asset is not served". Six assertions failed that way. Both now resolve the base through `OC.filePath()`, the platform's own resolver, correct in both layouts. Note one assertion in that file (`Airplane.svg` must 404) was PASSING for the wrong reason: everything 404s under a prefix that does not exist. - The `visual` project ran in CI despite its own docs calling it "opt-in / non-gating" and warning that its PNG baselines are host-specific. It was declared unconditionally, and `npx playwright test` — what the shared job runs — runs every declared project; `testIgnore` on the chromium project does nothing about that. It failed on a 1751x800 baseline vs a 1280x800 capture. Now gated behind PW_VISUAL=1, so `PW_VISUAL=1 npx playwright test --project visual` behaves exactly as before and the default invocation no longer silently includes it. - The delete-confirm selector `button.button-vue--primary` is @nextcloud/vue 9 markup; NC 31 ships v8, which emits `button-vue--vue-primary` for the same button. The class matched nothing and two tests timed out on a button that was on screen throughout. Now queried by role + accessible name ("Yes"), which the dialog's own accessibility contract guarantees on both. - The OCS capability allowlist listed seven keys; `iconPacks` is the eighth and is REQUIRED to be public by openspec/specs/icon-packs/spec.md ("capabilities.nldesign.iconPacks MUST equal [\"dsfr\"]"), with lib/Capabilities.php documenting an "eight-key payload". Correcting a stale fixture against the canonical spec — the assertion is still an exact set comparison, so a ninth key still fails. ## CI precondition A fresh Nextcloud leaves `token_set` unset, which resolves to the `nextcloud` set whose design_system is `none`, and `none` emits NO design-system layer and NO token layer at all. Three specs assert that cascade exists. `playwright-seed-command` now selects `rijkshuisstijl`, which resolves to the `nldesign` design system and is one of the 41 sets shipping a generated dark variant, which the dark-mode specs need. Nothing here skips a test, weakens an assertion, widens an allow-list, raises a timeout or adds a suppression. * style: reflow the getInstalledApps comment — phpcs rejects indented // lines The newly-enabled phpcs gate caught this on run 30891964264 job 91935893297: 2 errors, 'Expected 1 space before comment text but found 3; use block comment if you need indentation'. Left as evidence that the gate is doing something — it failed on its author's own commit within minutes of being switched on. * test(e2e): the last two failure clusters both named DOM that does not exist here Run 30892246034 job 91937146565: 89 passed / 5 failed / 10 did not run in 8.3 min (from 73/19/13 before the previous commit). Both remaining clusters were locators for things the CI Nextcloud never renders. per-app-theming (4 tests) targeted `activity`. Activity is an appstore app: it is bundled in the docker image but is NOT in nextcloud/server's `apps/`, which is what CI checks out. The panel itself was fine — after the getInstalledApps fix it renders, which is why the token-editor console -error assertion went green — there was simply no `input[data-app-id="activity"]` row, so all four blew a 30s timeout on an app that was never installed. Now `dashboard`: shipped by nextcloud/server, enabled by default, not in PROTECTED_IDS, and with a real page. Not `files`, because `/apps/files/` is already the control that must stay themed in the same test. lasuite-parity's `header app name` row asserted on `#header .header-appname` with the note "always present in stock chrome". It is not: `.header-appname` exists only in Nextcloud's PUBLIC layout (core/templates/layout.public.php). The authenticated layout this spec runs against has no such element on 31 or 34 — it renders `.header-start` + `#header-start__appmenu` — so the row could never pass at THEMING_URL on anything in the supported 28-34 range, and it blew a 15s waitForSelector every run. That row is deleted, not skipped. A `test.skip` would leave a grey row implying the check is temporarily unavailable, when the element does not exist in this render context at all. nldesign's own `#header .header-appname` rules are still live on public pages, so the CSS is not dead — it is the authenticated parity table that had no business naming it. Public-layout parity needs its own spec against a public render. * test(e2e): the sidebar parity row pinned the NC 34 id only Run 30893391595 job 91940672666: 94 passed / 1 failed / 7 did not run in 5.6 min. The one failure was `#app-navigation-vue` never becoming visible. The settings page renders that sidebar under two different ids depending on the server: Nextcloud 31 ships apps/settings/templates/settings/frame.php as a server-rendered `<div id="app-navigation">`, while 34 replaced it with a Vue app whose NcAppNavigation emits `#app-navigation-vue`. The reference row named only the 34 id, so it could not resolve on the version CI runs and blew a 15s waitForSelector. The row now uses `#app-navigation, #app-navigation-vue` — which is exactly what css/systems/lasuite/element-overrides.css itself writes: #app-navigation, .app-navigation, #app-navigation-vue { … } one declaration block, so whichever id the running Nextcloud renders carries the identical treatment. Matching the selector under test is the point; the asserted values (white surface, border-radius 0) are unchanged. The 7 "did not run" are the remainder of the lasuite-parity describe, which is `mode: 'serial'` — one failure stops the rest of that block, so the count is a consequence of the failure above rather than an independent signal. * test(e2e): the unified-search test read OC.requestToken on about:blank Run 30894215440 job 91943336466: 101 passed / 1 failed / 0 did not run in 5.9 min. The one failure never reached an assertion. `requestToken(page)` evaluates `window.OC.requestToken` in the page, and it was called BEFORE `page.goto(THEMING_URL)` — on a fresh `page` fixture that is still on about:blank, where `OC` is undefined: TypeError: Cannot read properties of undefined (reading 'requestToken') Every other test in this describe navigates first. This one had never surfaced because the describe is `mode: 'serial'`, so an earlier failure always stopped the block before this test ran — which is also why the "did not run" count shrank to zero as the earlier failures were fixed, and this one finally executed for the first time. Navigation now happens first, then the token read, then the token-set change, then a reload so the new cascade is actually applied before the modal is opened. The two `test.skip` calls further down are untouched: both are runtime-conditional (no unified-search trigger in the header / no `.modal-container` appearing), not blanket skips.
Codeberg is retired; ConductionNL is GitHub-only. GitHub Actions never executes .forgejo/**, so these workflows contributed zero status checks. Deleted 3 of 5: pre-merge-check-strict.yaml (covered by .github/workflows/code-quality.yml) and app-tests-live.yml + tests-live.yml. KEPT app-tests.yml + tests.yml -- tests.yml carries the only definition of the l10n extraction gate and the coverage ratchets (no .github/workflows/ l10n.yml here, enable-coverage-guard unset). Also repointed the .forgejo reference in tests/e2e/visual/README.md.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 2/2 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ❌ |
Quality workflow — 2026-08-04 09:27 UTC
Download the full PDF report from the workflow artifacts.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 2/2 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ |
Quality workflow — 2026-08-04 09:40 UTC
Download the full PDF report from the workflow artifacts.
* ci: harden fleet workflows — permissions and concurrency branch-protection: adopt the openregister template (adds an explicit empty permissions block, drops the unused secrets: inherit). code-quality: add a concurrency group (cancels superseded runs) and a least-privilege permissions block (CodeQL actions/missing-workflow-permissions). * ci(quality): add explicit permission ceiling and concurrency group The caller's permissions block is a static ceiling for every job in the called quality.yml — including disabled ones — so it must cover the widest declared grant (journeydoc/update-baseline/features-extract need contents/actions write; the Quality Report comment needs issues/pull-requests write). Also satisfies CodeQL actions/missing-workflow-permissions and cancels superseded runs. * build: regenerate docs/features.json at commit time via committed git hook Fleet convention (ConductionNL/.github CONVENTIONS.md § features.json): CI only verifies and blocks — generation happens on the developer's machine, before the checks run. - .githooks/pre-commit: regenerates docs/features.json whenever staged changes touch openspec/specs/ or the features overlay, and stages the result. Best-effort: it warns but never blocks the commit; the CI gate (features-check / features-extract -> Quality Report) enforces. - package.json "prepare" + composer.json "post-install-cmd" set core.hooksPath to .githooks, so any npm install or composer install activates the hook automatically. Existing clones activate once with `git config core.hooksPath .githooks`. Works from any client that runs real git (CLI, IDEs, Claude, GitKraken 9.5+); a bypassed or broken hook is caught by CI, which hard-fails the merge on a stale features.json. Includes the freshly regenerated docs/features.json — specs had drifted since the last manual regeneration, so this commit enters the enforced state green instead of failing the new gate on arrival. --------- Co-authored-by: Ruben van der Linde <ruben@conduction.nl>
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 2/2 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ |
Quality workflow — 2026-08-04 10:13 UTC
Download the full PDF report from the workflow artifacts.
nldesign's unit suite genuinely needs a Nextcloud server tree - in a bare checkout phpunit aborts with exit 255 on a missing OCP interface, which is not a test verdict. The guard is kept but now states verbatim why it skipped, and the check/check:full/check:strict summary lines no longer print a bare ALL CHECKS PASSED when the tests did not run. Cost stated: 'Frontend Build' and the dependent 'Quality Report' fail on this PR and fail identically at the PR base commit 065effe (run 30883115840) - a missing @gouvfr/dsfr icon source, unrelated to composer.json, and already green on the current development HEAD c6b1117. All four PHPUnit legs are green.
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 2/2 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ |
Quality workflow — 2026-08-04 11:12 UTC
Download the full PDF report from the workflow artifacts.
chore(deps): @conduction/nextcloud-vue 3.0.0-vue3.6
Quality Report — ConductionNL/nldesign @
|
| Check | PHP | Vue | Security | License | Tests |
|---|---|---|---|---|---|
| lint | ✅ | ||||
| phpcs | ✅ | ||||
| phpmd | ✅ | ||||
| psalm | ✅ | ||||
| phpstan | ✅ | ||||
| phpmetrics | ✅ | ||||
| eslint | ✅ | ||||
| stylelint | ✅ | ||||
| build | ✅ | ||||
| composer | ✅ | ✅ 100/100 | |||
| npm | ✅ | ✅ 2/2 | |||
| PHPUnit | ✅ | ||||
| Newman | ⏭️ | ||||
| Playwright | ✅ |
Quality workflow — 2026-08-04 13:12 UTC
Download the full PDF report from the workflow artifacts.
…pping (#214) A skipped job and a passing job are indistinguishable in the Quality Report. Every gate turned on here reported 'skipped' in every run. Each newly-enabled leg was measured against this tree BEFORE being enabled; the results are in the PR description. Legs that were measured failing are enabled anyway - the defects are pre-existing, and the only thing that changed is that CI can now see them. Journeydoc Capture and enable-axe are deliberately NOT enabled.
Automated PR to sync development changes to beta for beta release.
Merging this PR will trigger the beta release workflow.