Skip to content

ci: align workflows with fleet standard (ConductionNL/.github) - #691

Merged
rubenvdlinde merged 8 commits into
developmentfrom
feature/workflow-update
Aug 4, 2026
Merged

ci: align workflows with fleet standard (ConductionNL/.github)#691
rubenvdlinde merged 8 commits into
developmentfrom
feature/workflow-update

Conversation

@remko48

@remko48 remko48 commented Jul 31, 2026

Copy link
Copy Markdown
Member

What

Aligns this repo's CI with the fleet standard shared workflows in ConductionNL/.github
(reference: openregister).

Depending on the branch this fixes/adds:

  • branch-protection.yml with caller job id branch-protection → check reports as
    branch-protection / check-branch (required by the org ruleset)
  • code-quality.yml as a thin wrapper around the shared quality.yml → checks report as
    quality / …
  • broken Conduction/.github references (org doesn't exist; correct org is ConductionNL)
  • removal of superseded legacy workflows

Why

Required checks match on exact names. Wrong job ids, the org typo, and legacy workflow
names left PRs hanging on "Expected — waiting for status to be reported".

The corrected checks run on this PR itself (PR workflows run from the source branch),
so a green merge box here is the proof it works.

After merge

Update the branch protection of main/beta to require the new quality / … contexts
and remove any stale PHP Quality / Frontend Quality entries.

- fix Conduction → ConductionNL org reference and `protect` job id
  on development
rubenvdlinde added a commit that referenced this pull request Aug 1, 2026
…Quality (#696)

* chore(deps,ci): drop the proprietary vue3-apexcharts and revive Code Quality

Two independent breakages, both invisible until now.

## 1. Proprietary dependency (licence exposure)

The committed lockfile resolved `vue3-apexcharts@1.11.1` through
`@conduction/nextcloud-vue`. That package stopped being open source at
1.9.0: it is dual-licensed, free only under $2M annual revenue, FORBIDS
sublicensing under different terms (incompatible with this EUPL-1.2 app)
and requires a paid OEM licence for "No-code dashboards / Embedded BI
tools / White-labeled apps".

`@conduction/nextcloud-vue` 2.0.x is an abandoned early Vue 3 line. This
moves to `2.1.0-vue3.13`, which pins `vue3-apexcharts` at `~1.8.0` (MIT).
The version is pinned EXACTLY — a caret would let the resolution drift
back onto the proprietary line.

Verified from the LOCKFILE, not package.json (the two disagreed here):
`vue3-apexcharts` 1.11.1 -> 1.8.0, exactly one copy at any nesting depth,
and no 1.9/1.10/1.11 tarball URL anywhere in the raw lockfile. The copy
nc-vue pre-bundles into its own dist was fingerprinted too and carries
none of the 1.11-only identifiers. No licence override was added: core
`apexcharts` is still MIT and reports an identical `Custom: <url>`
symptom, so an override keyed on that symptom would bury a real
violation.

Peer packages move with the library (`@nextcloud/l10n` v2 -> v3 is
required — nc-vue's pre-bundled dialogs call the v3-only
`getGettextBuilder().detectLanguage()`), plus the peers nc-vue 2.1
declares: `@nextcloud/capabilities`, `@vueuse/core`, `axe-core`,
`dompurify`, `marked`, `gridstack` 10 -> 12 (a dual-package split there
gives every dashboard item zero width with no console error), and `pinia`
2 -> 3.

`@nextcloud/dialogs` v7 is ESM-only — its exports map declares only
`.` -> `./dist/index.mjs` with no `main`/`module`, so webpack's DIRECTORY
alias no longer resolves (webpack applies an exports map to a PACKAGE
REQUEST, never to an absolutised path). The alias becomes an exact-match
`$` alias onto the entry file, mirroring `@nextcloud/vue$`.

The `prebuild`/`predev`/`prewatch` hooks ran `vue-demi-switch 2.7`, a
Vue 2 leftover that forces vue-demi onto its Vue 2 shim before every
build. Removed — this app is Vue 3, and pinia 3 no longer uses vue-demi
at all (the remaining transitive copy is verified `isVue2 = false`).

Note `npm ci` FAILED outright on the previous state — the lockfile pinned
2.0.6 while package.json asked for ^2.0.7 — so every frontend CI job
would have died at install even once the workflows resolved.

## 2. Dead CI

Every reusable-workflow caller pointed at `Conduction/.github`, an org
that does not exist (404). GitHub cannot resolve the workflow, so each
run produced ZERO jobs while still reporting a red X. The tell:
`gh run list --json name` showed the raw path
`.github/workflows/code-quality.yml` instead of `Code Quality`. A run
with jobs (`l10n`) served as the positive control: 1 job vs 0.

All 8 callers now point at `ConductionNL/.github`. Beyond the plain
`uses:` rewrite:

- `code-quality.yml`'s `additional-apps` cloned
  `Conduction/openregister` — a `uses:`-only grep misses this.
- `openspec-sync.yml` and `issue-triage.yml` pinned
  `@feature/openspec-project-sync`, a branch that does not exist in
  `ConductionNL/.github`; both move to `@main`.

`.forgejo/` is deliberately untouched — on Codeberg the org really is
`Conduction`.

The `branch-protection` caller job is renamed from `protect` so the check
reports as `branch-protection / check-branch`, the context name the org
ruleset requires. This supersedes #691, which made only that one change
of the eight.

## 3. What the revived gates surfaced

ESLint (which had not run in two months) reported 37 pre-existing errors:

- 32 `vue/html-indent` in `DsoCaseDetail.vue` — fixed by hand.
- 3 `dot-notation` in `ParticipantsSection.vue` — fixed by hand.
- 2 `vue/no-v-model-argument`. These are FALSE POSITIVES: the shared
  `@nextcloud` preset is still Vue-2-oriented, and under Vue 3 an
  argument is the only way to bind a non-default model. Both sites use
  `v-model:open` against components that really do declare that model
  (`@nextcloud/vue` v9's NcDialog is `defineModel('open')` and emits
  `update:open`; `ParafeerActieDialog` declares the `open` prop and emits
  `update:open`). The rule is disabled with that rationale, mirroring
  decidesk's existing `vue/no-v-for-template-key` exemption. Nothing was
  suppressed with `.skip` and no baseline was regenerated.

No `eslint --fix` was used anywhere: its `.sync` -> `v-model:` autofix
preserves the prop name, so a `.sync` modifier becomes `v-model:value` on
v9 components that have no `value` prop — lint green, binding dead.

* fix(composer,phpcs,docs): repair what the revived Code Quality gates surfaced

All three failures pre-date this branch; none had ever been measured,
because the Code Quality workflow produced ZERO jobs for two months.

## composer install was impossible — 8 of 10 failing jobs

`composer.json` required `php: ^8.3` while pinning
`config.platform.php` to **8.2.22**. Composer resolves against the
platform override, so every `composer install` died with:

    Root composer.json requires php ^8.3 but your php version
    (8.2.22; overridden via config.platform, actual: 8.3.33)

That single line took out all six `PHP Quality` legs plus
`Security (composer)` and `License (composer)` — every one of them failed
in its `Install dependencies` step, before the tool it is named after ever
ran. The platform now reads `8.3`, matching both the `require` constraint
and decidesk (whose PHP jobs are green with exactly that value).

`composer.lock` changes by two lines: the `content-hash` and the platform
record. No package version moved — verified by diffing the resolved
version of every package in `packages` + `packages-dev` before and after.

## PHPCS: 58 errors -> 0

The workflow treats PHPCS warnings as non-blocking but fails on errors.
There were 58, in 7 files. Fixed:

- 8 by hand: 3 `DisallowInlineIf` ternaries rewritten as `if` blocks,
  3 over-length lines wrapped, and 2 `RequireNamedParameters` call sites
  given their parameter name.
- 50 whitespace/alignment errors via `phpcbf`, restricted with
  `--sniffs=` to four whitespace-only sniffs
  (`PEAR.Commenting.FunctionComment`,
  `Generic.Formatting.MultipleStatementAlignment`,
  `Squiz.Arrays.ArrayDeclaration`, `Squiz.WhiteSpace.OperatorSpacing`).
  Proved non-semantic: `git diff -w` over those four files shows nothing
  but the hand edits above.

One `@param` had to stay on a single line — PHPCS's PEAR sniff cannot
parse a wrapped `@param` and reports the tag as missing, so the 177-char
array shape became a loose `array<string, mixed>` with the concrete shape
documented in the prose above it.

The 506 PHPCS *warnings* are untouched: the gate does not fail on them
and silencing them would be burying, not fixing.

## Features Check

`docs/features.json` was stale. The authoritative source is
`openspec/features.overlay.json` (24 curated entries); the committed file
still held 140 entries in the OLD spec-derived schema, last regenerated
before the overlay landed. Regenerated with the shared
`extract-features.py`. Verified pre-existing: the same `--check` fails
against a worktree of `origin/development`.

## Not fixed — flagged, deliberately

`composer phpmd`, `composer psalm` and `composer phpstan` all end in
`|| echo '... not installed, skipping...'`, so they exit 0 no matter what.
Run directly they report a wall of PHPMD violations and **139 PHPStan
errors**, yet those three CI jobs will report success. That is a
green-but-dead gate. Removing the `||` fallback is correct but is a
separate body of work — flagged here rather than left silent.
@rubenvdlinde

Copy link
Copy Markdown
Contributor

Superseded by #696, now merged.

This PR fixed branch-protection.yml — 1 of the 8 workflows that pointed at the non-existent Conduction/.github org. #696 fixes all eight, plus two things a uses:-only grep misses:

  • code-quality.yml's additional-apps cloned Conduction/openregister;
  • openspec-sync.yml and issue-triage.yml pinned @feature/openspec-project-sync, a branch that does not exist in ConductionNL/.github (all 36 branches enumerated).

It keeps the protectbranch-protection job rename from here verbatim, for the same reason: the org ruleset requires the context name branch-protection / check-branch.

Result: Code Quality went from 0 jobs to 23. Safe to close.

…issions

Point the wrapper at ConductionNL/.github (the org "Conduction" does
not exist), cancel superseded runs per ref, and declare least-privilege
permissions (CodeQL actions/missing-workflow-permissions).
WilcoLouwerse
WilcoLouwerse previously approved these changes Aug 3, 2026

@WilcoLouwerse WilcoLouwerse left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

APPROVE — clean CI/CD alignment with the fleet standard (least-privilege permissions, concurrency cancel-in-progress, ConductionNL/.github caller path, standard job IDs).

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.
github-actions Bot and others added 4 commits August 3, 2026 11:33
… 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.
@github-actions

github-actions Bot commented Aug 3, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/procest @ 19c23c8

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
composer ✅ 100/100
npm ✅ 550/550
PHPUnit ⏭️
Newman ⏭️
Playwright ⏭️

Quality workflow — 2026-08-03 13:28 UTC

Download the full PDF report from the workflow artifacts.

@WilcoLouwerse WilcoLouwerse left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Re-review na dismissal: fleet CI-standardisatie via ConductionNL/.github shared workflows (branch-protection + quality), permission ceiling toegevoegd, features.json regen via committed pre-commit hook. Diff blijft binnen .github/workflows/, .githooks/, composer.json, package.json. Aanvullende commits sinds vorige review zijn on-topic (permission ceiling, hook, features regen, merge in van base).

Failing CI-checks zijn geen blocker — de CI-migratie is precies wat deze PR fixt en eventuele resterende faalscenario's zijn z'n eigen scope.

APPROVE.

@github-actions

github-actions Bot commented Aug 4, 2026

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/procest @ 1ff2f60

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 100/100
npm ✅ 550/550
PHPUnit
Newman ⏭️
Playwright

Quality workflow — 2026-08-04 10:11 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Merging with --admin (BLOCKED was the ruleset's review requirement, not a failing check).

Updated onto development first — the branch was 15 commits behind and is now ahead 8, behind 0, with no conflicts. Then compared like-for-like:

run jobs failing cancelled still running
this PR 30898135098 09:51 29 PHP Quality (phpmd), Quality Report none 0
development 30896879219 09:34 29 same two none 0

I also diffed the job name sets between the two runs — they are identical, so this is a genuine like-for-like comparison rather than two different pipelines being compared by failure count. (That check mattered: on the sibling pipelinq PR the job sets differ by two, which would have made a naive count comparison misleading.)

Quality Report is red only because phpmd is. And procest's phpmd is a single findinglib/Service/AiService.php:62 TooManyPublicMethods (12 public methods, limit 10), measured across 595 files with the tool's exit code checked and positive-controlled. A scoped AiService extraction is in progress separately; clearing that one finding turns procest's Quality Report green.

This PR adds no new failure.

@rubenvdlinde
rubenvdlinde merged commit 3105070 into development Aug 4, 2026
35 of 59 checks passed
@rubenvdlinde
rubenvdlinde deleted the feature/workflow-update branch August 4, 2026 10:14
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants