Skip to content

Release: merge beta into main - #1596

Merged
rubenvdlinde merged 30 commits into
mainfrom
beta
Aug 31, 2026
Merged

Release: merge beta into main#1596
rubenvdlinde merged 30 commits into
mainfrom
beta

Conversation

@rubenvdlinde

Copy link
Copy Markdown
Contributor

Second hop of the promotion. development → beta already merged; this carries beta to main, which is the branch Dependabot alerts and the Security (composer) gate actually read. Until it lands, the fixes on development drain nothing measurable.

Safe on the certificate front: this app's <id> in appinfo/info.xml is identical on beta and main, so signing is unaffected. Nextcloud issues one certificate per id, and an app whose id moves on promotion cannot sign a release until a new one is issued.

⚠️ Merge with --merge, never squash. Squashing a promotion rewrites the target's history and reverts commits already on main.

Do not merge before ~07:00 UTC. The Nextcloud App Store is rate-limiting this account: the current refusal is 429 ... available in 25043 seconds. The backoff escalates on every retry (3889s → 7010s → 25043s across today's attempts), so merging now would fail the App Store publish and risk pushing the window out further for every other app queued behind it. The GitHub release and tag are created regardless; only the store listing lags.

🤖 Generated with Claude Code

github-actions Bot and others added 16 commits August 30, 2026 19:10
The 0.4.10-beta.20260830190932 release bumped the version on beta. Without this,
development stays behind beta and the next development -> beta promotion
conflicts on the version file.

Version files resolve to development's side, which is the higher line,
so this never moves a version backwards.
…0260830191227

chore(sync): carry beta back into development
The 0.4.10 release bumped the version on main. Without this,
development stays behind main and the next development -> main promotion
conflicts on the version file.

Version files resolve to development's side, which is the higher line,
so this never moves a version backwards.
Bumps [@vue/compiler-sfc](https://github.com/vuejs/core/tree/HEAD/packages/compiler-sfc) from 3.5.41 to 3.5.42.
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](https://github.com/vuejs/core/commits/v3.5.42/packages/compiler-sfc)

---
updated-dependencies:
- dependency-name: "@vue/compiler-sfc"
  dependency-version: 3.5.42
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [vue](https://github.com/vuejs/core) from 3.5.41 to 3.5.42.
- [Release notes](https://github.com/vuejs/core/releases)
- [Changelog](https://github.com/vuejs/core/blob/main/CHANGELOG.md)
- [Commits](vuejs/core@v3.5.41...v3.5.42)

---
updated-dependencies:
- dependency-name: vue
  dependency-version: 3.5.42
  dependency-type: direct:production
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [webpack](https://github.com/webpack/webpack) from 5.109.2 to 5.110.1.
- [Release notes](https://github.com/webpack/webpack/releases)
- [Changelog](https://github.com/webpack/webpack/blob/main/CHANGELOG.md)
- [Commits](webpack/webpack@v5.109.2...v5.110.1)

---
updated-dependencies:
- dependency-name: webpack
  dependency-version: 5.110.1
  dependency-type: direct:development
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [css-loader](https://github.com/webpack/css-loader) from 7.1.4 to 7.1.5.
- [Release notes](https://github.com/webpack/css-loader/releases)
- [Changelog](https://github.com/webpack/css-loader/blob/main/CHANGELOG.md)
- [Commits](webpack/css-loader@v7.1.4...v7.1.5)

---
updated-dependencies:
- dependency-name: css-loader
  dependency-version: 7.1.5
  dependency-type: direct:development
  update-type: version-update:semver-patch
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@nextcloud/vue](https://github.com/nextcloud-libraries/nextcloud-vue) from 9.9.0 to 9.11.0.
- [Release notes](https://github.com/nextcloud-libraries/nextcloud-vue/releases)
- [Changelog](https://github.com/nextcloud-libraries/nextcloud-vue/blob/main/CHANGELOG.md)
- [Commits](nextcloud-libraries/nextcloud-vue@v9.9.0...v9.11.0)

---
updated-dependencies:
- dependency-name: "@nextcloud/vue"
  dependency-version: 9.11.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…1570)

Bumps [node-polyfill-webpack-plugin](https://github.com/Richienb/node-polyfill-webpack-plugin) from 4.0.0 to 4.1.0.
- [Release notes](https://github.com/Richienb/node-polyfill-webpack-plugin/releases)
- [Commits](Richienb/node-polyfill-webpack-plugin@v4.0.0...v4.1.0)

---
updated-dependencies:
- dependency-name: node-polyfill-webpack-plugin
  dependency-version: 4.1.0
  dependency-type: direct:production
  update-type: version-update:semver-minor
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
vue-router 5 peers `vite: ^7.3.0 || ^8.0.0` and expects a Vite toolchain. These
apps build with webpack, which cannot resolve it at all: the build dies on
`Can't resolve 'vue-router'` from src and from @nextcloud/vue's own chunks.
Adopting it is a Vite migration, not a version bump.

Dependabot proposed it across 8 repositories in a single run, and merging any
one of them takes that app's build from green to red with no code change that
can fix it.

versioniq already builds with Vite and is the natural pilot if the fleet does
move. Lift this when an app's toolchain can actually take it.
#1588)

* fix(pipeline): declare propertyMappings so a pipeline can say what it boards

The New Lead and New Request forms offered NO pipeline at all. Both
filtered on `pipeline.entityType`, and PipelineManager already calls that
field a legacy fallback: the live model is `propertyMappings[].schemaSlug`.
No stored pipeline carries either, so every pipeline failed the filter,
the dropdown was empty and autoAssignDefaultPipeline() found no default.

`propertyMappings` was never declared on the pipeline schema. Magic-table
storage drops undeclared properties, so PipelineFormDialog's mapping
editor — schema slug, column property, totals property, add and remove
rows — has been writing an array OpenRegister silently discarded, and
PipelineBoard resolved no object types to subscribe to. The register's
own changelog already names this failure mode on another schema:
"declared explicitly because magic-table storage drops undeclared
properties". Declaring it is the fix; the read side needed no change.

The forms now share pipelineAppliesTo(), which prefers propertyMappings,
falls back to entityType, and treats a pipeline declaring NEITHER as
unscoped rather than inapplicable. That default is the actual bug fix:
reading "undeclared" as "applies to nothing" is what emptied the list.

Seed data could not demonstrate any of this. The two demo pipelines
declared no mappings; the leads carried a stage name but no pipeline, so
they belonged to no board and every column counted zero; one used a
Qualified stage the pipeline did not define, and the service pipeline
was still Dutch while its requests were English, matching 1 of 4 stages
in use. The seeder had no pipelineKey to link them with, so this adds
one alongside the existing clientKey.

Verified against the running instance: after seeding, all six demo leads
carry a pipeline uuid and a stageOrder matching the pipeline's own
ordering. That check is what caught the schema gap — the seed reported
"created 2" while propertyMappings came back null.

Also subscribes the dashboard cache to `cn:page:refresh`. The library's
declarative surfaces announce a refresh with that event and nothing
listened, so a declarative refresh would have bumped an event into the
void while the 5-minute cache kept serving — a button that looks like it
worked and refreshes nothing.

* docs(dependabot): correct the vue-router holdback to what was measured

The comment claimed these apps "cannot resolve it at all". That is not what the
evidence shows, and a comment that overstates its case is worse than none: the
next person reads it, tries vue-router 5 somewhere it works, and stops trusting
the file.

Measured across four apps: integriq and zaakafhandelapp fail their build on
`Can't resolve 'vue-router'`, while openregister and learniq build clean on
5.3.0. The holdback still stands, for the honest reason rather than the
overstated one: a major that breaks some apps and not others cannot be merged
unattended, and the difference between them is not yet understood.

No behaviour change. The ignore rule is unchanged; only the reasoning is.
…225518

chore(sync): carry main back into beta
…0260830225526

chore(sync): carry beta back into development
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/pipelinq @ e58a5aa

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-vue-demi
test-l10n
format
check-schema-l10n
check-l10n-js
composer ✅ 106/106
npm ✅ 645/645
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Spec coverage: 68% — 212 of 313 enforceable scenarios carry an @e2e reference (threshold 20%, 2362 excluded with a reason).


Quality workflow — 2026-08-31 01:16 UTC

Download the full PDF report from the workflow artifacts.

rubenvdlinde and others added 9 commits August 31, 2026 03:25
…1601)

2.25.x makes the canonical KPI card flat and horizontal, so dashboards stop
drawing a grey box inside the white card CnWidgetWrapper already draws, and
2.25.1 fixes the narrow-tile step-down that 2.25.0 shipped inert (a source-order
bug left KPI values clipped on a three-column tile).

The caret range already allowed both; only the lockfile pinned this app back.
Lockfile only.
development has been failing `quality / Frontend Check (format)` on this one
file. Prettier wants a two-element array broken across lines:

    propertyMappings: [{ schemaSlug: 'lead' }, { schemaSlug: 'request' }],

becomes one entry per line. No behaviour change; the spec is untouched
otherwise.

This is pre-existing breakage on development, not something the promotion
introduced: the same six checks fail on development's own push run
(33340433368). It surfaced through the development -> beta PR (#1585), which
reports it faithfully.

Verified: `npm run format` exits 0 across the whole tree afterwards.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
development fails `quality / Frontend Check (check:schema-l10n)`: the ratchet
counts 1983 uncovered schema strings against a baseline of 1982.

The gate reports a COUNT, not which string, so the four were found by diffing
the uncovered list at 8580ced (1979) against development (1983). All four are
in lib/Settings/pipelinq_register.json and all four came in with the same
pipeline-scope feature as the spec file fixed in the sibling PR:

  schemaSlug.description
  columnProperty.description
  totalsProperty.description
  propertyMappings.description

Added to en.json as identity and nl.json translated, then `npm run l10n:build`
so they reach l10n/nl.js — the only l10n file the browser loads. A nl.json-only
change would have satisfied the gate and still rendered English.

The baseline drops 1982 -> 1979 rather than staying put. Covering 4 strings
against a baseline of 1982 leaves 3 spare, and a ratchet with slack in it
silently permits the next 3 regressions.

Verified: check:schema-l10n exits 0, and the Dutch text is present in
l10n/nl.js rather than only in the JSON.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
…1600)

development fails `quality / PHP Quality (phpmd)` on one violation:

  DemoSeedService.php:676  CyclomaticComplexity
  linkReferences() has a Cyclomatic Complexity of 10.
  The configured threshold is 10.

The method wired four relations, each as an isset() guard plus a null check —
eight branches — plus the request/parentTicket choice. Extracting the repeated
lookup into linkOneReference() takes linkReferences() to 2 and the helper to 3.

Behaviour is unchanged: the same four links with the same field names, keeping
clientField ?? 'client' (the contract schema calls it clientRef and everything
else client) and the request -> parentTicket switch for ticket subtypes. The
comments explaining both survive, because they carry the reason.

Two self-inflicted findings on the way, both caught by reading phpcs rather
than my own summary of it:
  - the repo requires named arguments for internal calls; the four new call
    sites each tripped that sniff.
  - naming them pushed three lines past the 150-char limit, so they are
    wrapped one argument per line.

Verified: php -l clean, phpcs exit 0, phpmd exit 0 -- repo-wide, both composer
scripts, not just the changed file.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
…ema (#1603)

E2E and Newman both die seeding demo data with HTTP 412. The body the seed
script already prints says why:

  Pipelinq register or schemas are not provisioned -- run the provisioning
  step first.

That is resolveContext() returning null, and step 1 shows the reason: the
reimport returns success and lists every schema id EXCEPT one.

  "register":"16", "client_schema":"19", ... "pipeline_schema":""

pipeline_schema is empty. The schema silently failed to import while reimport
reported success: true.

The cause is a union type:

  "totalsProperty": { "type": ["string", "null"] }

OpenRegister drops the entire schema when a property declares a union, and
logs nothing at warning level. The correlation here is exact: one union type
in the file, one empty schema id, and they are the same schema.

totalsProperty is not a required property, so the null member was redundant --
optionality is expressed by absence, not by a nullable union. The description
and title are untouched.

This supersedes my earlier diagnosis on #1585, which blamed the Contacts
integration. The seed script prints the response body and always did; I had
claimed it did not, and reading it would have been faster than reading four
PHP files.

Verified: JSON parses, no union types remain anywhere in the file, and the
diff is 1 insertion / 4 deletions -- the union collapsed, nothing reformatted.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
* fix(deps): resolve the peer chain so npm ci works

npm ci failed with ERESOLVE, so every frontend job failed before running
a single check.

Majors had landed WITHOUT the peers that must move with them. These
packages are a set: bumping one alone leaves another declaring a range
the new version cannot satisfy, and npm rejects the whole tree rather
than the single package. Fixing them individually walks the list,
because each correction exposes the next conflict underneath.

Realigned: node-polyfill-webpack-plugin=4.0.0

Each range is the one npm itself demanded in the ERESOLVE it reported --
discovered by applying it and re-checking until resolution succeeded --
rather than a version chosen by hand.

Measured across the fleet: nine apps were unresolvable on this pattern.

Verified: the lockfile resolves from a clean tree, where it previously
exited on ERESOLVE.

* style: run Prettier now that npm ci works

The dependency fix in this branch is what let these checks run at all.
While npm ci exited on ERESOLVE, every frontend job failed at install and
reported nothing about the code -- so a formatting drift sat unreported
underneath.

With resolution restored the checks execute for the first time in a
while, and this is what they found. Prettier only; no behavioural change.

---------

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
….4.10

chore(release): sync main back into development
….4.10-beta.20260830190932

chore(release): sync beta back into development
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
Carries the two KPI-card fixes this dashboard reads: the canonical card is flat
and horizontal (no grey box inside the white card CnWidgetWrapper already
draws), and a calendar-aligned date range follows the reader's calendar rather
than UTC — "Current month" previously showed a To of 1 September in CEST on
31 August.

The caret range already allowed it; only the lockfile pinned this app back.

npm also pruned 157 packages that were extraneous in the committed lockfile.
That is a consequence of regenerating, not of the bump. Verified rather than
assumed: none of them is declared in package.json or named by a script, npm ci
installs clean, and the production build succeeds.

Prepared in a fresh clone — the workspace checkout is held by other in-flight
work that is itself editing package-lock.json.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
rubenvdlinde and others added 2 commits August 31, 2026 09:55
* test(leads): pin the pipeline select end to end

The pipeline dropdown was empty on both create forms and nothing caught
it. tests/vitest/pipelineScope.spec.js now pins the filter predicate, but
that was only half the defect: `propertyMappings` was undeclared on the
schema, so the data the predicate reads was discarded on write. Only an
end-to-end check spans both halves.

Fields are addressed by data-testid rather than label text. The dev
instance renders Dutch ("Pijplijn" / "Fase") and CI renders English, so a
label selector passes in one and fails in the other for no product
reason.

* style(e2e): prettier on the pipeline-select spec
…1609)

pipelinq is the only one of the 21 fleet apps still carrying
beta-release.yaml and release-workflow.yaml. The other twenty ship
release.yml alone, and pipelinq release.yml is byte-identical to theirs
apart from the app-name input, so it already covers every branch the two
legacy files triggered on: main, beta and development.

Keeping them costs a real failure rather than only duplication. Both
check out with ssh-key: secrets.DEPLOY_KEY and then git push, and that
key is read-only, so every push to beta runs release-management and it
exits 128. That is the second failure on #1596, and it needs no secret
change to clear: the job should not be running at all.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
rubenvdlinde and others added 2 commits August 31, 2026 10:52
…it was hiding (#1615)

* chore(lint): clear the correctness half of the warning backlog

Four categories, 91 warnings, chosen because each one is a real defect
rather than a missing sentence.

`OC.currentUser` and `OC.generateUrl` were deprecated in Nextcloud 19.
Nine call sites now use the accessor the rest of this codebase already
uses (`window.OC?.getCurrentUser?.()?.uid`) and the canonical
`generateUrl` import, so no new dependency is taken.

Fifty `$emit` calls were undeclared. In Vue 3 an undeclared event stays
in `$attrs` and falls through onto the root element, so a parent's
handler can fire twice — once from the DOM, once from the emit. Every
component that emits now declares what it emits.

Six template refs were declared and never read; none of their files
touches `$refs` at all.

ctiApi.js carried auto-generated `@param root0` stubs with no
descriptions. Its twenty-six warnings are now real prose, including the
one that is not obvious from the signature: `expiresAt` exists so the
recording's retention rule travels with the link instead of being
assumed downstream.

A blanket `eslint --fix` is NOT how this was done. Running it adds
`@param` tags with no types, which the config treats as errors: it took
the tree from 0 errors to 30. The remaining 271 warnings are almost all
missing @PARAM prose and are being worked through by file.

* chore(lint): document the services and settings, fix the docblock formats

Second sweep batch: 229 -> 174 warnings, still 0 errors.

MyWork, Settings and the two status services get real @PARAM prose. The
descriptions say what the caller must know rather than restating the
name: `computeGroup`'s `isClosed` exists because a closed item must
never land in an overdue bucket, and `weekEnd` is the "this week"
boundary, neither of which is visible from the signature.

The two formatting rules are fixed from their reported locations rather
than by hand: 14 docblocks were missing the blank line between
description and first tag, and 14 prose mentions of `@objectId` parsed
as inline JSDoc tags and are now backticked.

`eslint --prune-suppressions` is run because fixing suppressed
violations LEFT STALE ENTRIES, and stale entries make eslint exit 2 —
the sweep briefly broke `npm run lint` for the opposite of the usual
reason. The baseline drops 360 -> 336.

* chore(lint): document the component and widget handlers

Third sweep batch: 174 -> 116 warnings, 0 errors, suppression baseline
336 -> 278.

Fifty-eight @PARAM descriptions across the relationship, survey,
messaging, product, pipeline, timeline, contact and widget components,
each written against what the parameter actually is rather than
restating its name. The one worth reading is
`ensureClientInOptions(clientId)`: it exists so a client already on the
record still appears in the picker when it falls outside the current
search results, which is not deducible from the signature.

Types are filled in alongside the prose, because a description without
one still fails jsdoc/require-param-type — the pair has to land
together.

* chore(lint): document the settings, store and dialog handlers

Fourth sweep batch: 116 -> 63 warnings, 0 errors.

Twenty-four descriptions filled and twenty-three @PARAM tags added
where the docblock carried only a @SPEC line and no parameter
documentation at all.

Twenty-nine docblocks are reordered so @PARAM and @return come before
@SPEC, matching the convention the rest of the file base already
follows. Inserting the tags put them after @SPEC, which lints clean and
reads wrong.

* fix(xwiki): sanitise the remote article HTML before rendering it

The viewer's own header said it "displays sanitised content via v-html".
Nothing sanitised it. The markup comes from whatever xWiki instance an
admin configured, and neither XWikiService nor XWikiController touches
it, so remote HTML reached v-html raw.

The lint rule that would have said so was suppressed by an
`eslint-disable-next-line` sitting one line too high: it covered the
`<div` line while the violation was reported on the `v-html` attribute
two lines below. The suppression was silently doing nothing, which is
why the warning was still in the backlog.

DOMPurify was already a declared dependency. The disable comment now
sits where it belongs and the header says what the code does.

Also replaces the last vague JSDoc types: five `Function` and three `*`
now carry real signatures, so `getCategoryById` reads as
`(function(string): (object|undefined))` rather than "a Function".

* chore(gates): tag the three methods gate-16 flagged

Two are deprecated-global swaps whose behaviour did not change, and one
is the new sanitising computed. None has a requirement to point at:
openspec/specs/customer-portal specifies the portal's origin gate, not
document download or export requests, and openspec/specs/xwiki-proxy
specifies where article content is fetched from, not how it is rendered.

A reason-bearing `@spec exclude` is the honest tag here. Inventing a
requirement reference to turn the gate green would make the gate lie
about coverage that does not exist.

* chore(gates): move the cascade e2e spec to the feature branch it tests

A `git add -A` swept it into this commit. It belongs with the client and
contact pickers in #1612, not with the lint sweep.
Release: merge development into beta
@github-actions

Copy link
Copy Markdown
Contributor

Quality Report — ConductionNL/pipelinq @ ab34641

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
check-manifest
check-vue-demi
test-l10n
format
check-schema-l10n
check-l10n-js
composer ✅ 106/106
npm ✅ 631/631
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman
Playwright
Hydra gates

Spec coverage: 68% — 212 of 313 enforceable scenarios carry an @e2e reference (threshold 20%, 2362 excluded with a reason).


Quality workflow — 2026-08-31 10:32 UTC

Download the full PDF report from the workflow artifacts.

@rubenvdlinde
rubenvdlinde merged commit df79341 into main Aug 31, 2026
57 of 58 checks passed
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.

1 participant