Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .coverage-baseline
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
13.01
53 changes: 53 additions & 0 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,56 @@ jobs:
# schemas, or the app's own register→schema mapping still aren't there.
# cwd for this step is the Nextcloud server root.
playwright-seed-command: 'bash apps/softwarecatalog/tests/e2e/ci-seed.sh'

# Integration Tests (Newman) stays OFF here, deliberately. The
# `enable-newman: false` further up is not a default nobody chose: it
# records that the collection's requests hard-code
# `/var/www/html/custom_apps/openregister/...` paths that do not exist on
# a CI runner (Nextcloud lives under `server/apps/`, no rewrite), and that
# it assumes a seeded `voorzieningen` register / `module` schema. Turning
# it on would produce a guaranteed red whose cause is already written
# down. Flipped back on in the commit that rewrites the collection to the
# CI base_url and adds the seed step.
#
# Noted while checking this, because it is the kind of thing that reads as
# working when it is not: the validator counts collections RECURSIVELY
# (`find`) while the run step globs them FLAT (`for collection in
# *.postman_collection.json` after `cd`). A `newman-collection-path` that
# only satisfies the validator passes validation and then runs nothing.
# The configured `tests` path does satisfy both here.

# ── Frontend Check legs ──────────────────────────────────────────────
# `frontend-checks` defaults to `[]`, and an empty list means the shared
# workflow emits NO "Frontend Check" job at all — so these three
# validators ran nowhere while the run still looked complete.
# Measured on this tree before enabling: ALL THREE PASS. They are enabled
# to keep them passing, not because they are currently broken.
# `test:l10n:parity` is deliberately NOT added: measured on this tree it
# is short 404+ translations across the required locales. That is a
# translation backlog, and a permanently-red leg is one that gets switched
# off again.
# `test` / `test:unit` are NOT listed: "Frontend Tests (unit)" runs them.
frontend-checks: '["check:manifest", "check:vue-demi", "test:l10n"]'

# ── Coverage ratchet ─────────────────────────────────────────────────
# `enable-coverage-guard` defaults to FALSE, which is why both
# "Coverage Baseline Protection" and "Coverage Baseline Check" have only
# ever reported `skipped`. It needs two inputs this repo did not have,
# both added in this commit: `scripts/coverage-guard.php` (byte-identical
# to openregister's) and `.coverage-baseline` = 13.01, this repo's own
# measured coverage (4077 of 31330 statements) read from clover.xml in the
# `coverage-report` artifact of run 30911570224. That is the lowest figure
# in the fleet by a wide margin and is recorded here as measured, not
# rounded up: the ratchet's job is to stop it falling further, and a
# baseline set above the truth would fail on the first honest run.
enable-coverage-guard: true

# ── 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. Pinned to v1.0.1 so a change to the gate package
# cannot move this repo's verdict without a commit here.
# `enable-axe` deliberately NOT set: a vanilla Nextcloud 34 already carries
# serious/critical violations from core's own UI.
enable-hydra-gates: true
hydra-gates-ref: v1.0.1
59 changes: 59 additions & 0 deletions scripts/coverage-guard.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
#!/usr/bin/env php
<?php
/**
* Coverage guard — prevents test coverage from dropping.
*
* Usage: php scripts/coverage-guard.php <clover.xml> [--update-baseline]
*
* Exit codes:
* 0 — coverage is equal to or higher than baseline
* 1 — coverage dropped (PR should be blocked)
* 2 — missing files or invalid input
*/

$baselineFile = __DIR__ . '/../.coverage-baseline';
$cloverFile = $argv[1] ?? 'coverage/clover.xml';
$updateBaseline = in_array('--update-baseline', $argv, true);

if (!file_exists($cloverFile)) {
fwrite(STDERR, "Error: Clover file not found: $cloverFile\n");
exit(2);
}

if (!file_exists($baselineFile)) {
fwrite(STDERR, "Error: Baseline file not found: $baselineFile\n");
exit(2);
}

$xml = simplexml_load_file($cloverFile);
if ($xml === false) {
fwrite(STDERR, "Error: Could not parse $cloverFile\n");
exit(2);
}

$metrics = $xml->project->metrics;
$statements = (int)$metrics['statements'];
$covered = (int)$metrics['coveredstatements'];
$current = $statements > 0 ? round(($covered / $statements) * 100, 2) : 0.0;

$baseline = (float)trim(file_get_contents($baselineFile));

echo "Coverage baseline: {$baseline}%\n";
echo "Coverage current: {$current}%\n";

if ($current < $baseline) {
echo "FAIL: Coverage dropped by " . round($baseline - $current, 2) . "%\n";
exit(1);
}

if ($current > $baseline) {
echo "Coverage improved by " . round($current - $baseline, 2) . "%\n";
if ($updateBaseline) {
file_put_contents($baselineFile, number_format($current, 2) . "\n");
echo "Baseline updated to {$current}%\n";
}
} else {
echo "Coverage unchanged.\n";
}

exit(0);
Loading