Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
55 commits
Select commit Hold shift + click to select a range
1605870
fix(l10n): regenerate all 38 browser catalogues, and add the check (#…
rubenvdlinde Aug 27, 2026
6caa14f
chore(release): 0.1.141-unstable.20260827025647 (#754)
github-actions[bot] Aug 27, 2026
2c55aed
ci: run check:l10n-js, so the browser catalogues cannot drift again (…
rubenvdlinde Aug 27, 2026
ffa4bba
fix(deps): development cannot npm install (#762)
rubenvdlinde Aug 27, 2026
2fdf073
perf(ci): one Code Quality run per commit, not two (#770)
rubenvdlinde Aug 27, 2026
61af6df
chore: untrack the build logs that were triggering full CI runs (#771)
rubenvdlinde Aug 27, 2026
9cd3aab
fix(release): name softwarecatalog as this app's previous App Store i…
rubenvdlinde Aug 27, 2026
41899ab
feat(demo): generated demo data for every schema (ADR-111) (#769)
rubenvdlinde Aug 27, 2026
6b79248
chore(deps): hydra-gates 1.10, so the E2E skip-discipline gate can ru…
rubenvdlinde Aug 28, 2026
f188aee
fix(e2e): move the three fixme reasons where the gate can read them (…
rubenvdlinde Aug 28, 2026
5738157
refactor(manifest): the flow pages are an index and a flow (#775)
rubenvdlinde Aug 28, 2026
1242262
chore(release): 0.1.143-unstable.20260828092138 (#781)
github-actions[bot] Aug 28, 2026
485e4a8
feat(walkthrough): show where flows are edited, without asking anyone…
rubenvdlinde Aug 28, 2026
6194ae4
chore(release): 0.1.144-unstable.20260828095409 (#782)
github-actions[bot] Aug 28, 2026
181aaa4
docs: add a local demo environment (#783)
rubenvdlinde Aug 28, 2026
80f8c74
feat(setup): a wizard that offers the demo data this app already ship…
rubenvdlinde Aug 29, 2026
fe5de96
fix(e2e): settle the demo-data decision so the wizard stops masking c…
rubenvdlinde Aug 29, 2026
f813345
chore(deps): @conduction/nextcloud-vue 2.21.0 -> 2.22.1 (#790)
rubenvdlinde Aug 29, 2026
7a6556c
test(e2e): seed the walkthrough marker so the tour cannot intercept c…
rubenvdlinde Aug 29, 2026
4f44f09
chore(release): 0.1.145-unstable.20260829094614 (#791)
github-actions[bot] Aug 29, 2026
4955243
ci(docs): publish from development, and retire the old hostname (#792)
rubenvdlinde Aug 29, 2026
e22eed0
chore(release): 0.1.146-unstable.20260829125943 (#795)
github-actions[bot] Aug 29, 2026
ea37772
chore(deps): @conduction/nextcloud-vue 2.22.1 -> 2.24.1 (#796)
rubenvdlinde Aug 29, 2026
38cd18b
chore(deps): @conduction/nextcloud-vue 2.24.1 -> 2.24.2 (#798)
rubenvdlinde Aug 29, 2026
60139e3
chore(deps-dev): bump stylelint-config-html from 1.1.0 to 2.0.0 (#820)
dependabot[bot] Aug 30, 2026
7f6687c
chore(deps): bump webpack from 5.109.2 to 5.110.1 (#819)
dependabot[bot] Aug 30, 2026
e7e7bdf
chore(deps-dev): bump @vitest/coverage-v8 from 3.2.7 to 4.1.11 (#818)
dependabot[bot] Aug 30, 2026
e3837ad
chore(deps-dev): bump @types/node from 20.19.43 to 26.4.0 (#817)
dependabot[bot] Aug 30, 2026
1dd85dd
chore(deps): bump node-polyfill-webpack-plugin from 4.0.0 to 4.1.0 (#…
dependabot[bot] Aug 30, 2026
e8a9e4a
chore(deps-dev): bump nextcloud/ocp from 34.0.2 to 34.0.3 (#814)
dependabot[bot] Aug 30, 2026
a9db8ef
chore(deps): bump vue-draggable-plus from 0.2.7 to 0.6.1 (#813)
dependabot[bot] Aug 30, 2026
b8f3155
chore(deps-dev): bump typescript from 5.9.3 to 7.0.2 (#812)
dependabot[bot] Aug 30, 2026
a3746a5
chore(deps-dev): bump squizlabs/php_codesniffer from 3.13.6 to 4.0.4 …
dependabot[bot] Aug 30, 2026
306bdbf
chore(deps-dev): bump phpcsstandards/phpcsextra from 1.5.0 to 1.5.1 (…
dependabot[bot] Aug 30, 2026
cea64bf
chore(deps-dev): bump postcss-html from 1.8.1 to 2.0.0 (#809)
dependabot[bot] Aug 30, 2026
1221cd1
chore(deps-dev): bump caniuse-lite from 1.0.30001806 to 1.0.30001810 …
dependabot[bot] Aug 30, 2026
189c756
chore(deps-dev): bump phpstan/phpstan from 2.2.8 to 2.2.9 (#806)
dependabot[bot] Aug 30, 2026
139028f
chore(deps): bump adbario/php-dot-notation from 3.3.0 to 3.5.0 (#805)
dependabot[bot] Aug 30, 2026
e3c1469
chore(deps): bump actions/checkout from 4 to 7 (#804)
dependabot[bot] Aug 30, 2026
8c88a82
chore(deps-dev): bump phpmetrics/phpmetrics from 2.9.1 to 2.11.0 (#803)
dependabot[bot] Aug 30, 2026
15448e2
chore(deps): bump twig/twig from 3.27.0 to 3.28.0 (#801)
dependabot[bot] Aug 30, 2026
84f8ad5
feat(flows): give the flow-detail canvas its sidebar (#789)
rubenvdlinde Aug 30, 2026
42d8326
chore(sync): carry beta back into development
rubenvdlinde Aug 30, 2026
aeb500a
chore(sync): carry beta back into development
rubenvdlinde Aug 30, 2026
0b4c16f
Merge pull request #823 from ConductionNL/sync/beta-to-development-20…
rubenvdlinde Aug 30, 2026
5020800
Merge pull request #824 from ConductionNL/sync/beta-to-development-20…
rubenvdlinde Aug 30, 2026
e2a4c1b
chore(release): 0.1.147-unstable.20260830083652 (#822)
github-actions[bot] Aug 30, 2026
deb9fa7
fix(deps): align dexie on 4.4.5 so only one copy loads per page (#826)
rubenvdlinde Aug 30, 2026
dc76189
fix: null guards on IUser/IGroup, and typescript 6 so eslint can run …
rubenvdlinde Aug 30, 2026
791e8f0
fix(sidebar): render the manifest page's sidebar alongside our own (#…
rubenvdlinde Aug 30, 2026
85aab13
chore(deps): adopt vitest 4 (#834)
rubenvdlinde Aug 30, 2026
6685d2f
style: run Prettier over the sidebar change (#836)
rubenvdlinde Aug 30, 2026
d802a5f
fix(phpstan): guard against a null user, not against false (#828)
rubenvdlinde Aug 30, 2026
06b051b
fix(e2e): target the picker's input, not the wrapper that now shares …
rubenvdlinde Aug 30, 2026
3e60097
fix(e2e): close the .vs__search class in catalog-ratings too (#841)
rubenvdlinde Aug 30, 2026
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
59 changes: 35 additions & 24 deletions .github/workflows/code-quality.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,36 +27,47 @@ on:
# `enable-coverage-guard` was switched on here in the previous commit; without
# this trigger its push-side half would have been dead on arrival.
push:
# An ALLOW-LIST of branch prefixes is a gate with a hole in it, and the
# hole is SILENT: a branch matching nothing gets no CI at all, and its last
# visible status is whatever it inherited — indistinguishable, on every
# dashboard, from a branch that passed.
# DEFAULT BRANCHES ONLY. `pull_request` below carries every other branch.
#
# Two live examples, both found 2026-08-14: `perf/**` was uncovered in
# openconnector, where a merge carrying unresolved conflict markers and 84
# failing tests was pushed and nothing ran; and `feat/**` was uncovered in
# openregister — note the list said `feature/**`, so every branch anyone
# named `feat/...` had been running unchecked.
# This was an allow-list of branch prefixes, and that was a gate with a
# SILENT hole: a branch matching nothing got no CI at all, and its last
# visible status was whatever it inherited — indistinguishable, on every
# dashboard, from a branch that passed. Two live examples, both found
# 2026-08-14: `perf/**` was uncovered in openconnector, where a merge
# carrying unresolved conflict markers and 84 failing tests was pushed and
# nothing ran; and `feat/**` was uncovered in openregister, because the
# list said `feature/**`.
#
# Prefixes are added rather than replaced with `**` because this workflow is
# expensive (PHPUnit matrix, Newman, Playwright). The fast structural checks
# DO run on `**` — see merge-hygiene.yml, added in the same change.
# The comment that stood here said adding prefixes was not the durable fix,
# and that the durable fix was to let the pull_request trigger gate it.
# THIS IS THAT CHANGE.
#
# ⚠️ Adding prefixes is not the durable fix; the next invented one is
# uncovered again. The durable fix is branch protection requiring a PR into
# development, which the pull_request trigger below already gates correctly.
# What forced it now: a push to a branch with an open PR ran the SAME 34
# jobs TWICE on the same commit. `concurrency` cannot dedupe them — the
# group is suffixed by event name deliberately (.github#540: a
# default-branch push carries jobs a PR run does not, and a dispatch must
# not be cancellable by a standing release PR), so the two events sit in
# different lanes BY DESIGN and both run to completion. Measured fleet-wide
# 2026-08-25..27, 659 of 2,106 Code Quality runs were that duplicate — 31%
# of the fleet's most expensive workflow, re-deciding a commit another run
# was already deciding. The account ceiling is 60 concurrent jobs (Team
# plan); the fleet was measured at 53 running with 1,528 jobs queued behind
# them, the oldest run 7 hours old and not yet started.
#
# NO BRANCH LOSES ITS FLOOR. merge-hygiene.yml runs on `'**'` — every
# branch anyone pushes, no prefix list to forget — and it is the check
# `development` actually requires. That is the smoke alarm; this workflow
# is the fire brigade and belongs on the PR. Of 668 feature-branch push
# runs in that window, only NINE were on a branch with no PR run beside
# them.
#
# The default branches STAY: their push runs are not duplicates, they are
# the only carrier of Coverage Baseline Check, SBOM and Features Extract,
# none of which run on a pull_request event.
branches:
- main
- beta
- development
- feature/**
- feat/**
- bugfix/**
- hotfix/**
- perf/**
- refactor/**
- chore/**
- fix/**
pull_request:
branches: [main, beta, development]
# Same family of defect as the missing `push:` above, one step further along:
Expand Down Expand Up @@ -226,7 +237,7 @@ jobs:
# renders the English source inside an otherwise translated form, silently.
# The fleet had 30,459 such strings, so this records the current count and
# fails only when it GROWS — burning it down stays an ordinary PR.
frontend-checks: '["check:manifest", "check:vue-demi", "test:l10n", "format", "check:schema-l10n"]'
frontend-checks: '["check:manifest", "check:vue-demi", "test:l10n", "format", "check:schema-l10n", "check:l10n-js"]'

# ── Coverage ratchet ─────────────────────────────────────────────────
# `enable-coverage-guard` defaults to FALSE, which is why both
Expand Down
88 changes: 25 additions & 63 deletions .github/workflows/documentation.yml
Original file line number Diff line number Diff line change
@@ -1,82 +1,44 @@
name: Documentation

# Publishes the docs site to the Cloudflare Worker that serves it.
#
# TRIGGERS ON `development`, NOT ON A `documentation` BRANCH. This file used to
# listen on a branch called `documentation`; nobody has pushed to one since
# 2026-05-25, so the site simply stopped being rebuilt while every docs change
# merged to development satisfied its review and published nothing.
on:
# `development` is where the work lands. This used to trigger on a
# `documentation` branch that exists but nobody updates — so the workflow
# was green and idle while the live site aged. Measured today:
# softwarecatalog.conduction.nl and stackiq.conduction.nl both still serve
# the pre-rename "SoftwareCatalog" title while docs/docusaurus.config.js
# says 'Stackiq'.
push:
branches: [development]
pull_request:
branches: [development]

jobs:
deploy:
# Permission CEILING for the called documentation workflow, not a grant.
# The callee has three jobs and this block is their UNION, which is what the
# token already resolves to today:
# build contents: read
# deploy contents: write (peaceiris/actions-gh-pages pushes to gh-pages)
# image contents: read, packages: write (buildx push to GHCR)
#
# ⚠️ `packages: write` is load-bearing at RUNTIME, not merely statically:
# the callee's `build-image` input DEFAULTS TO TRUE, so the `image` job
# really does run on a push to `development` and really does push to
# GHCR. Dropping it 403s that push.
#
# It would be required even if that job were disabled, because GitHub
# validates the callee's DECLARED job permissions against this ceiling
# before dispatch — including for jobs an `if:` will skip — so a too-low
# ceiling makes the whole call fail to start rather than run with less.
permissions:
contents: write
packages: write
uses: ConductionNL/.github/.github/workflows/documentation.yml@main
# A reusable workflow receives NO secrets by default, and the
# `permissions:` block above governs the TOKEN, not the secrets. Without
# this block `secrets.CF_API_TOKEN` is empty inside the callee, its
# "Publish to the Cloudflare Worker" step skips itself on its own guard,
# and the run finishes GREEN having written only gh-pages — which nothing
# serves. The live site never changes and no check goes red to say so.
#
# Mapped explicitly rather than `secrets: inherit`, because `inherit`
# hands the callee EVERY secret this repo holds — signing cert and key,
# appstore token, deploy keys — for the sake of two Cloudflare values.
# This way only those two cross the boundary.
#
# The exposure above is the ONLY reason for the explicit mapping. The
# names are the same on both sides: the org secrets really are
# `CF_API_TOKEN` / `CF_ACCOUNT_ID` — the names ConductionNL/.github's own
# deploy-docs.yml reads directly, and the names the callee declares under
# `workflow_call.secrets`.
#
# This block first read `secrets.CLOUDFLARE_API_TOKEN` /
# `secrets.CLOUDFLARE_ACCOUNT_ID`, which are not secrets anywhere in this
# org. Mapping from a name that does not exist is NOT an error — it
# yields an empty string — so the callee's publish step would have skipped
# itself on its own guard and the run would still have finished green.
# Measured on planninq run 32760529026, where that spelling did merge:
# "Publish to the Cloudflare Worker" SKIPPED, the log showing
# `CF_API_TOKEN:` with no value.
# A reusable workflow receives NO secrets by default. Without this block the
# callee's publish step finds CF_API_TOKEN empty, skips itself on its own
# `if:` guard, and the run finishes GREEN having changed nothing -- the
# failure that left the fleet's docs sites on May builds. The names are the
# same on both sides; the org secrets really are CF_API_TOKEN/CF_ACCOUNT_ID.
secrets:
CF_API_TOKEN: ${{ secrets.CF_API_TOKEN }}
CF_ACCOUNT_ID: ${{ secrets.CF_ACCOUNT_ID }}
with:
# `stackiq.conduction.nl` resolves as of 2026-08-23 — attached as a
# second custom domain on the SAME `softwarecatalog-docs` worker that
# serves `softwarecatalog.conduction.nl`. Both hosts answer 200.
# (The comment that used to sit here said the new host answered 000;
# that was true when it was written and is not any more.)
cname: stackiq.conduction.nl

# softwarecatalog.conduction.nl is the retired hostname. It stays in docs-hosts so
# existing links keep resolving, and canonical-host below turns it into a
# 301 rather than a second live copy of every page.
# EVERY host this worker answers on, in FULL: wrangler reconciles the
# worker's triggers against this list, so a host left out is REMOVED and
# goes dark.
docs-hosts: softwarecatalog.conduction.nl,stackiq.conduction.nl

# The worker that ALREADY holds both custom domains. Without this the
# callee derives the name from `cname` — `stackiq-docs` — which does not
# exist. Deploying that would create a SECOND worker while both custom
# domains keep routing to `softwarecatalog-docs`: every deploy green,
# reaching nobody. Renaming the worker is a Cloudflare-side move, not
# something this file can perform.
# The ONE hostname this site is reached on. Every other host in
# docs-hosts answers 301 to the same path here. Before this, both hostnames
# served identical content and the retired name stayed as discoverable
# as the current one.
canonical-host: stackiq.conduction.nl
# PINNED. Deriving the name is how a deploy goes green and reaches
# nobody: wrangler creates the derived worker and publishes there while
# the custom domains keep routing to the real one.
worker-name: softwarecatalog-docs
2 changes: 1 addition & 1 deletion .github/workflows/l10n.yml
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@ jobs:
# Observed fleet-wide n=225: median 0.1 min, max 1.2 min. Bound loosely at 15.
timeout-minutes: 15
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7
- uses: actions/setup-node@v4
with:
node-version: "22"
Expand Down
2 changes: 1 addition & 1 deletion .github/workflows/merge-hygiene.yml
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ jobs:
name: Conflict markers and PHP syntax
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- uses: actions/checkout@v7

# Conflict markers, anywhere in the tree we author. A marker means a merge
# was committed half-finished; every downstream signal from that commit is
Expand Down
9 changes: 9 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,12 @@ concurrency:
group: release-${{ github.ref_name }}
cancel-in-progress: false

# `previous-app-id` is the App Store id this app shipped under before the
# rename. The store keys everything on the id, so `stackiq` is a brand new
# entry starting from nothing -- without this the version line restarts
# BELOW what the app already published as `softwarecatalog`, and the store accepts
# that with a 200 and then never offers it to anyone. Drop the input once
# the `softwarecatalog` entry is retired.
jobs:
unstable:
if: github.ref == 'refs/heads/development'
Expand All @@ -47,6 +53,7 @@ jobs:
with:
release-type: unstable
app-name: stackiq
previous-app-id: softwarecatalog
secrets: inherit

beta:
Expand All @@ -59,6 +66,7 @@ jobs:
with:
release-type: beta
app-name: stackiq
previous-app-id: softwarecatalog
secrets: inherit

stable:
Expand All @@ -71,4 +79,5 @@ jobs:
with:
release-type: stable
app-name: stackiq
previous-app-id: softwarecatalog
secrets: inherit
8 changes: 8 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -78,3 +78,11 @@ tests/e2e/test-results/
.stale/
/.e2e-state/
.phpunit.cache

# Build and test transcripts written at the repo ROOT by local tooling. These
# were tracked, so every local build produced a commit-shaped diff, and every
# such commit triggered the full Code Quality suite — 34 jobs deciding a
# changed log file. Root-anchored on purpose: .claude/skills/*/examples/*.log
# are gate FIXTURES, not artefacts, and must stay tracked.
/*.log
/changed.tsv
2 changes: 1 addition & 1 deletion appinfo/info.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ Vrij en open source onder de EUPL-licentie.

**Ondersteuning:** Voor ondersteuning, neem contact op via support@conduction.nl. Voor een Service Level Agreement (SLA), neem contact op via sales@conduction.nl.
]]></description>
<version>0.1.142-beta.20260820200443</version>
<version>0.1.147-unstable.20260830083652</version>
<licence>EUPL-1.2</licence>
<author mail="info@conduction.nl" homepage="https://www.conduction.nl/">Conduction</author>
<namespace>Stackiq</namespace>
Expand Down
3 changes: 3 additions & 0 deletions appinfo/routes.php
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@
return [
'routes' => [
// Dashboard routes
// First-time setup wizard (ADR-042) - the standard CnSetupWizard contract.
['name' => 'setup#status', 'url' => '/api/setup/status', 'verb' => 'GET'],
['name' => 'setup#runAction', 'url' => '/api/setup/action/{actionId}', 'verb' => 'POST', 'requirements' => ['actionId' => '[a-z0-9\\-]+']],
['name' => 'dashboard#page', 'url' => '/', 'verb' => 'GET'],
['name' => 'dashboard#index', 'url' => '/api/dashboard', 'verb' => 'GET'],

Expand Down
2 changes: 1 addition & 1 deletion composer.json
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
"phpstan/phpstan": "^2.0",
"phpunit/phpunit": "^10.5",
"roave/security-advisories": "dev-latest",
"squizlabs/php_codesniffer": "^3.9",
"squizlabs/php_codesniffer": "^4.0",
"vimeo/psalm": "^5.26"
},
"config": {
Expand Down
Loading
Loading