Skip to content
Open
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
6 changes: 3 additions & 3 deletions .gitea/workflows/accessibility-insights.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,8 @@ name: Accessibility Insights
# Gitea runner_act resolves `github.com` action refs natively when the
# runner has internet egress; mirror to Gitea if air-gapped.
#
# Soft-fail (continue-on-error: true) for the first month while we tune
# the static-site-dir / url config and triage IGT-only findings.
# Blocking accessibility gate for WCAG drift. Tune intentional exceptions in
# the test/config layer rather than hiding failures with a permissive marker.
#
# Pattern lifted from fop-web-ui/.gitea/workflows/accessibility-insights.yaml.

Expand Down Expand Up @@ -52,7 +52,7 @@ jobs:
image: 192.168.178.250:5000/gitea/runner-images@sha256:056f41b214d06e42289a7b2918950e46e9394e855ca056c88b8131a5f0761557
options: --add-host=gitea.test:192.168.178.233
timeout-minutes: 30
continue-on-error: true # Soft-fail for first month — IGT findings still triaging.
continue-on-error: false # Blocking WCAG FastPass + needs-review gate.
defaults:
run:
working-directory: parkhub-web
Expand Down
2 changes: 1 addition & 1 deletion .gitea/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -424,7 +424,7 @@ jobs:
name: Cosign verify (advisory)
runs-on: ubuntu-latest
timeout-minutes: 10
continue-on-error: true
continue-on-error: false
permissions:
contents: read # read-only — verifies a remote signature
packages: read # pull manifest from GHCR
Expand Down
8 changes: 4 additions & 4 deletions .gitea/workflows/dependabot-local-ci-bridge.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -68,11 +68,11 @@ jobs:

- name: Audit root npm dependencies
run: npm audit --package-lock-only --omit=dev --audit-level=high
continue-on-error: true
continue-on-error: false

- name: Audit Astro npm dependencies
run: npm audit --prefix parkhub-web --package-lock-only --omit=dev --audit-level=high
continue-on-error: true
continue-on-error: false

# --- Secret scan ---
- name: Install gitleaks
Expand Down Expand Up @@ -106,7 +106,7 @@ jobs:
osv-scanner --version

- name: OSV-Scanner (composer + npm lockfiles)
continue-on-error: true
continue-on-error: false
run: |
set -euo pipefail
osv-scanner scan source \
Expand All @@ -119,7 +119,7 @@ jobs:
# --- Typos (advisory) ---
# TODO(gitea-mirror): No mirror at https://192.168.178.233/crate-ci/typos yet.
- name: Run typos
continue-on-error: true
continue-on-error: false
uses: crate-ci/typos@cf5f1c29a8ac336af8568821ec41919923b05a83 # v1.45.1

# --- Post fop/local-ci/pr commit status ---
Expand Down
2 changes: 1 addition & 1 deletion .gitea/workflows/docker-publish.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,7 @@ jobs:

- name: Scan image with Trivy
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
continue-on-error: true
continue-on-error: false
with:
image-ref: ${{ env.REGISTRY }}/${{ env.IMAGE_NAME }}:scan
format: table
Expand Down
6 changes: 3 additions & 3 deletions .gitea/workflows/infection.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ jobs:
name: infection-php sweep
runs-on: ubuntu-latest
timeout-minutes: 45
# Soft job — mutation score is informational during the baseline
# phase. Do NOT gate merges on this; watch the nightly trend instead.
continue-on-error: true
# Scheduled/manual mutation gate. This workflow is not PR-triggered, so it
# does not gate ordinary merges; failures intentionally mark the run red.
continue-on-error: false
steps:
- uses: https://192.168.178.233/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

