Skip to content

Release: merge development into beta - #245

Merged
rubenvdlinde merged 26 commits into
betafrom
development
Aug 30, 2026
Merged

Release: merge development into beta#245
rubenvdlinde merged 26 commits into
betafrom
development

Conversation

@github-actions

Copy link
Copy Markdown
Contributor

Automated PR to sync development changes to beta for beta release.

Merging this PR will trigger the beta release workflow.

Reminder: Add a major, minor, or patch label to this PR to control the version bump. Default is patch.

rubenvdlinde and others added 3 commits August 27, 2026 18:15
* fix(e2e): appConfigValue must fail loudly when the READ fails

versioniq's E2E went red on development between 2026-08-26 13:52 (green)
and 2026-08-27 08:34, with eight specs failing across five files. Every
one of them reads through appConfigValue, and every one fails as though
the FEATURE did nothing:

  expect(pin.driftedTo ?? …, 'drift recorded on the pin').toBeTruthy()
  expect(binding.forge).toBe('codeberg')            Received: undefined
  expect(binding.sha256?.['1.0.1'], …).toMatch(…)   Received: undefined

The helper did `if (!res.ok()) return null`. Once that null reaches
`JSON.parse(… ?? '{}')` a failed READ and a feature that wrote nothing
are indistinguishable, so all eight blame the app for what may be a
transport, auth or provisioning_api problem. They need different fixes,
so they must not wear the same words.

The sibling test that asserts an ABSENCE -- "records no drift while the
installed version matches the pin" -- PASSES on a null read, because a
read that returned nothing looks exactly like a job that recorded
nothing. That is precisely the failure mode #233's own docblock warns
about, one helper over in the same file.

This is the same fix #233 applied to runJob. It does not turn the suite
green; it makes the next run say which of the two problems it has. I
could not determine that from the logs, because the current helper is
built so that it cannot be determined.

A genuinely unset key stays a real answer: OCS replies 200 with an
ocs.meta statuscode of 404, and that still returns null.

Verified: npm run lint rc=0. The tsc errors in src/**/*.spec.ts are
pre-existing and unrelated to this file.

* fix(e2e): retry the 5xx band, because a 503 here is transient

The loud error this branch added did its job on the first run, and the
answer it gave was "HTTP 503" -- not an app defect at all.

Measured on this branch's own E2E run: the error fired FIVE times and
every one of those specs PASSED on retry. Nine flaky specs in a single
run, all of them this same config read. Nextcloud answers 503 while an
app install or upgrade is in flight, which is exactly when these
fixtures run.

So retry the 5xx band, briefly and boundedly (4 attempts, 250ms steps).
A persistent outage still throws, and the message now distinguishes the
two cases:

  4xx        -> check provisioning_api is enabled and the request is authed
  5xx x4     -> an unhealthy server, not a race; check for maintenance mode

4xx is deliberately NOT retried. An auth or permission failure is a real
answer, and repeating it would only hide it -- which is the same mistake
as the swallow this branch set out to remove.

Verified: npm run lint rc=0, and `playwright test --list` compiles all
103 tests across 17 files.

---------

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
* perf(ci): one Code Quality run per commit, not two

* ci: add the merge-hygiene smoke alarm this repo never had
* fix(e2e): an install that no-ops must fail where it happens

installFixture returned exit 0 and a structured payload without ever
checking that the app actually moved. resetFixtureApp has always known
this can happen -- 'rapid sequential installs each toggle maintenance
mode, and an occasional overlap can make one attempt a no-op' -- and
retries once with maintenance:mode --off. No other caller had that.

A no-op there is silent, and it does not surface where it happens. It
surfaces as whatever the test asserted next, phrased as if that were the
defect. jobs.spec.ts:169 installs 1.0.1, pins at 1.0.0 and expects the
reconcile job to record drift; when the install no-ops the app stays at
1.0.0, installed == pinned, PinReconcileJob correctly records NO drift,
and CI reports 'Error: drift recorded on the pin' -- true about the job,
and a completely false lead about the cause. It failed both attempts on
2026-08-27 with six more install-backed tests flaky in the same run.

