feat(advisories): configurable check interval and a weekly digest (#171) #297
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
| name: Code Quality | |
| on: | |
| push: | |
| branches: [main, development, feature/**, bugfix/**, hotfix/**] | |
| pull_request: | |
| branches: [main, master, development, beta] | |
| workflow_dispatch: | |
| jobs: | |
| quality: | |
| uses: ConductionNL/.github/.github/workflows/quality.yml@main | |
| with: | |
| # app_versions with an UNDERSCORE, matching <id>app_versions</id> in | |
| # appinfo/info.xml — NOT the repository name, which is hyphenated. | |
| # | |
| # Nextcloud requires the app DIRECTORY name to equal the app id. Checked | |
| # out as `apps/app-versions`, `occ app:enable` fails with | |
| # | |
| # App "app-versions" cannot be installed because appinfo file cannot be read. | |
| # | |
| # which reads like a malformed or missing info.xml and is nothing of the | |
| # sort — the file is valid and simply not where that id says to look. All | |
| # six PHPUnit legs and the E2E job died on this at the install step, so | |
| # not one of them ever ran a test. | |
| app-name: app_versions | |
| php-version: "8.3" | |
| php-test-versions: '["8.3", "8.4"]' | |
| # THE LIST IS THE WHOLE DECLARED RANGE. appinfo/info.xml declares | |
| # <nextcloud min-version="32" max-version="34"/>, so 32, 33 and 34 each get | |
| # a leg. The previous list ran stable31 — below the floor even before this | |
| # change raised it — and had no stable34 leg at all, so the one major this | |
| # app most needed to prove was the one nothing touched. | |
| # stable34 leads because newman, playwright and journeydoc-capture all read | |
| # `fromJSON(inputs.nextcloud-test-refs)[0]` as their single server. | |
| nextcloud-test-refs: '["stable34", "stable32", "stable33"]' | |
| # This repo's PHP toolchain is the upstream Nextcloud app-template one: | |
| # php-cs-fixer + psalm (+ rector, phpunit). It has no phpcs.xml, no | |
| # phpmd.xml and no phpstan.neon, and correspondingly no `phpcs`, `phpmd`, | |
| # `phpstan` or `phpmetrics` composer script. | |
| # | |
| # Those four legs were nevertheless switched on, so quality.yml ran | |
| # `composer <tool>` and got `Command "<tool>" is not defined.` — i.e. the | |
| # phpmd / phpstan / phpmetrics jobs have been failing on every run for | |
| # months for the absence of a tool, not for a finding, and the phpcs job | |
| # passed VACUOUSLY (quality.yml maps composer's exit 1 to "warnings only → | |
| # pass"). Turning them off makes CI say what is true. Adopting them for | |
| # real is tracked as a follow-up issue; flip these back when the configs | |
| # and scripts land. | |
| enable-psalm: true | |
| enable-phpstan: false | |
| enable-phpcs: false | |
| enable-phpmd: false | |
| enable-phpmetrics: false | |
| enable-frontend: true | |
| enable-eslint: true | |
| enable-phpunit: true | |
| # ── Integration tests: OFF, and this is a correction ────────────────── | |
| # This was `true`, but there is no `tests/integration/` directory in this | |
| # repository and no *.postman_collection.json anywhere in it. The shared | |
| # workflow's "Validate Newman collections" step hard-fails on exactly | |
| # that ("collection directory 'tests/integration' does not exist"), so | |
| # the input could only ever have produced a guaranteed red that measures | |
| # nothing. It has never actually surfaced, because the Newman job also | |
| # carries `needs.security.result != 'failure'` and Security (npm) has | |
| # been failing here — so a broken input has been hiding behind an | |
| # unrelated failure. | |
| # This is not a gate being switched off because it failed. It is a gate | |
| # being switched off because the repository has nothing for it to run. | |
| # Flip it back to `true` in the same commit that adds a collection. | |
| enable-newman: false | |
| # ── notifications, because four e2e specs assert on its table ───────── | |
| # | |
| # jobs.spec.ts reads and clears `oc_notifications` to prove the | |
| # auto-update job tells the admin what it did. That table is created by | |
| # the `notifications` app, which is bundled into Nextcloud RELEASES but | |
| # is a separate repo and is NOT present in a server GIT checkout — which | |
| # is what this workflow installs. | |
| # | |
| # So those assertions failed with | |
| # SQLSTATE[42P01] relation "oc_notifications" does not exist | |
| # i.e. the app under test was blamed for the absence of an integration | |
| # that was never installed. Checking it out at the same stable branch the | |
| # server runs makes the assertion measure what it claims to. | |
| # `notes` is here for the same reason, found the same way. versions.spec | |
| # picks it as a representative App Store app and failed with | |
| # waiting for locator('article').filter({ has: getByText('notes') }) | |
| # i.e. the app card was simply not in the list, because Notes is another | |
| # separate repo absent from a server git checkout. It has no stableXX | |
| # branches, so `main` is the only ref there is. | |
| # `notes` was here and is deliberately gone. It is a separate repo whose | |
| # info.xml declares min-version="33", while this matrix includes | |
| # stable32 — so on two of the six PHPUnit cells it could never enable: | |
| # App "Notes" cannot be installed because it is not compatible with | |
| # this version of the server. | |
| # That looked harmless only because a failed enable is currently a | |
| # ::warning:: and the job carries on; ConductionNL/.github#355 makes it | |
| # fail, which is correct — a suite running without the app it was told to | |
| # install reports the absence as this repository's own failures. | |
| # | |
| # It was added so versions.spec had an installed App Store app to walk. | |
| # `dashboard` serves that purpose with no compatibility floor at all, | |
| # because Nextcloud bundles it — see the note at the top of that spec. | |
| additional-apps: '[{"repo":"nextcloud/notifications","app":"notifications","ref":"stable34"}]' | |
| enable-sbom: true | |
| # ── E2E browser tests ──────────────────────────────────────────────── | |
| # `enable-playwright` defaults to FALSE and this caller never set it, so | |
| # the 15 spec files under tests/e2e had never run in CI while the job | |
| # reported `skipped`. | |
| # No CI-scoped config is needed here, unlike most of the fleet: this | |
| # repo's ROOT playwright.config.ts declares only `setup` and `chromium` | |
| # — no `docs-capture` project (which would re-shoot documentation | |
| # screenshots on every PR) and no `visual` project (whose committed PNG | |
| # baselines are host-font/GPU specific and cannot byte-match a CI | |
| # runner). The run step's fallback to the root config is therefore the | |
| # correct behaviour here rather than an accident. | |
| # Honest expectation: this job will keep reporting `skipped` until | |
| # Security (npm) goes green, because the playwright job carries | |
| # `needs.security.result != 'failure'`. Enabling the input removes the | |
| # first of the two reasons it was dark; the second is a real failure in | |
| # this repo that this change does not touch. | |
| enable-playwright: true | |
| # ── The forge fixture, without which two thirds of the suite skips ──── | |
| # | |
| # Ten spec files open with | |
| # | |
| # test.skip(!(await fixtureAvailable(page)), 'forge fixture not running') | |
| # | |
| # and nothing in CI ever started it. On the first run in which this job | |
| # executed at all (2026-08-19) the tally was | |
| # | |
| # 7 failed · 3 flaky · 66 skipped · 22 passed | |
| # | |
| # and "22 passed" is what a reader takes away. The 66 are the CLI | |
| # commands, downgrade migration drift, the artifact cache, TOFU digest | |
| # recording, install faults and rate-limited forges — most of what this | |
| # app does. A skip whose reason has quietly stopped being true reads as a | |
| # considered decision and is an unnoticed hole. | |
| # | |
| # `bootstrap.sh` cannot serve here: it assumes Nextcloud in a container | |
| # named `av-e2e` joined to the fixture by a Docker network, and this job | |
| # runs the PHP built-in server on the runner. `bootstrap-ci.sh` is the | |
| # same wiring without Docker, and it EXITS NON-ZERO if the fixture does | |
| # not come up — the seed step fails the job on that, which is the point. | |
| # A fixture that silently fails to start would put those 66 tests back to | |
| # skipping for a reason that is no longer true. | |
| playwright-seed-command: "bash apps/app_versions/tests/e2e/fixtures/forge/bootstrap-ci.sh" | |
| # ── Hydra mechanical gates ─────────────────────────────────────────── | |
| # `enable-hydra-gates` defaults to FALSE, so this tier has never executed | |
| # here — the job reported `skipped`, which the Quality Report renders | |
| # identically to a pass. Unlike the two jobs above, this one is NOT gated | |
| # on the security job, so it reaches a verdict on this PR. | |
| # | |
| # No `hydra-gates-ref` here on purpose. The shared workflow defaults it | |
| # to @main, and this workflow is itself consumed at @main, so the two | |
| # sides move together and a gate fix reaches this repo without a commit | |
| # in this repo. A pin is a silent expiry date: 22 repos sat on v1.0.1 and | |
| # 16 gates were dead fleet-wide while every one reported PASS (.github#159), | |
| # and a default flipped at @main later reached those old runners and made | |
| # them red on gates they had no subject matter for (.github#173). | |
| # To hold this repo still for a specific reason, set the input explicitly | |
| # and say why — it is still honoured. To roll back for everyone, revert on | |
| # ConductionNL/.github main. | |
| # | |
| # Whole-tree debt on this repo (inherited, not created here): gates 38 | |
| # skip-link, 40 form-label-association, 43 table-headers and 45 | |
| # prefers-reduced-motion fail on the full tree. Diff scoping keeps them | |
| # out of unrelated PRs. | |
| # `enable-axe` deliberately NOT set: a vanilla Nextcloud 34 already carries | |
| # serious/critical violations from core's own UI. | |
| enable-hydra-gates: true |