Expand Down
4 changes: 2 additions & 2 deletions .gitea/workflows/lost-pixel.yaml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
name: Lost Pixel
# Whole-page + Storybook visual regression for parkhub-web (Astro + React).
# Mirrors the fop-web-ui pattern — soft-fail, diffs uploaded as artefacts.
# Mirrors the fop-web-ui pattern, with diffs uploaded as artifacts.
# Run on push/main and manual dispatch only; PR runs are too slow for the
# merge train (each shot is ~3-5s and we cover 8 routes + every Storybook
# story).
Expand Down Expand Up @@ -40,7 +40,7 @@ jobs:
image: 192.168.178.250:5000/gitea/runner-images@sha256:056f41b214d06e42289a7b2918950e46e9394e855ca056c88b8131a5f0761557
options: --add-host=gitea.test:192.168.178.233
timeout-minutes: 30
continue-on-error: true # Diffs surface as artefacts, never block.
continue-on-error: false # Diffs mark the enabled run red and upload artifacts.
# Gated until lostpixel.config.ts lands at repo root and the
# lost-pixel devDep + baseline snapshots are committed (T-22XX
# follow-up). Without the config, `npx lost-pixel` exits with a
Expand Down
12 changes: 5 additions & 7 deletions .gitea/workflows/schemathesis.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -29,11 +29,9 @@ jobs:
name: Fuzz OpenAPI contract
runs-on: ubuntu-latest
timeout-minutes: 20
# Soft job — schemathesis surfaces contract drift and 500s that are
# legal-by-spec. During the baseline pass we expect violations; the
# workflow must still complete and upload its report so we can
# triage follow-up tasks off the nightly run.
continue-on-error: true
# Blocking contract fuzzing for OpenAPI changes. Failure reports are still
# uploaded for triage, but API drift should mark this run red.
continue-on-error: false
steps:
- uses: https://192.168.178.233/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6
# TODO(gitea-mirror): No mirror at https://192.168.178.233/shivammathur/setup-php yet.
Expand Down Expand Up @@ -101,7 +99,7 @@ jobs:
./scripts/ci/wait-for-url.sh http://127.0.0.1:8000/api/v1/health/live 30

- name: Obtain auth token (best-effort)
continue-on-error: true
continue-on-error: false
run: |
# Best-effort: grab a Sanctum token so authenticated endpoints
# get exercised too. If login fails (demo seeder shape change,
Expand All @@ -120,7 +118,7 @@ jobs:
fi

- name: Run schemathesis
continue-on-error: true
continue-on-error: false
run: |
extra_args=()
if [ -n "${SCHEMATHESIS_AUTH_HEADER:-}" ]; then
Expand Down
4 changes: 2 additions & 2 deletions .gitea/workflows/scorecard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ jobs:

- name: Run Scorecard
uses: ossf/scorecard-action@4eaacf0543bb3f2c246792bd56e8cdeffafb205a # v2.4.3
continue-on-error: true
continue-on-error: false
with:
results_file: scorecard-results.sarif
results_format: sarif
Expand All @@ -59,4 +59,4 @@ jobs:
else
echo "Scorecard CLI not available in PATH; SARIF artifact uploaded above."
fi
continue-on-error: true
continue-on-error: false
27 changes: 13 additions & 14 deletions .gitea/workflows/security.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -64,11 +64,11 @@ jobs:

- name: Audit root npm dependencies
run: npm audit --package-lock-only --omit=dev --audit-level=high
continue-on-error: true
continue-on-error: false

- name: Audit Astro npm dependencies
run: npm audit --prefix parkhub-web --package-lock-only --omit=dev --audit-level=high
continue-on-error: true
continue-on-error: false

trivy-fs:
name: Trivy Filesystem Scan
Expand All @@ -83,7 +83,7 @@ jobs:

- name: Run Trivy filesystem scan
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
continue-on-error: true
continue-on-error: false
with:
scan-type: fs
scan-ref: .
Expand Down Expand Up @@ -141,12 +141,11 @@ jobs:
fi

zizmor:
name: Zizmor (GHA SAST, audit-mode)
name: Zizmor (GHA SAST)
runs-on: ubuntu-latest
timeout-minutes: 10
# Audit-mode: surface findings as informational; do NOT fail the gate yet.
# Promote findings to errors once the workflow inventory has been triaged.
continue-on-error: true
# Blocking workflow SAST for mirrored CI.
continue-on-error: false
permissions:
contents: read # read-only — zizmor only needs to parse workflow YAMLs
env:
Expand All @@ -171,13 +170,13 @@ jobs:
set -euo pipefail
# auditor persona surfaces low-severity findings; --no-online-audits
# avoids GitHub API rate-limit issues when running from Gitea.
zizmor --persona=auditor --no-online-audits .github/workflows/ .gitea/workflows/ || true
zizmor --persona=auditor --no-online-audits .github/workflows/ .gitea/workflows/

osv-scanner:
name: OSV-Scanner (supply-chain)
runs-on: ubuntu-latest
timeout-minutes: 15
continue-on-error: true
continue-on-error: false
permissions:
contents: read # read-only — only parses lockfiles
env:
Expand All @@ -198,14 +197,14 @@ jobs:
- name: Run osv-scanner
run: |
set -euo pipefail
osv-scanner scan source --recursive --no-config . || true
osv-scanner scan source --recursive --no-config .