Verify that the version landed whenever the CLI claims success, clear the
stuck maintenance flag and retry once, and throw naming the no-op if it
still has not moved. Deliberate failures (tamper, wrong id, refused
guard) exit non-zero and are untouched.

* fix(e2e): gate the no-op check on installStatus, not the exit code

install-effects.spec.ts calls installFixture for an appId-mismatch archive
and asserts nothing about the outcome. Keying the new verification off
the exit code alone would, if that path ever exits 0 while reporting a
failure, turn a passing test into a thrown error here.

installStatus === 'installed' is the marker the specs themselves assert
on (not.toBe('installed') for every refused case), so gate on that.
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ b8af4ff

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 282/282
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-27 21:00 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ 142fa07

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 282/282
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-27 22:26 UTC

Download the full PDF report from the workflow artifacts.

rubenvdlinde and others added 2 commits August 28, 2026 06:58
Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
…242)

The App Store keys everything on the app id, so renaming <id> to versioniq made
it a brand new store entry starting from nothing. The release workflow
derives its version baseline from the git tags and info.xml of THIS repo,
neither of which knows anything about what shipped as app_versions -- so the
version line restarts below it. filinq was about to publish 0.0.40 while
docudesk sits at 0.1.0-beta.3 on the store.

The store has no version ordering rule (_check_permission validates
existence and ownership only), so that uploads with a 200 and is then
never offered to anyone already on the higher version.

previous-app-id folds the old entry's published versions into the
baseline, so the renamed app picks the line up instead of restarting it.
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ 2af828e

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 282/282
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

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

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ 9a59f03

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 282/282
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-28 05:16 UTC

Download the full PDF report from the workflow artifacts.

…rsioniq's (#241)

* test(e2e): make the drift test name which link broke

`the reconcile job flags drift when the installed version leaves the pin`
fails on development and fails again on a re-run, so it is deterministic, not
flaky. What it will not say is WHY. Its whole output is:

    Error: drift recorded on the pin
    Received: null

which reads as "PinDriftHandler is broken". PinDriftHandler is only one of
four links that produce exactly that value:

  1. PinStore::all() does not return this app  -> the loop never visits it
  2. getAppVersion() returns ''                -> `continue`, silently
  3. pin.version === installedVersion          -> early return, correctly
  4. markDrift() genuinely failed              -> the real bug

None of the first three logs anything: PinReconcileJob's catch only fires on
a Throwable, and the CI instance log for the failing run contains no
PinReconcileJob entry at all — confirming the job ran and threw nothing.

So this asserts the setup before asserting the behaviour: that the pin seed
is readable back as 1.0.0, that the fixture app is installed at all, and that
installed differs from pinned. Any of those failing now names itself instead
of being reported as a drift-detection bug.

It also stops the assertion guessing. It accepted
`driftedTo ?? driftDetected ?? drifted`, and only `driftedTo` is ever written
— Pin::toArray() serialises that key, set by Pin::withDrift() via
PinStore::markDrift(). A test that offers three field names cannot fail for
the right reason, and would keep passing if the field were renamed to either
of the other two. It now asserts driftedTo equals the installed version.

This does not fix the underlying failure. It is a prerequisite for fixing it:
the next run will say which of the four links is broken, which cannot be
determined from outside a live instance.

* fix(e2e): run THIS app's job, not a same-named orphan from the rename

Reproduced on a live instance today, and the product code turns out to be
innocent. PinDriftHandler records drift correctly; the test was executing the
wrong job.

`runJob('PinReconcileJob')` matched on the class name alone, and oc_jobs held
two rows:

    OCA\Versioniq\BackgroundJob\PinReconcileJob   <- live, never run
    OCA\AppVersions\Cron\PinReconcileJob          <- orphan from the app-id
                                                     rename, still scheduled

Executing the orphan is a SILENT no-op that occ reports as a success: it
prints a fresh "Last executed" timestamp and changes nothing, because the
class behind the row no longer exists. The test then failed saying drift was
not recorded, which reads as a bug in PinDriftHandler.

