From 4a28e711aee81de464c63b0b40d84bb5851667b9 Mon Sep 17 00:00:00 2001 From: rubenvdlinde Date: Sat, 25 Jul 2026 12:07:56 +0200 Subject: [PATCH 1/4] ci(quality): --ignore-npm-errors on cyclonedx SBOM step (#70) --- .github/workflows/quality.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 5caac168..57d25e9c 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -1898,7 +1898,12 @@ jobs: # peer/version mismatches in transitive deps, a hard dependency declared # by a lib but deduped away, etc. — which has nothing to do with the SBOM. # The lockfile is the deterministic source of truth for what gets installed. - run: npx @cyclonedx/cyclonedx-npm --package-lock-only --output-file bom-npm.cdx.json --spec-version 1.5 --omit dev + # --ignore-npm-errors: cyclonedx-npm still shells out to `npm ls` internally + # even with --package-lock-only, and aborts on those same benign + # ELSPROBLEMS (e.g. a transitive @vueuse/core pulled by @nextcloud/dialogs + # that mismatches a peer range). The tree quirk does not affect the SBOM, + # so tolerate it rather than red the whole quality run. + run: npx @cyclonedx/cyclonedx-npm --package-lock-only --ignore-npm-errors --output-file bom-npm.cdx.json --spec-version 1.5 --omit dev - name: Merge PHP + npm SBOMs if: ${{ inputs.enable-frontend }} From ef723c18507888454d33c5a826e1392f6720bc66 Mon Sep 17 00:00:00 2001 From: rubenvdlinde Date: Sun, 26 Jul 2026 09:40:16 +0200 Subject: [PATCH 2/4] ci(quality): install app deps before enabling app (phpunit job) (#71) --- .github/workflows/quality.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 57d25e9c..9494a471 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -758,13 +758,20 @@ jobs: php occ app:enable "$name" || echo "::warning::Failed to enable $name, continuing..." done fi - php occ app:enable ${{ inputs.app-name }} chmod -R a+w config - - name: Install app dependencies + # Install the app's own dependencies BEFORE enabling it. Enabling triggers + # install-scope repair steps that autowire services with eager constructors + # (e.g. SaveObject does `new Twig\Environment(...)`); without vendor present + # that fatals with an uncaught \Error (NC core only catches \Exception), + # killing the step. Matches the newman/playwright/journeydoc jobs, which + # already composer-install before enabling the app. + - name: Install app dependencies and enable app run: | cd server/apps/${{ inputs.app-name }} composer install --no-progress --prefer-dist --optimize-autoloader + cd ../../ + php occ app:enable ${{ inputs.app-name }} - name: Validate test infrastructure run: | From 71037419e04fadb1ce1edd90413b754bc0a0b2fe Mon Sep 17 00:00:00 2001 From: rubenvdlinde Date: Sun, 26 Jul 2026 10:00:45 +0200 Subject: [PATCH 3/4] ci(quality): --omit=dev on SBOM npm audit (#72) --- .github/workflows/quality.yml | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 9494a471..6ffaa4f5 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -1949,7 +1949,12 @@ jobs: - name: npm audit if: ${{ inputs.enable-frontend }} - run: npm audit --audit-level=critical + # --omit=dev: gate only on production-dependency criticals. Dev-only + # build tooling (node-gyp/cacache → tar, cyclonedx, babel, …) is never + # shipped in the app bundle, and its frequent advisories would otherwise + # red every run. Matches the dedicated `Security (npm)` job, which + # already runs `--audit-level=critical --omit=dev`. + run: npm audit --audit-level=critical --omit=dev # ── Publish validated SBOM ── # The SBOM is intentionally NOT committed back to the repo. From 22c319d7deef82d4b8d6cdd803202e520f4b6628 Mon Sep 17 00:00:00 2001 From: Conduction Release Bot Date: Sun, 26 Jul 2026 10:13:21 +0200 Subject: [PATCH 4/4] ci(quality): tolerate unavailable npm advisory endpoint in npm audit npm is retiring the audits/quick advisory endpoint; it now intermittently returns 400 ('audit endpoint returned an error' / 'Invalid package tree'), hard-failing both npm-audit steps even on a lockfile that is byte-identical to one that passed days earlier. An unreachable advisory endpoint is an infra outage, not a security finding, so warn-and-continue on those specific endpoint signals while still failing on real advisories (which print a vuln table). Same posture as the SBOM step's --ignore-npm-errors. --- .github/workflows/quality.yml | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/.github/workflows/quality.yml b/.github/workflows/quality.yml index 6ffaa4f5..4cadaf09 100644 --- a/.github/workflows/quality.yml +++ b/.github/workflows/quality.yml @@ -362,7 +362,19 @@ jobs: ;; npm) npm ci --legacy-peer-deps - npm audit --audit-level=critical --omit=dev + # Tolerate an unavailable npm advisory endpoint: npm is retiring + # the audits/quick endpoint and it intermittently 400s ("audit + # endpoint returned an error" / "Invalid package tree"). That is an + # infra outage, not a security finding, and must not hard-fail CI. + # Real advisories (which print a vuln table, not an endpoint error) + # still fail the gate. + out="$(npm audit --audit-level=critical --omit=dev 2>&1)" && rc=0 || rc=$? + echo "$out" + if [ "$rc" -ne 0 ] && printf '%s' "$out" | grep -qiE "audit endpoint returned an error|Invalid package tree|ECONNRESET|ETIMEDOUT|ENOTFOUND|being retired|Service Unavailable"; then + echo "::warning::npm audit skipped — npm advisory endpoint unavailable (external); not a vulnerability." + elif [ "$rc" -ne 0 ]; then + exit "$rc" + fi ;; esac @@ -1952,9 +1964,18 @@ jobs: # --omit=dev: gate only on production-dependency criticals. Dev-only # build tooling (node-gyp/cacache → tar, cyclonedx, babel, …) is never # shipped in the app bundle, and its frequent advisories would otherwise - # red every run. Matches the dedicated `Security (npm)` job, which - # already runs `--audit-level=critical --omit=dev`. - run: npm audit --audit-level=critical --omit=dev + # red every run. Matches the dedicated `Security (npm)` job. + # Also tolerate an unavailable npm advisory endpoint (npm is retiring + # audits/quick; it intermittently 400s) — an infra outage, not a finding. + # Real advisories (a vuln table, not an endpoint error) still fail. + run: | + out="$(npm audit --audit-level=critical --omit=dev 2>&1)" && rc=0 || rc=$? + echo "$out" + if [ "$rc" -ne 0 ] && printf '%s' "$out" | grep -qiE "audit endpoint returned an error|Invalid package tree|ECONNRESET|ETIMEDOUT|ENOTFOUND|being retired|Service Unavailable"; then + echo "::warning::npm audit skipped — npm advisory endpoint unavailable (external); not a vulnerability." + elif [ "$rc" -ne 0 ]; then + exit "$rc" + fi # ── Publish validated SBOM ── # The SBOM is intentionally NOT committed back to the repo.