Files
Fenris/CI.md
T

49 lines
2.8 KiB
Markdown

# 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
```sh
# 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.