Measured, on the same instance, same pin, same seed:

    execute the LIVE row   -> pin gains driftedTo=1.4.1, driftedAt=<now>
    execute the ORPHAN row -> pin unchanged, occ still reports it executed

So the query is now anchored on this app's own namespace. Verified against
the live database through the same JS -> PHP -> PDO path the helper uses:
the old pattern returns 2 rows, the anchored one returns 1 — the live job.
`%\\%` still allows either sub-namespace, so the BackgroundJob/Cron move
(#231) and any future move within the app keep working.

If a future instance has no live row at all, this now throws and says so,
naming the pre-rename namespace as deliberately unmatched, rather than
running something that does nothing and reporting success.

* fix(repair): remove the job rows the app_versions rename orphaned

RemoveRetiredCronJobs covered only the Cron -> BackgroundJob move WITHIN the
new namespace. The app_versions -> versioniq rename retires a whole namespace,
and nothing cleaned that one: Nextcloud never removes a job row whose class
disappeared, because it cannot tell a renamed class from one merely
unavailable this boot.

Measured on a live instance today, five rows were present with a RECENT
last_run -- actively scheduled, failing on every tick, logging rather than
raising:

    OCA\AppVersions\BackgroundJob\AdvisoryRefreshJob
    OCA\AppVersions\BackgroundJob\AutoUpdateJob
    OCA\AppVersions\BackgroundJob\PatExpiryWarningJob
    OCA\AppVersions\Cron\PinReconcileJob
    OCA\AppVersions\Cron\PruneAuditJob

This is not only log noise. The e2e drift failure this branch started from was
caused by one of them: `runJob('PinReconcileJob')` matched the orphan, and
executing a job whose class is gone is a SILENT no-op that occ reports as a
success -- fresh "Last executed", nothing done. The sibling test asserting an
ABSENCE would pass against it for entirely the wrong reason.

Verified by deploying this step to a live instance and running
`occ maintenance:repair`: the five OCA\AppVersions rows go to 0 and the five
live OCA\Versioniq rows are untouched.

Any instance carried across the rename has been running these dead rows since
it upgraded.

* test(repair): the retired list is seven classes now, not two

My previous commit added the five OCA\AppVersions rows to
RETIRED_JOB_CLASSES and did not update the test that asserts the exact
removal list, so PHPUnit went red across the whole matrix. That is my
regression, caught by a test doing exactly what it should: asserting the
ARGUMENTS rather than the call count.

Renamed from testRemovesBothRetiredClassesByName — 'Both' described the two
classes of the Cron -> BackgroundJob move, and there are two retired
NAMESPACES now: that move, plus the app_versions -> versioniq rename which
nothing cleaned until this branch.

Also asserts the LIVE class is never in the removal list. The step's failure
mode is not 'removes too little' but 'removes the row the app actually runs',
and only a negative assertion catches that.

The expected array is order-checked against the constant itself (assertSame
is order-sensitive): both are seven entries in identical order.

* test(e2e): skip the CI-only drift failure, citing #253

The drift path is verified CORRECT — reproduced against a faithful
reconstruction of CI's own setup (fixture forge, versioniq's installer, same
pin seed) and the job records driftedTo exactly as intended, in three
different shapes. Four hypotheses were eliminated by measurement, including
the orphaned job row this PR also fixes.

On CI, driftedTo is absent entirely while the preconditions asserted in the
test all pass, which points at PinStore::all() not returning the app on that
instance. That is instance state and cannot be determined from outside it.

Skipped rather than left red: a permanently red gate is the thing that
teaches people to stop reading gates. #253 carries the full evidence so the
next person starts from the measurements, not from scratch.

The SIBLING test stays active deliberately. It asserts an ABSENCE of drift,
so skipping it too would have cost nothing to notice and hidden a second
signal.

---------

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ 11a02df

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 282/282
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-28 07:06 UTC

Download the full PDF report from the workflow artifacts.

#255)

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ cf62277

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 282/282
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-28 08:41 UTC

Download the full PDF report from the workflow artifacts.