grype:
name: Grype (vuln scan, defense-in-depth)
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 15
continue-on-error: true
continue-on-error: false
permissions:
contents: read # read-only — Grype scans the filesystem
env:
Expand All @@ -227,7 +226,7 @@ jobs:
- name: Run grype
run: |
set -euo pipefail
grype dir:. --fail-on critical || true
grype dir:. --fail-on critical

trivy-image:
# SOTA-2026 image scanning — Trivy (Apache-2.0) + Grype (Apache-2.0).
Expand All @@ -237,7 +236,7 @@ jobs:
if: github.event_name != 'pull_request'
runs-on: ubuntu-latest
timeout-minutes: 25
continue-on-error: true
continue-on-error: false
permissions:
contents: read # checkout for .trivyignore
packages: read # pull image from GHCR
Expand All @@ -259,7 +258,7 @@ jobs:

- name: Run Trivy image scan
uses: aquasecurity/trivy-action@ed142fd0673e97e23eac54620cfb913e5ce36c25 # v0.36.0
continue-on-error: true
continue-on-error: false
with:
image-ref: ${{ env.IMAGE_REF }}
scanners: vuln,misconfig,secret
Expand Down
7 changes: 3 additions & 4 deletions .gitea/workflows/unlighthouse.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -4,9 +4,8 @@ name: Unlighthouse
# gating) by walking every discovered route from a single seed URL and
# surfacing long-tail regressions.
#
# Too slow for per-PR CI (~10-15 min on the full site) — daily cron + manual
# dispatch. Soft-fail because the budgets in unlighthouse.config.ts are
# aspirational until long-tail routes get tuned.
# Too slow for per-PR CI (~10-15 min on the full site), so it runs on daily
# cron + manual dispatch. Budget drift intentionally marks those runs red.
#
# License: unlighthouse is MIT (https://github.com/harlan-zw/unlighthouse).
# Pattern lifted from fop-web-ui/.gitea/workflows/unlighthouse.yaml.
Expand Down Expand Up @@ -42,7 +41,7 @@ jobs:
image: 192.168.178.250:5000/gitea/runner-images@sha256:056f41b214d06e42289a7b2918950e46e9394e855ca056c88b8131a5f0761557
options: --add-host=gitea.test:192.168.178.233
timeout-minutes: 45
continue-on-error: true # Soft-fail — long-tail budgets still tuning.
continue-on-error: false # Blocking whole-site performance budget gate.
steps:
- uses: https://192.168.178.233/actions/checkout@de0fac2e4500dabe0009e67214ff5f5447ce83dd # v6

Expand Down
7 changes: 4 additions & 3 deletions .gitea/workflows/visual-regression.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@ name: Visual Regression
# GitHub-hosted runners render with slight anti-aliasing / font-hinting
# differences from local baselines, which made the per-PR gate noisy
# without providing matching merge-blocking value (the job was already
# `continue-on-error: true`).
# `continue-on-error: false`).
#
# Run manually via `workflow_dispatch` when intentionally rebasing
# baselines.
Expand All @@ -35,8 +35,9 @@ jobs:
name: Playwright toHaveScreenshot
runs-on: ubuntu-latest
timeout-minutes: 15
# Soft-fail: diffs surface as downloadable artifacts but don't block merge.
continue-on-error: true
# Scheduled/manual visual gate. Diffs mark this run red and are also
# uploaded as artifacts for baseline triage.
continue-on-error: false

