Files
Fenris/CI.md

2.8 KiB

CI quality gates

Workflow: .gitea/workflows/ci.yml (runner label bongbetic-ci, no third-party uses: actions; code is checked out with shell git). Status contexts: CI / security (pull_request), CI / lint (pull_request), CI / ai-review (pull_request).

Job Runs on Blocks merge? What it does
security PR, push to main, weekly schedule, manual Yes Semgrep 1.178.0, p/default + p/owasp-top-ten, --error
lint PR, push to main, manual Yes ruff check src/ tests/ (ruff 0.16.10, rules E4/E7/E9/F) and jscpd 4.3.0 duplicate-code threshold 8%
ai-review PR only No (advisory) PR-Agent review, comment-only, continue-on-error: true

There is no e2e (no web UI) and no deploy job (not a Coolify app). The weekly schedule (0 3 * * 1) runs only security.

Run locally

# security (same command as CI)
podman run --rm -v "$PWD:/src:Z" docker.io/semgrep/semgrep:1.178.0 \
  semgrep scan --config p/default --config p/owasp-top-ten --metrics off --error

# lint (needs `pip install -e '.[dev]'` or `pip install ruff==0.16.10`)
make lint

# duplicate code
npx --yes jscpd@4.3.0 --config .jscpd.json .

Notes:

  • The semgrep container needs no extra flags. :Z is only for SELinux hosts; its working directory is /src.
  • The lint job installs python3-venv from apt because node:24-bookworm has no ensurepip; ruff itself is pinned.
  • .jscpd.json threshold is 8%, just above the 7.15% baseline, so duplication cannot grow. Lower it as duplication is removed.
  • Semgrep prints some non-fatal PartialParsing errors; they do not fail the job.

PR-Agent (advisory)

ai-review posts a review comment on the PR through the Gitea API. It never pushes code and never blocks. It exits 0 with a notice when its secrets are empty (for example on fork PRs).

Required repository secrets: OPENROUTER_API_KEY, PR_AGENT_GITEA_TOKEN (Gitea token of the bot account, scopes to comment on PRs). Optional repository variable: PR_AGENT_MODEL (default openrouter/anthropic/claude-sonnet-5). The workflow sets config__custom_model_max_tokens to 200000, so adjust it if you pick a model with a different context window.

Caveats

  • Semgrep registry rules (p/default, p/owasp-top-ten) are fetched at runtime and are not pinned, so a new rule can turn a green main red. The weekly scheduled security run catches this early.
  • Intentional findings are suppressed with a narrow # nosemgrep: <rule-id> -- <reason> on the line. Do not use .semgrepignore for source files.

Rollback

Revert the PR that added ci.yml (and its follow-up commits). If branch protection requires CI / security, CI / lint or CI / ai-review, relax it first, otherwise merges stay blocked on checks that no longer run.