Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
49 changes: 33 additions & 16 deletions .github/scripts/fop-local-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ usage() {
cat <<'EOF'
Usage: .github/scripts/fop-local-ci.sh [--profile pr|full|cd] [--dry-run] [--post-status] [--background]

Runs ParkHub-PHP's local-first CI through fop's build queue. The optional
Runs ParkHub-PHP's local-first CI through the Nido/fop build queue. The optional
--background flag runs the gate in a detached subshell, logs to
.fop/reports/local-ci-<profile>-<sha>-bg.log, and returns immediately.
Combine with --post-status for fire-and-forget full runs that publish their
Expand Down Expand Up @@ -34,7 +34,9 @@ Environment overrides:
FOP_LOCAL_CI_DIFF_PATHS newline-delimited diff path override for
contract tests and explicit local reruns.
FOP_LOCAL_CI_BG_LOG_DIR background log directory override.
FOP_LOCAL_CI_DIRECT 1 = bypass the `fop build` queue wrapper and
FOP_LOCAL_CI_QUEUE_BIN queue wrapper binary. Defaults to `nido` when it
supports `build`, otherwise `fop`.
FOP_LOCAL_CI_DIRECT 1 = bypass the queue wrapper and
run each step directly in the current shell.
Use only for the bootstrap chicken-and-egg
run that introduces this script, or when
Expand Down Expand Up @@ -108,6 +110,19 @@ fi
repo_root="$(git rev-parse --show-toplevel)"
cd "$repo_root"

queue_bin="${FOP_LOCAL_CI_QUEUE_BIN:-}"
if [[ -z "$queue_bin" ]]; then
supports_queue_build() {
command -v "$1" >/dev/null 2>&1 && "$1" build --help >/dev/null 2>&1
}

if supports_queue_build nido; then
queue_bin="nido"
else
queue_bin="fop"
fi
fi

sha="$(git rev-parse HEAD)"
context="fop/local-ci/${profile}"
report_dir="$repo_root/.fop/reports"
Expand Down Expand Up @@ -382,8 +397,9 @@ write_report() {
EOF
}

# All non-trivial work goes through `fop build --backend local` so the
# fop queue can serialize concurrent runs and apply the OOM cap.
# All non-trivial work goes through the local queue wrapper (`nido build`
# on current workstations, `fop build` on older hosts) so concurrent runs
# are serialized and the OOM cap is applied.
#
# `interactive-small` shrinks the per-step memory request to ~1-2 GiB
# instead of the 6 GiB default. PHP/Composer/Pint/PHPStan/Vitest steps
Expand All @@ -404,32 +420,32 @@ run_fop_step() {

set +e
PARKHUB_FOP_STEP_MARKER="$marker" \
fop build --backend local --resource-profile "$resource_profile" . --preset custom -- \
"$queue_bin" build --backend local --resource-profile "$resource_profile" . --preset custom -- \
bash -euo pipefail -c "$wrapped_command" 2>&1 | tee "$log_file"
local status=${PIPESTATUS[0]}
set -e

if ! grep -Fq "$marker" "$log_file"; then
echo "ERROR: fop build reported success but the inner step completion marker was missing." >&2
echo "This usually means the wrapped command exited before completion or fop masked its status." >&2
echo "ERROR: ${queue_bin} build reported success but the inner step completion marker was missing." >&2
echo "This usually means the wrapped command exited before completion or ${queue_bin} masked its status." >&2
rm -f "$log_file"
return 1
fi

if [[ "$status" -ne 0 ]]; then
echo "WARN: fop build exited ${status} after the wrapped step completed; continuing because the completion marker was present." >&2
echo "This can happen when fop's compact summary classifier flags advisory-only output after the command already handled it." >&2
echo "WARN: ${queue_bin} build exited ${status} after the wrapped step completed; continuing because the completion marker was present." >&2
echo "This can happen when the active queue wrapper flags advisory-only output after the command already handled it." >&2
fi

rm -f "$log_file"
}

# Setting FOP_LOCAL_CI_DIRECT=1 bypasses the fop queue wrapper and
# Setting FOP_LOCAL_CI_DIRECT=1 bypasses the queue wrapper and
# runs each step directly in the current shell. Use this for the
# bootstrap chicken-and-egg run that introduces this script (the queue
# would refuse capacity if a sibling tab already holds the parallelism
# slot), or when running outside fop entirely. Operators must still
# guarantee local memory headroom themselves in that mode.
# slot), or when running without the active queue wrapper. Operators
# must still guarantee local memory headroom themselves in that mode.
run_step() {
local name="$1"
local command="$2"
Expand All @@ -438,10 +454,11 @@ run_step() {
printf 'DRY-RUN: %s\n' "$command"
return 0
fi
if [[ "${FOP_LOCAL_CI_DIRECT:-0}" == "1" ]] || ! command -v fop >/dev/null 2>&1; then
# Direct mode (no fop queue): explicit opt-in OR fop binary not on
if [[ "${FOP_LOCAL_CI_DIRECT:-0}" == "1" ]] || ! command -v "$queue_bin" >/dev/null 2>&1; then
# Direct mode (no queue wrapper): explicit opt-in OR queue binary not on
# PATH (GitHub Actions runners, fresh contributor boxes). The kernel
# + earlyoom handle resource pressure when fop isn't available.
# + earlyoom handle resource pressure when the active wrapper is not
# available.
bash -euo pipefail -c "$command"
return 0
fi
Expand All @@ -456,7 +473,7 @@ run_step_heavy() {
printf 'DRY-RUN: %s\n' "$command"
return 0
fi
if [[ "${FOP_LOCAL_CI_DIRECT:-0}" == "1" ]] || ! command -v fop >/dev/null 2>&1; then
if [[ "${FOP_LOCAL_CI_DIRECT:-0}" == "1" ]] || ! command -v "$queue_bin" >/dev/null 2>&1; then
bash -euo pipefail -c "$command"
return 0
fi
Expand Down
31 changes: 31 additions & 0 deletions .nido/local-ci.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# ParkHub PHP local CI entrypoints for Nido-first tabs.

[[gates]]
name = "legal-docs"

[[gates.steps]]
name = "legal-readiness-wording"
command = "scripts/tests/test-legal-readiness-wording.sh"
timeout_secs = 60
allow_failure = false

[[gates.steps]]
name = "legal-module-openapi-contract"
command = "scripts/tests/test-legal-openapi-contract.sh"
timeout_secs = 60
allow_failure = false

[[gates.steps]]
name = "working-tree-whitespace"
command = "git diff --check"
timeout_secs = 60
allow_failure = false

[[gates]]
name = "pr"

[[gates.steps]]
name = "parkhub-pr-local-ci"
command = "NO_COLOR=true .github/scripts/fop-local-ci.sh --profile pr --post-status"
timeout_secs = 7200
allow_failure = false
2 changes: 1 addition & 1 deletion COMPLIANCE-REPORT.md
Original file line number Diff line number Diff line change
Expand Up @@ -383,7 +383,7 @@ This is the standard approach recommended by German DPAs.

### No new files created.

All existing templates are legally sound for their purpose as operator-customizable templates. The project correctly disclaims that templates do not constitute legal advice.
All existing templates are structured as operator-customizable starting points with explicit disclaimers. The project correctly states that templates do not constitute legal advice.

---

Expand Down
4 changes: 2 additions & 2 deletions Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -19,12 +19,12 @@
# Mirrored node:22-slim — pinned to the registry digest, NOT Docker Hub.
#
# NODE_BASE / WOLFI_BASE are parameterized so cloud CI (GitHub Actions) can
# pass --build-arg NODE_BASE=docker.io/library/node:22-slim@sha256:868499d5...
# pass --build-arg NODE_BASE=docker.io/library/node:22-slim@sha256:689c1104...
# and --build-arg WOLFI_BASE=cgr.dev/chainguard/wolfi-base@sha256:4973aa3c2ccbe13fe2049aab539b0ab342ec584bd5b54a269d55d4891091c639 while
# local + gitea-runner builds default to the LAN mirror. Same images either
# way, just different ingress to them.
# ---------------------------------------------------------------------------
ARG NODE_BASE=192.168.178.250:5000/node:22-slim@sha256:868499d55378719bffa87b0ed1f099591823c029b543043c09c2483468e93201
ARG NODE_BASE=192.168.178.250:5000/node:22-slim@sha256:689c11043dad91472750cd824c97dd5e2318e9dd6f954e492fe7af0135d33ceb
ARG WOLFI_BASE=192.168.178.250:5000/wolfi-base@sha256:4973aa3c2ccbe13fe2049aab539b0ab342ec584bd5b54a269d55d4891091c639

FROM ${NODE_BASE} AS frontend
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@
</tr>
</table>

> Live demo: <a href="https://parkhub-php-demo.onrender.com">parkhub-php-demo.onrender.com</a> · drücke <kbd>⌘K</kbd> / <kbd>Ctrl</kbd>+<kbd>K</kbd> für die Command-Palette · <kbd>?</kbd> blendet das Help-Overlay ein.

Check warning on line 59 in README.md

View workflow job for this annotation

GitHub Actions / Typos (advisory)

"ein" should be "in".

---

Expand All @@ -68,7 +68,7 @@
| **Themes** | OKLCH tokens across `marble_light`, `marble_dark`, `void`; self-hosted Inter-Variable keeps the LCP budget green. |
| **Command Palette** | cmdk-powered, mounted globally, reachable from every route with `Cmd+K` / `Ctrl+K`. |
| **Onboarding** | 3-step `/tour` wizard (Privacy -> Toggles -> Trust) guides first-time users before the Laravel app shell mounts. |
| **Accessibility** | axe-core runs in CI on the v5 surfaces; keyboard-only nav verified for the full shell + Assistent panel. |

Check warning on line 71 in README.md

View workflow job for this annotation

GitHub Actions / Typos (advisory)

"Assistent" should be "Assistant".
| **Mobile** | Playwright now ships a `mobile-chrome` (Pixel 5) project so v5 specs can opt into mobile viewports on CI. |

Live demo: <https://parkhub-php-demo.onrender.com>.
Expand Down Expand Up @@ -381,6 +381,8 @@

**GDPR** (EU) | **DSGVO** (DE) | **TTDSG** (DE) | **DDG** (DE) | **BDSG** (DE) | **NIS2** (EU) | **CCPA** (US) | **UK GDPR** | **nDSG** (CH)

The Nido/fop legal catalog service (current CLI entrypoint: `fop legal catalog --json`; `nido legal` is not exposed by the installed Nido CLI yet) is reference-only and does not replace attorney review, citation verification, deployment-specific configuration review, human signoff, or final legal judgment.

All legal documents are provided as **operator-customizable templates** -- not binding legal texts and not legal advice.

### Operator Go-Live Checklist
Expand Down
Loading
Loading