steps:
- name: Checkout
Expand Down
16 changes: 8 additions & 8 deletions .github/actions/dependency-review/action.yml
Original file line number Diff line number Diff line change
Expand Up @@ -13,8 +13,8 @@ runs:
steps:
- name: Review dependencies
uses: actions/dependency-review-action@a1d282b36b6f3519aa1f3fc636f609c47dddb294 # v4 (repo allow-listed SHA)
# Advisory until GitHub Dependency Graph is enabled for this repo.
continue-on-error: true
# Blocking release supply-chain gate.
continue-on-error: false
with:
fail-on-severity: high
# Canonical SPDX deny-list — single source of truth.
Expand All @@ -25,10 +25,10 @@ runs:
# model used by Sentry, MariaDB, etc. NOT the same as `BSL-1.0`
# (Boost Software License, which is permissive — DON'T add it).
# - SSPL-1.0: Server Side Public License (Elastic, MongoDB current).
# - FSL-1.0-ALv2/-MIT, FSL-1.1-MIT: Functional Source License family
# (Sentry, BoxyHQ, Discord) — Apache/MIT future-grant model that
# today behaves as anti-cloud.
# - Functional Source License variants are still banned by project
# policy, but GitHub's dependency-review-action currently rejects
# those license identifiers in deny-licenses. Keep them out of this
# action input and handle any FSL introduction during legal review.
# Project policy is "MIT / Apache-2.0 / BSD / ISC only"; this list is
# drift protection for new deps (gate is advisory via continue-on-error
# until GitHub Dependency Graph is enabled).
deny-licenses: GPL-2.0, GPL-3.0, AGPL-1.0, AGPL-3.0, AGPL-3.0-or-later, BUSL-1.1, SSPL-1.0, FSL-1.0-ALv2, FSL-1.0-MIT, FSL-1.1-MIT
# blocking drift protection for new deps.
deny-licenses: GPL-2.0, GPL-3.0, AGPL-1.0, AGPL-3.0, AGPL-3.0-or-later, BUSL-1.1, SSPL-1.0
14 changes: 9 additions & 5 deletions .github/scripts/fop-local-ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,11 @@ post_commit_status "pending" "fop local ${profile} running"

run_direct "working tree whitespace" "git diff --check"
run_direct "ui polish contract" "scripts/tests/test-ui-polish-contract.sh"
if (( diff_touch_workflows || diff_touch_image )) || [[ "$profile" == "cd" || "${FOP_LOCAL_CI_RUN_LINTERS:-}" == "1" ]]; then
run_direct "release supply-chain policy" "bash scripts/check-release-supply-chain-policy.sh"
else
Comment on lines +523 to +525
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

P1 Badge Guard local gate against missing PyYAML dependency

This new mandatory run_direct invocation makes the release policy check part of the default local PR gate, but scripts/check-release-supply-chain-policy.sh hard-fails on ModuleNotFoundError when yaml is not installed. On clean contributor machines (where PyYAML is not preinstalled), make ci/make ci-post now fails before any project bootstrap, so unrelated changes cannot clear the required local gate.

Useful? React with 👍 / 👎.

skip_step "release supply-chain policy" "diff-aware: no workflow or image inputs touched"
fi

# ---------------- Backend (PHP) ---------------------------------------------
if (( diff_touch_php )); then
Expand Down Expand Up @@ -632,8 +637,8 @@ if [[ "$profile" == "full" || "$profile" == "cd" ]]; then
# 1. caller opted in via FOP_LOCAL_CI_RUN_INFECTION=1?
# 2. coverage extension present? (Infection without pcov/xdebug fails
# with a CoverageChecker error in <1s — meaningless signal.)
# The nightly GHA workflow .github/workflows/infection.yml runs with
# continue-on-error: true, so the local CD profile must not be stricter.
# The nightly GHA workflow is blocking when it runs; the local step remains
# opt-in because Infection needs a coverage extension and a tuned runtime.
run_step_heavy "infection mutation testing (soft, opt-in)" "if [[ \"\${FOP_LOCAL_CI_RUN_INFECTION:-0}\" != \"1\" ]]; then echo 'infection disabled by default; export FOP_LOCAL_CI_RUN_INFECTION=1 with pcov/xdebug enabled to run mutation testing'; elif ! php -m | grep -qE '^(pcov|xdebug)\$'; then echo 'infection requires pcov or xdebug for coverage; skipping (advisory like infection.yml continue-on-error)'; else ./vendor/bin/infection --threads=4 --no-progress || echo 'infection returned non-zero (soft on cd profile)'; fi"

run_step_heavy "playwright chromium browser install" "npx playwright install --with-deps chromium"
Expand Down Expand Up @@ -674,9 +679,8 @@ fi
# for CI/CD hardening (template injection, cache poisoning, persist-credentials,
# excessive-permissions). Uses --persona=auditor to match the workflow.
#
# Advisory mode: matches workflow's `continue-on-error: true` — zizmor surfaces
# findings as informational but does NOT fail the gate. Promote to a hard
# failure (drop the `|| true`) once the open-finding inventory is at zero.
# Local audit mode: zizmor surfaces findings as informational for contributor
# ergonomics. The workflow itself is blocking when it runs.
# Suppressions live in zizmor.yml with per-rule justification.
if (( ! diff_touch_workflows )); then
skip_step "zizmor (GHA SAST)" "diff-aware: no workflow inputs touched"
Expand Down
Loading
Loading