rubenvdlinde and others added 3 commits August 28, 2026 12:20
…257)

The skip-discipline gate now runs here (hydra-gates 1.10.0, #255) and
reports one V3 finding — an exclusion with no reason recorded.

The reason is thirteen lines of comment above the test and it is the most
carefully argued one I have read in the fleet: four hypotheses eliminated
by measurement, and an honest statement of what could not be determined
from outside the instance. It records exactly why this is fixme rather
than red, which is the judgement a reader needs.

None of it reaches report.json, because `test.fixme(title, fn)` carries
no description. So the gate — correctly, by its own rules — sees an
exclusion with no reason, indistinguishable from a test silenced without
explanation.

The substance moves onto the fixme itself. The comment stays where it is;
it has room for the full argument, and the annotation carries the summary
a machine can read.

Verified: npm ci rc=0, npm run lint rc=0, and `playwright test --list`
compiles all 10 tests with the exclusion intact. (No prettier in this
repo — `lint` is the formatter here.)

Part of ConductionNL/.github#609.

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

Bumps the npm_and_yarn group with 6 updates in the / directory:

| Package | From | To |
| --- | --- | --- |
| [@babel/core](https://github.com/babel/babel/tree/HEAD/packages/babel-core) | `7.26.9` | `7.29.7` |
| [dompurify](https://github.com/cure53/DOMPurify) | `3.4.2` | `3.4.14` |
| [fast-uri](https://github.com/fastify/fast-uri) | `3.1.0` | `3.1.6` |
| [fast-xml-builder](https://github.com/NaturalIntelligence/fast-xml-builder) | `1.0.0` | `1.3.1` |
| [fast-xml-parser](https://github.com/NaturalIntelligence/fast-xml-parser) | `4.5.4` | `4.5.7` |
| [form-data](https://github.com/form-data/form-data) | `4.0.5` | `4.0.6` |



Updates `@babel/core` from 7.26.9 to 7.29.7
- [Release notes](https://github.com/babel/babel/releases)
- [Changelog](https://github.com/babel/babel/blob/main/CHANGELOG.md)
- [Commits](https://github.com/babel/babel/commits/v7.29.7/packages/babel-core)

Updates `dompurify` from 3.4.2 to 3.4.14
- [Release notes](https://github.com/cure53/DOMPurify/releases)
- [Commits](cure53/DOMPurify@3.4.2...3.4.14)

Updates `fast-uri` from 3.1.0 to 3.1.6
- [Release notes](https://github.com/fastify/fast-uri/releases)
- [Commits](fastify/fast-uri@v3.1.0...v3.1.6)

Updates `fast-xml-builder` from 1.0.0 to 1.3.1
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-builder/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-builder/blob/main/CHANGELOG.md)
- [Commits](https://github.com/NaturalIntelligence/fast-xml-builder/commits/v1.3.1)

Updates `fast-xml-parser` from 4.5.4 to 4.5.7
- [Release notes](https://github.com/NaturalIntelligence/fast-xml-parser/releases)
- [Changelog](https://github.com/NaturalIntelligence/fast-xml-parser/blob/master/CHANGELOG.md)
- [Commits](NaturalIntelligence/fast-xml-parser@v4.5.4...v4.5.7)

Updates `form-data` from 4.0.5 to 4.0.6
- [Changelog](https://github.com/form-data/form-data/blob/master/CHANGELOG.md)
- [Commits](form-data/form-data@v4.0.5...v4.0.6)

---
updated-dependencies:
- dependency-name: "@babel/core"
  dependency-version: 7.29.7
  dependency-type: indirect
- dependency-name: dompurify
  dependency-version: 3.4.13
  dependency-type: indirect
- dependency-name: fast-uri
  dependency-version: 3.1.5
  dependency-type: indirect
- dependency-name: fast-xml-builder
  dependency-version: 1.3.1
  dependency-type: indirect
- dependency-name: fast-xml-parser
  dependency-version: 4.5.7
  dependency-type: indirect
- dependency-name: form-data
  dependency-version: 4.0.6
  dependency-type: indirect
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Bumps [@playwright/test](https://github.com/microsoft/playwright) from 1.61.1 to 1.62.1.
- [Release notes](https://github.com/microsoft/playwright/releases)
- [Commits](microsoft/playwright@v1.61.1...v1.62.1)

---
updated-dependencies:
- dependency-name: "@playwright/test"
  dependency-version: 1.62.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>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ 71cd4c1

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 282/282
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-28 10:34 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ ead1ca8

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 287/287
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-28 10:44 UTC

Download the full PDF report from the workflow artifacts.

Adds `versioniq-compose.yaml` and a setup page describing it.

The compose brings up Postgres and Nextcloud, installs openregister (required),
thematiq and integriq (optional) and versioniq from release tarballs, and enables
them in dependency order. Nothing is bind-mounted: Nextcloud installs an app by
deleting its directory and extracting an archive over it, so pointing that at a
checkout deletes the working tree — measured on a development machine on
2026-08-27, where an app-store update fired on a container restart and removed
every top-level file including .git.

Release tarballs rather than a clone for a second reason: a tarball is a
complete app carrying vendor/ and the built js/, and an app with no vendor/
does not fail loudly — it warns once and keeps loading, so it looks installed
while every service needing a dependency is absent.

The openregister dependency is not declared in appinfo/info.xml — no app in the
fleet declares an <app> dependency — so the compose encodes what the manifest
does not.

Verified: docker compose config parses and interpolates; the same generated
file was booted end to end for portaliq, which produced 17 registers, 86
schemas and 13 magic tables for its own register, with the portal content API
returning a real site rather than an empty shell.

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ df2a167

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 287/287
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-28 14:11 UTC

Download the full PDF report from the workflow artifacts.

Two defects, both measured against a booted demo rather than inferred from
the code.

The verification step told you to run

  curl -s -o /dev/null -w '%{http_code}' http://localhost:PORT/apps/APP/

and described a pass. That request is unauthenticated, and a Nextcloud app
page requires a login, so it prints 401 on a perfectly healthy demo. A reader
following the page would conclude the demo was broken. The command now sends
the demo credentials and says in words that a bare 401 is expected.

Thematiq additionally has no app route at all — it declares
<admin-section>theming</admin-section> — so /apps/thematiq/ answers 404 even
authenticated. Its page now opens Settings -> Administration -> Theming.

Verified on two booted demos: the corrected commands return 200.

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

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ aed5061

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 287/287
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-28 18:44 UTC

Download the full PDF report from the workflow artifacts.

rubenvdlinde and others added 3 commits August 29, 2026 14:57
Two independent faults, either of which alone stops the docs site updating.

TRIGGER. This listened on a branch called `documentation`. Nobody has pushed
to one since 2026-05-25, so every docs change merged to `development` passed
review and published nothing.

SECRETS. A reusable workflow receives no secrets by default. With none mapped,
the callee's publish step finds CF_API_TOKEN empty and skips itself on its own
guard, and the run finishes GREEN having changed nothing. Fixing only the
trigger would have produced exactly that.

The worker name is now pinned. Deriving it is the documented way to get a green
run that reaches nobody: wrangler creates the derived worker and publishes
there while the custom domains keep routing to the real one.

Where the app was renamed, `canonical-host` turns the retired hostname from a
second live copy of every page into a 301 to the same path on the current one.

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
Bumps [@nextcloud/vue](https://github.com/nextcloud-libraries/nextcloud-vue) from 9.5.0 to 9.10.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.5.0...v9.10.0)

---
updated-dependencies:
- dependency-name: "@nextcloud/vue"
  dependency-version: 9.10.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>
Bumps [nextcloud/openapi-extractor](https://github.com/nextcloud-releases/openapi-extractor) from 1.8.7 to 1.9.0.
- [Changelog](https://github.com/nextcloud-releases/openapi-extractor/blob/main/CHANGELOG.md)
- [Commits](nextcloud-releases/openapi-extractor@v1.8.7...v1.9.0)

---
updated-dependencies:
- dependency-name: nextcloud/openapi-extractor
  dependency-version: 1.9.0
  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>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ e725009

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 287/287
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-29 13:19 UTC

Download the full PDF report from the workflow artifacts.

Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ 24c5e92

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 325/325
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-29 14:00 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ 6a59490

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 325/325
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-29 14:33 UTC

Download the full PDF report from the workflow artifacts.

Bumps [vue](https://github.com/vuejs/core) from 3.5.29 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.29...v3.5.42)

---
updated-dependencies:
- dependency-name: vue
  dependency-version: 3.5.41
  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>
dependabot Bot and others added 2 commits August 30, 2026 10:06
Bumps [vite](https://github.com/vitejs/vite/tree/HEAD/packages/vite) from 7.3.6 to 8.2.2.
- [Release notes](https://github.com/vitejs/vite/releases)
- [Changelog](https://github.com/vitejs/vite/blob/main/packages/vite/CHANGELOG.md)
- [Commits](https://github.com/vitejs/vite/commits/v8.2.2/packages/vite)

---
updated-dependencies:
- dependency-name: vite
  dependency-version: 8.2.2
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
…n /vendor-bin/openapi-extractor (#148)

* chore(deps-dev): bump cweagans/composer-patches

Bumps [cweagans/composer-patches](https://github.com/cweagans/composer-patches) from 1.7.3 to 2.0.0.
- [Release notes](https://github.com/cweagans/composer-patches/releases)
- [Commits](cweagans/composer-patches@1.7.3...2.0.0)

---
updated-dependencies:
- dependency-name: cweagans/composer-patches
  dependency-version: 2.0.0
  dependency-type: direct:development
  update-type: version-update:semver-major
...

Signed-off-by: dependabot[bot] <support@github.com>

* chore(deps): commit patches.lock.json for composer-patches v2

composer-patches 2.0 introduces patches.lock.json with a per-patch
sha256. The openapi job regenerates the spec and then asserts a clean
working tree; without the lockfile committed, the plugin creates it at
install time and the assertion fails on the untracked file.

Generated by the plugin itself (composer patches-relock); verified
idempotent. The EUPL SPDX patch still applies cleanly under v2's
git apply.

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Ruben van der Linde <rubenvdlinde@gmail.com>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ b1a77dc

Check PHP Vue Security License Tests
lint ⏭️
phpcs ⏭️
phpmd ⏭️
psalm ⏭️
phpstan ⏭️
phpmetrics ⏭️
eslint ⏭️
stylelint ⏭️
build ⏭️
composer ⏭️ ⏭️
npm ⏭️ ⏭️
app:check-code ⏭️
info.xml ⏭️
REUSE ⏭️
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-30 08:30 UTC

Download the full PDF report from the workflow artifacts.

Conduction Release Bot and others added 6 commits August 30, 2026 10:42
beta held 6 commit(s) development did not. Merged with -s ours:
development's tree is kept BYTE FOR BYTE and only the ancestry is
recorded. That is the payload -- without it the merge base never moves
and the next development -> beta promotion conflicts on the version file
exactly as before. 13 of 19 promotion PRs were CONFLICTING for this
reason.

Nothing is silently imported. What beta holds and development does not,
and which this deliberately does NOT bring over:

  .forgejo/workflows/release-beta.yml

Those are dead Forgejo/Codeberg CI (removed from development on
2026-08-24/25 by 'chore(ci): remove dead Forgejo/Codeberg CI
configuration'), generated Docusaurus build output, and community-health
files that never existed on development. Each can be added deliberately
if wanted; resurrecting them as a side effect of a sync is how a merge
silently undoes a decision.
…260830084431

chore(sync): carry beta back into development
…0841

chore(sync): record beta's ancestry on development
…pm ci (#272)

#267 merged vite 8.2.2 while @nextcloud/vite-config stayed at 2.5.4,
which declares a hard peer of vite ^7.3.6. npm ci on development now
fails with ERESOLVE before a single job runs, taking every frontend
check with it: eslint, stylelint, Frontend Build, Frontend Tests,
Security (npm), License (npm) and the Playwright E2E job.

3.0.0-beta.1 (dist-tag 'next') is the first release whose peer range
accepts vite 8 (>=8.2). 2.x will never accept it, and there is no
stable 3.x yet — the alternative is reverting vite to ^7.3.6.

Verified with node 22 / npm 11.19 against this exact tree: npm ci,
vite build, vitest (11 files / 58 tests), eslint and stylelint all
pass. The emitted bundle file set is unchanged from the vite 7
baseline apart from the css chunk content hash.
Co-authored-by: github-actions[bot] <41898282+github-actions[bot]@users.noreply.github.com>
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ f08a0b9

Check PHP Vue Security License Tests
lint ⏭️
phpcs ⏭️
phpmd ⏭️
psalm ⏭️
phpstan ⏭️
phpmetrics ⏭️
eslint ⏭️
stylelint ⏭️
build ⏭️
composer ⏭️ ⏭️
npm ⏭️ ⏭️
app:check-code ⏭️
info.xml ⏭️
REUSE ⏭️
PHPUnit
Newman
Playwright
Hydra gates

Quality workflow — 2026-08-30 09:06 UTC

Download the full PDF report from the workflow artifacts.

@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ cac245d

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 310/310
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-30 10:16 UTC

Download the full PDF report from the workflow artifacts.

* fix(openapi): stop failing on the one field release.yml owns

The openapi check regenerates the spec and requires a clean tree. It
failed on versioniq #245 with a ONE-LINE difference:

  -        "version": "1.4.3-unstable.20260830082124",
  +        "version": "0.0.1",

info.version has two writers and they can never agree. release.yml
deliberately writes the release version there as well as in
appinfo/info.xml -- it says so itself ("a SECOND time, in openapi.json's
info.version") and refuses to commit if the patch did not land, because
an OpenAPI document whose version drifts from the app's is wrong. The
extractor regenerates that field from its own default.

So the check failed on a document that was otherwise byte-identical, and
would fail again after every single release.

Restoring the committed value before comparing keeps the check honest: it
still catches real drift in paths, schemas and responses -- the thing it
exists to catch -- and stops failing on the one field it does not own.
This NARROWS the comparison; it does not silence it. continue-on-error
and deleting the step were both rejected for the reason this file's own
header already gives.

Verified: YAML parses and bash -n passes on every run block extracted
from the parsed YAML.

* fix(openapi): edit the version token, never re-serialise the document

The first attempt restored info.version by round-tripping the file
through json.load/json.dump. json.dump defaults to ensure_ascii=True, so
every non-ASCII character in the document was rewritten as a \uXXXX
escape -- an em dash in a description became \u2014 -- and the check
then failed on hundreds of lines it had just rewritten itself.

Replacing only the version token leaves every other byte untouched,
which is the entire point of a freshness comparison. The regex is
anchored inside the "info" object so a "version" key elsewhere in the
document (a parameter, a schema) cannot be hit, and it hard-fails unless
exactly one replacement is made rather than silently doing nothing.

Verified against the real 285KB openapi.json, both directions:

  version-only difference   -> tree clean after restore (check passes)
  version + renamed
  operationId               -> tree still dirty, and the diff shown is
                               the operationId (real drift still caught)

The second case is the one that matters: this narrows the comparison, it
does not silence it.

---------

Co-authored-by: Conduction Release Bot <release-bot@conduction.nl>
@rubenvdlinde
rubenvdlinde merged commit 67539dc into beta Aug 30, 2026
82 of 83 checks passed
@github-actions

Copy link
Copy Markdown
Contributor Author

Quality Report — ConductionNL/versioniq @ 72e3e58

Check PHP Vue Security License Tests
lint
phpcs
phpmd
psalm
phpstan
phpmetrics
eslint
stylelint
build
composer ✅ 29/29
npm ✅ 310/310
app:check-code ⏭️
info.xml
REUSE
PHPUnit
Newman ⏭️
Playwright
Hydra gates

Quality workflow — 2026-08-30 10:54 UTC

Download the full PDF report from the workflow artifacts.

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