Security Scan (SIAX Cloud) / gitleaks (push) Failing after 21s
CI (SIAX Cloud) / security (push) Successful in 27s
Security Scan (SIAX Cloud) / trivy (push) Failing after 47s
CI (SIAX Cloud) / quality (push) Successful in 3m28s
Security Scan (SIAX Cloud) / license-inventory (push) Successful in 8m59s
BACKLOG P0-13: next.config.mjs now sets HSTS, X-Frame-Options, X-Content-Type-Options, Referrer-Policy, Permissions-Policy, and a same-origin CSP on every route. Previously the only security header came from Vercel's platform default (HSTS) -- nothing was set by the app itself, so it would have silently disappeared on cutover to Coolify/Traefik. Verified at runtime (curl -I against a production build), not just that the build compiles. BACKLOG P0-16: Trivy in security.yml/nightly.yml now actually fails the build on HIGH/CRITICAL findings (`--exit-code 1`) instead of the previous `--exit-code 0` (purely advisory, never blocked a merge). Verified locally against this repo's real dependency tree -- 19 HIGH findings currently exist in pnpm-lock.yaml (next.js, postcss, sharp, nanoid), several in next.js itself relating to middleware/auth bypass. See PR description: this is expected to turn the security.yml `trivy` job red until those are bumped in a follow-up -- that's the fix working as intended, not a regression, but it needs a human decision on timing given the sibling auth-gate PR (#11). `services/scrapers/` stays explicitly excluded from the scan (--skip-dirs) -- that tree is a dated, deliberate keep-decision under active review in a separate thread (BACKLOG P3-3) and is out of scope here. BACKLOG P0-19: dedicated gitleaks job added to security.yml, full git history (--log-opts=--all), pinned + checksum-verified binary. Verified locally against this repo's actual history first (81 commits, no leaks) so this blocking gate doesn't open red on day one. BACKLOG P1-14: SBOM (CycloneDX) + license inventory (`pnpm licenses list`) generated as informational, non-blocking build artifacts. actions/checkout, actions/setup-node, actions/cache, actions/upload-artifact all pinned to commit SHA (was floating @v4 tags) across every workflow file, Trivy/gitleaks pinned to specific released versions instead of floating install scripts. cosign image-signing explicitly NOT added -- there is no container-registry publish step in this repo's CI to attach a signature to yet (Coolify builds directly from git); flagging as a real follow-up once that pipeline exists. BACKLOG P1-15: explicit `permissions: contents: read` + `concurrency` added to every workflow that lacked them (only .github/workflows/ci.yml already had concurrency). Pinned pnpm-store cache added to ci.yml's quality job. Root CODEOWNERS added (`* @sax3l`) so Gitea has someone to assign once required-approvals is turned on (separate repo-settings change, not a file change). The "doctor step" part of P1-15 is added in the follow-up repo- hygiene PR, alongside the `siax:doctor` script it invokes.
63 lines
2.5 KiB
YAML
63 lines
2.5 KiB
YAML
name: CI
|
|
|
|
# Quality gate: typecheck + test on every PR and non-main push.
|
|
# 0pt previously relied solely on the Vercel build with no pre-merge gate.
|
|
# Build is intentionally NOT run here because it needs runtime secrets
|
|
# (POSTGRES_URL, ENGINE_URL, STRIPE, RESEND) — Vercel owns the build; CI owns
|
|
# the static gate.
|
|
#
|
|
# Updated by the GitHub<->Gitea unification merge (2026-07-28). The note that
|
|
# used to sit here — "lint is not a step because this repo has no eslint
|
|
# dependency or config wired" — is no longer true: the Gitea line's Wave 2
|
|
# hardening added eslint + typescript-eslint + a flat config and repointed the
|
|
# "lint" script at `eslint src tests`. Lint now runs, ADVISORY
|
|
# (continue-on-error), matching .gitea/workflows/ci.yml: the v0-generated
|
|
# legacy tree carries pre-existing lint noise, so it must not block merges.
|
|
#
|
|
# `typecheck` (BLOCKING) is tsc over tsconfig.check.json = src/ + tests/.
|
|
# `typecheck:app` (ADVISORY) is the whole-repo tsc this workflow used to run as
|
|
# its blocking step. It was green on the GitHub line alone but reports 9
|
|
# pre-existing errors on the unified tree (app/api/0pt/* route handlers, where
|
|
# the Wave 2 Zod schemas type fields as plain `string` while the services want
|
|
# narrower unions). It is kept running, and kept visible, rather than deleted —
|
|
# see package.json's "//scripts" note. Flip it back to blocking once those 9
|
|
# are cleared.
|
|
#
|
|
# Python engine (services/api) is gated separately if/when a Python workflow
|
|
# is added.
|
|
on:
|
|
pull_request:
|
|
push:
|
|
branches-ignore: [main]
|
|
|
|
permissions:
|
|
contents: read
|
|
|
|
concurrency:
|
|
group: ci-${{ github.ref }}
|
|
cancel-in-progress: true
|
|
|
|
jobs:
|
|
gate:
|
|
name: Typecheck + test
|
|
runs-on: ubuntu-latest
|
|
steps:
|
|
- uses: actions/checkout@11d5960a326750d5838078e36cf38b85af677262 # v4.4.0
|
|
- uses: actions/setup-node@49933ea5288caeca8642d1e84afbd3f7d6820020 # v4.4.0
|
|
with:
|
|
node-version: '22'
|
|
- name: Enable corepack (pnpm)
|
|
run: corepack enable
|
|
- name: Install (frozen lockfile)
|
|
run: pnpm install --frozen-lockfile
|
|
- name: Typecheck (tsc over src/ + tests/ -- blocking)
|
|
run: pnpm run typecheck
|
|
- name: Test (vitest -- blocking)
|
|
run: pnpm run test
|
|
- name: Typecheck whole repo (advisory -- 9 pre-existing app/ errors)
|
|
continue-on-error: true
|
|
run: pnpm run typecheck:app
|
|
- name: Lint (eslint -- advisory; legacy tree has pre-existing noise)
|
|
continue-on-error: true
|
|
run: pnpm run lint
|