Files
certctl/scripts/ci-guards/L-1-bulk-action-loop.sh
shankar0123 1caedd5fd3 ci-pipeline-cleanup Phase 1: extract 20 regression guards to scripts/ci-guards/
Bundle: ci-pipeline-cleanup, Phase 1.

Pure relocation — no behavior change. Each guard's bash logic is
byte-identical to the prior inline version; the only changes are:
(a) the guard becomes a sibling script under scripts/ci-guards/<id>.sh,
(b) ci.yml's per-guard step is replaced by a single loop step that
iterates all scripts.

20 scripts extracted (alphabetized):
  B-1-orphan-crud.sh, D-1-D-2-statusbadge-phantom.sh,
  G-1-jwt-auth-literal.sh, G-2-api-key-hash-json.sh,
  G-3-env-docs-drift.sh, H-001-bare-from.sh, H-009-readme-jwt.sh,
  L-001-insecure-skip-verify.sh, L-1-bulk-action-loop.sh,
  M-012-no-root-user.sh, P-1-documented-orphan-fns.sh,
  S-1-hardcoded-source-counts.sh, S-2-strings-contains-err.sh,
  T-1-frontend-page-coverage.sh, U-2-plaintext-healthcheck.sh,
  U-3-migration-mount.sh, bundle-8-L-015-target-blank-rel-noopener.sh,
  bundle-8-L-019-dangerously-set-inner-html.sh,
  bundle-8-M-009-bare-usemutation.sh, test-naming-convention.sh

Plus scripts/ci-guards/README.md documenting the contract:
- Each script must exit 0 on clean repo, non-zero with ::error::
  prefix on regression
- Runnable from repo root via 'bash scripts/ci-guards/<id>.sh'
- Adding a new guard: drop a new <id>.sh; CI auto-picks it up

ci.yml dropped 1488 → 557 lines (-931, -63%).

Single CI loop step now collects ALL guard failures before failing
the build instead of fail-fast — UX win for regressions that hit
two guards at once.

Two guards (QA-doc Part-count + seed-count, ci.yml lines 868-917)
deliberately NOT extracted — they move to 'make verify-docs' in
Phase 11 because they protect docs-the-operator-reads, not the
product itself.

Verification (sandbox):
- All 20 scripts pass against HEAD (chmod +x; for g in scripts/ci-guards/*.sh; do bash $g; done)
- New ci.yml YAML-parses cleanly
- Job boundaries preserved: go-build-and-test, frontend-build,
  helm-lint, deploy-vendor-e2e, deploy-vendor-e2e-windows
- Loop step appears twice (once at end of go-build-and-test, once
  at end of frontend-build) so both jobs continue running their
  set of guards
2026-04-30 20:36:26 +00:00

47 lines
2.0 KiB
Bash
Executable File
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
#!/usr/bin/env bash
# scripts/ci-guards/L-1-bulk-action-loop.sh
#
# L-1 master closed cat-l-fa0c1ac07ab5 (bulk-renew loop) and
# cat-l-8a1fb258a38a (bulk-reassign loop) by adding server-side
# bulk endpoints (POST /api/v1/certificates/bulk-renew and
# POST /api/v1/certificates/bulk-reassign) that the GUI calls
# in a single round-trip. Pre-L-1 the GUI looped per-cert
# HTTP calls — 100 selected certs = 100 round-trips × ~50200ms
# each = a 520-second wedge during which the operator stares
# at a progress bar.
#
# This script grep-fails the build if either loop shape reappears
# in CertificatesPage.tsx. Patterns catch the actual pre-L-1
# shapes:
# - `for (const id of ids) { await triggerRenewal(id) }`
# - `for (const id of ids) { await updateCertificate(id, { owner_id }) }`
# - `for (let i = 0; i < ids.length; i++) { await triggerRenewal(ids[i]) }`
#
# Allowed: comment lines explaining the pre-L-1 pattern in the
# docblock above each handler. Test files (_test.tsx) exempt
# so negative-pattern tests can keep working.
#
# See coverage-gap-audit-2026-04-24-v5/unified-audit.md
# cat-l-fa0c1ac07ab5 and cat-l-8a1fb258a38a for closure
# rationale, or web/src/api/client.ts::bulkRenewCertificates
# / bulkReassignCertificates for the canonical call path.
set -e
BAD_LOOP=$(grep -nE 'for[[:space:]]*\(' web/src/pages/CertificatesPage.tsx 2>/dev/null \
| grep -E 'await[[:space:]]+(triggerRenewal|updateCertificate)\(' \
| grep -v '\.test\.' \
| grep -vE '^\s*[^:]+:[0-9]+:\s*//' \
|| true)
if [ -n "$BAD_LOOP" ]; then
echo "::error::L-1 regression: client-side bulk-action loop reappeared in CertificatesPage.tsx:"
echo "$BAD_LOOP"
echo ""
echo "Use bulkRenewCertificates({ certificate_ids: [...] }) or"
echo "bulkReassignCertificates({ certificate_ids: [...], owner_id, team_id? })"
echo "instead of looping per-item HTTP calls. See"
echo "coverage-gap-audit-2026-04-24-v5/unified-audit.md cat-l-* for rationale."
exit 1
fi
echo "L-1 bulk-action-loop: clean."