Skip to content

gate: hold each app's Nextcloud floor and its tested CI matrix together (fleet-wide) #267

Description

@rubenvdlinde

The gap

Measured 2026-08-08 across the 16 fleet apps on development: exactly one (procest) has anything asserting that appinfo/info.xml's <nextcloud min-version> and .github/workflows/code-quality.yml's nextcloud-test-refs agree. openbuild has one in an unmerged PR (openbuild#148); doriath's was added today (doriath#190). The other 13 have nothing.

grep -c for a floor gate in hydra-gates/ returns 0.

Why it needs a gate rather than 16 copies

The floor has moved three times in 48 hours in openregister alone — 32 (#2378) → 28 (#2380) → 32 (#2384) — and every consumer had to be re-measured by hand each time. Two of those moves were made on a premise that had already expired when it was written.

Today's fleet-wide raise to 32 had to re-derive the same invariant per repo, and produced two copies of the same test that will now drift independently. One gate, run everywhere, is the shape that survives.

What it must assert

  1. No tested leg below the declared floor. min-version is enforced at install time, so occ app:enable refuses on such a leg. The shared workflow runs app-enable as || echo "::warning::…", so the refusal is only a warning: the job continues without its data layer and dies ~70 seconds later on missing schemas, which reads like a migration fault and sends you to the wrong file. This has now cost investigation time in at least three repos.
  2. At least one leg at or above the floor — otherwise the declared range is asserted but never exercised.
  3. The fleet-wide floor as a pinned literal. Assertions 1+2 are both satisfied by floor 28 with a stable28 leg — a self-consistent lowering. That is exactly the #2378→#2380 shape, and it is invisible to any agreement check.
  4. Exactly one nextcloud element in info.xml. Not hypothetical: several fleet info.xml files carry literal <nextcloud …/> examples inside comments, and grepping them produced two false floor readings today (procest and doriath were both reported as 28 when both are 32). A gate that regexes raw file text must count matches, or it will read a comment as a declaration.
  5. Omitting nextcloud-test-refs is not neutral. The shared quality.yml default is '["stable31", "stable32"]', so a repo that simply doesn't set the input silently inherits a stable31 leg. launchpad was in exactly this state on main today while carrying a comment that described the refs — prose, not the input.
  6. Positive control. The gate must fail loudly (distinct exit code) when it cannot find either input, rather than reporting a pass. A check that did not run looks exactly like one that passed.

Reference implementations

  • procest:tests/Unit/AppInfo/NextcloudFloorMatrixTest.php — PHPUnit; mutation-proved today (baseline green; floor→33 red; refs→[stable31,stable32] red; both red).
  • doriath:tests/Unit/AppInfo/NextcloudFloorMatrixTest.php (doriath#190) — adds assertions 3 and 4 above; mutation-proved 4 ways including the self-consistent drift-back.
  • openbuild:scripts/check-nc-floor.js (openbuild#148) — Node, wired into the frontend-checks matrix; mutation-proved 7 ways.

Note for whoever implements this: openbuild's script docblock claims a PHPUnit version of this test was impossible because "the PHPUnit job runs against a DEPLOYED copy … .github/workflows/ is not part of it." That claim is false. The shared workflow places the app with actions/checkout into server/apps/<name>, a full checkout including .github/ — which is why procest's PHPUnit version passes in CI today. Either shape works.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions