docs(ci): add CI incident runbook and update quality gate documentation #2809
@@ -88,6 +88,41 @@ The format follows [Keep a Changelog](https://keepachangelog.com/en/1.1.0/).
|
||||
|
||||
### Fixed
|
||||
|
||||
- **Docs — CI incident runbook and quality gate documentation**: Added
|
||||
`docs/development/ci-incident-runbook.md` documenting how to diagnose,
|
||||
triage, and recover from master branch CI quality gate failures. Updated
|
||||
`docs/development/ci-cd.md` and `docs/development/quality-automation.md` to
|
||||
accurately reflect the full 11-job `status-check` consolidation gate
|
||||
(including the previously undocumented `e2e_tests` and `helm` jobs), the
|
||||
job dependency graph, and the prohibition on direct pushes to `master`. (#2597)
|
||||
|
||||
- **CLI — `agents plan list --namespace/-n` filter option**: `agents plan list`
|
||||
now accepts `--namespace`/`-n` to filter plans by namespace, mirroring the
|
||||
existing `--namespace` option on `agents action list`. The service layer
|
||||
already supported namespace filtering; only the CLI layer was missing the
|
||||
option. The TUI Filters panel displays the active namespace filter when
|
||||
provided. (#2165)
|
||||
|
||||
- **MCP — Correct error extraction from MCP 1.4.0 protocol responses**:
|
||||
`MCPToolAdapter.invoke()` now extracts error messages from
|
||||
`content[0].text` per the MCP 1.4.0 protocol, replacing the previous
|
||||
`result.get('error', 'unknown error')` lookup that silently swallowed all
|
||||
real error messages from MCP 1.4.0-compliant servers. (#2158)
|
||||
|
||||
- **CI — Nox output captured as Forgejo CI artifacts**: All 8 nox-running CI
|
||||
jobs now capture stdout+stderr to `build/nox-<job>-output.log` via `tee`
|
||||
and upload the log as a named artifact (`ci-logs-<job>`, 30-day retention).
|
||||
Agent definitions updated with a CI Log Artifacts section explaining which
|
||||
artifact corresponds to each domain. (#2750)
|
||||
|
||||
- **Agents — Correct IssueMeta schema for Forgejo dependency API**: All agent
|
||||
definitions that call the Forgejo blocks/dependencies REST API now use the
|
||||
correct `IssueMeta` schema (`{"owner": "...", "repo": "...", "index": N}`)
|
||||
instead of the undocumented `{"dependency_id": N}` format that returned
|
||||
404 errors. Affects `ca-new-issue-creator`, `ca-pr-api-creator`,
|
||||
`ca-state-reconciler`, `ca-project-owner`, `ca-backlog-groomer`, and
|
||||
`ca-epic-planner`. (#2750)
|
||||
|
||||
- Fixed session leak in all `AutomationProfileRepository` public methods
|
||||
(`get_by_name()`, `list_all()`, `upsert()`, and `delete()`): added
|
||||
`finally: if self._auto_commit: session.close()` blocks matching the
|
||||
|
||||
+51
-27
@@ -15,24 +15,29 @@ pull requests with the following protections enforced.
|
||||
#### Required Status Checks
|
||||
|
||||
Every pull request targeting `master` must pass **all** of the following CI jobs
|
||||
before merging is allowed:
|
||||
before merging is allowed. These are enforced by the `status-check` consolidation
|
||||
gate — if any single job fails, the entire gate fails and the PR cannot merge.
|
||||
|
||||
| CI Job | What It Checks | Failure Means |
|
||||
|--------|---------------|---------------|
|
||||
| `lint` | Ruff format and lint (nox) | Code style violations or lint errors |
|
||||
| `typecheck` | Pyright strict type checking (nox) | Type errors in `src/` |
|
||||
| `security` | Security scan + dead code (nox) | Security vulnerabilities or dead code |
|
||||
| `quality` | Radon complexity (nox) | Extremely complex methods (31+ cyclomatic complexity) |
|
||||
| `unit_tests` | BDD unit tests via `nox -s unit_tests` | Failing unit test scenarios |
|
||||
| `integration_tests` | Robot integration tests via `nox -s integration_tests` | Failing integration tests |
|
||||
| `coverage` | Test coverage measurement (nox) | Coverage dropped below 97% |
|
||||
| `build` | Wheel build | Build failure |
|
||||
| # | CI Job | Nox Session(s) | What It Checks | Failure Means |
|
||||
|---|--------|----------------|----------------|---------------|
|
||||
| 1 | `lint` | `nox -s lint` + `nox -s format -- --check` | Ruff lint rules and code formatting | Code style violations or lint errors |
|
||||
| 2 | `typecheck` | `nox -s typecheck` | Pyright strict type checking | Type errors in `src/` |
|
||||
| 3 | `security` | `nox -s security_scan` + `nox -s dead_code` | Bandit HIGH gate, Semgrep custom rules, Vulture dead-code | Security vulnerabilities or dead code |
|
||||
| 4 | `quality` | `nox -s complexity` | Radon cyclomatic complexity | Extremely complex methods (31+ cyclomatic complexity) |
|
||||
| 5 | `unit_tests` | `nox -s unit_tests` | All Behave BDD scenarios under `features/` | Failing unit test scenarios |
|
||||
| 6 | `integration_tests` | `nox -s integration_tests` | Robot Framework tests under `robot/` (excl. slow/E2E) | Failing integration tests |
|
||||
| 7 | `e2e_tests` | `nox -s e2e_tests` | End-to-end Robot tests under `robot/e2e/` with real LLM keys | Failing end-to-end tests |
|
||||
| 8 | `coverage` | `nox -s coverage_report` | Slipcover test coverage ≥ 97% | Coverage dropped below 97% |
|
||||
| 9 | `build` | `nox -s build` | Python wheel build | Build failure |
|
||||
| 10 | `docker` | Docker CLI | Docker image build + smoke test (`--version`) | Image build or startup failure |
|
||||
| 11 | `helm` | Helm CLI + kubeconform | Helm chart lint, template render, and Kubernetes manifest validation | Chart or manifest invalid |
|
||||
|
||||
**Deployment-gating jobs** (run after core checks pass):
|
||||
**Job dependencies** (some jobs only run after others pass):
|
||||
|
||||
| CI Job | Depends On | What It Checks |
|
||||
|--------|-----------|----------------|
|
||||
| `docker` | `lint`, `typecheck`, `unit_tests`, `security` | Docker image builds and runs |
|
||||
| CI Job | Depends On |
|
||||
|--------|-----------|
|
||||
| `coverage` | `lint`, `typecheck`, `security`, `quality` |
|
||||
| `docker` | `lint`, `typecheck`, `security`, `quality`, `unit_tests` |
|
||||
|
||||
#### Required Reviews
|
||||
|
||||
@@ -44,7 +49,9 @@ before merging is allowed:
|
||||
#### Additional Protections
|
||||
|
||||
- **No direct pushes** to `master`. All changes must come via pull request.
|
||||
The `no-commit-to-branch` pre-commit hook enforces this locally.
|
||||
The `no-commit-to-branch` pre-commit hook enforces this locally. Direct
|
||||
pushes bypass CI entirely and are the primary cause of master CI breakage
|
||||
(see [CI Incident Runbook](ci-incident-runbook.md)).
|
||||
- **No force pushes** to `master`. History must be preserved.
|
||||
- **No deletions** of the `master` branch.
|
||||
- **Require branches to be up-to-date** before merging (prevents merge skew).
|
||||
@@ -155,15 +162,24 @@ PR template at `.forgejo/pull_request_template.md` in the repository root):
|
||||
```
|
||||
lint ──────────────────┐
|
||||
typecheck ─────────────┤
|
||||
├── coverage (needs lint + typecheck)
|
||||
├── coverage (needs lint + typecheck + security + quality)
|
||||
security ──────────────┤
|
||||
├── docker (needs lint + typecheck + unit_tests + security)
|
||||
unit_tests ────────────┘
|
||||
quality ───────────────┘
|
||||
└── docker (needs lint + typecheck + security + quality + unit_tests)
|
||||
unit_tests ─────────────── (independent; also feeds docker)
|
||||
integration_tests ──────── (independent)
|
||||
quality ────────────────── (independent)
|
||||
e2e_tests ──────────────── (independent; requires LLM API keys)
|
||||
build ──────────────────── (independent)
|
||||
helm ───────────────────── (independent)
|
||||
┌── status-check (needs ALL 11 jobs above)
|
||||
```
|
||||
|
||||
The `status-check` consolidation job is the single gate that branch protection
|
||||
checks. It fails if **any** of the 11 dependent jobs fail, skipped, or are
|
||||
cancelled. A broken `master` blocks all open PRs. See the
|
||||
[CI Incident Runbook](ci-incident-runbook.md) for diagnosis and recovery
|
||||
procedures.
|
||||
|
||||
### Nox-Based CI
|
||||
|
||||
All CI jobs now run their checks through nox sessions rather than invoking
|
||||
@@ -173,19 +189,27 @@ appropriate nox session.
|
||||
|
||||
### Quality Gates Summary
|
||||
|
||||
All gates must pass for a PR to be mergeable:
|
||||
All gates must pass for a PR to be mergeable. **No gate may be suppressed,
|
||||
bypassed, or weakened** — fixes must address the actual code, not the
|
||||
enforcement configuration. See [CI Incident Runbook](ci-incident-runbook.md)
|
||||
for the complete list of prohibited suppression techniques.
|
||||
|
||||
| Gate | Threshold | Enforced By |
|
||||
|------|-----------|-------------|
|
||||
| Formatting | Zero violations | `lint` job (ruff format) |
|
||||
| Linting | Zero violations | `lint` job (ruff check) |
|
||||
| Formatting | Zero violations | `lint` job (`nox -s format -- --check`) |
|
||||
| Linting | Zero violations | `lint` job (`nox -s lint`) |
|
||||
| Type Safety | Zero errors | `typecheck` job (pyright strict) |
|
||||
| Security | Zero HIGH severity | `security` job (bandit) |
|
||||
| Dead Code | Zero findings | `security` job (vulture) |
|
||||
| Complexity | No grade-F methods | `quality` job (radon) |
|
||||
| Unit Tests | All pass (3.11-3.13) | `behave` job |
|
||||
| Coverage | >= 97% | `coverage` job (nox) |
|
||||
| Dead Code | Zero findings ≥80% confidence | `security` job (vulture) |
|
||||
| Custom Rules | Zero violations | `security` job (semgrep) |
|
||||
| Complexity | No grade-F methods (31+) | `quality` job (radon) |
|
||||
| Unit Tests | All Behave scenarios pass | `unit_tests` job |
|
||||
| Integration Tests | All Robot suites pass | `integration_tests` job |
|
||||
| E2E Tests | All E2E Robot suites pass | `e2e_tests` job |
|
||||
| Coverage | ≥ 97% | `coverage` job (`nox -s coverage_report`) |
|
||||
| Build | Wheel builds | `build` job |
|
||||
| Docker | Images build and smoke-test | `docker` job |
|
||||
| Helm | Chart lints, renders, and validates | `helm` job |
|
||||
|
||||
### Nightly Quality Monitoring
|
||||
|
||||
|
||||
@@ -0,0 +1,374 @@
|
||||
# CI Incident Runbook: Master Branch Quality Gate Failures
|
||||
|
||||
This runbook documents how to diagnose, triage, and resolve CI quality gate
|
||||
failures on the `master` branch. It was written in response to issue #2597,
|
||||
which identified a critical pattern of direct pushes to `master` bypassing
|
||||
the PR process and introducing regressions.
|
||||
|
||||
## Why a Broken Master Is a Critical Incident
|
||||
|
||||
When `master` CI is broken, **all development work stops**:
|
||||
|
||||
1. **All open PRs are blocked.** The `status-check` consolidation gate requires
|
||||
all 11 CI jobs to succeed. Any failure prevents any PR from merging.
|
||||
2. **New branches inherit failures.** Any branch created from a broken `master`
|
||||
starts with broken code.
|
||||
3. **Branch protection enforces up-to-date branches.** PRs must be rebased on
|
||||
`master` before they can merge — a broken `master` guarantees they will also
|
||||
fail CI.
|
||||
4. **The TDD workflow is broken.** TDD issue-capture tests require merging to
|
||||
`master` before bug fixes can begin.
|
||||
5. **No releases can be cut.** Release tags are pushed from `master`; a broken
|
||||
`master` means no releases.
|
||||
|
||||
**Treat a broken `master` as the single highest-priority incident. All other
|
||||
work is blocked until `master` is green.**
|
||||
|
||||
---
|
||||
|
||||
## The 11-Job Status-Check Gate
|
||||
|
||||
The `status-check` consolidation job (defined in `.forgejo/workflows/ci.yml`)
|
||||
requires **all** of the following jobs to report `success` before any PR can
|
||||
merge:
|
||||
|
||||
| # | CI Job | Nox Session(s) | What It Checks |
|
||||
|---|--------|----------------|----------------|
|
||||
| 1 | `lint` | `nox -s lint` + `nox -s format -- --check` | Ruff lint rules and code formatting |
|
||||
| 2 | `typecheck` | `nox -s typecheck` | Pyright strict type checking |
|
||||
| 3 | `security` | `nox -s security_scan` + `nox -s dead_code` | Bandit HIGH gate, Semgrep custom rules, Vulture dead-code (≥80% confidence) |
|
||||
| 4 | `quality` | `nox -s complexity` | Radon cyclomatic complexity (no grade-F methods) |
|
||||
| 5 | `unit_tests` | `nox -s unit_tests` | All Behave BDD scenarios under `features/` |
|
||||
| 6 | `integration_tests` | `nox -s integration_tests` | All Robot Framework tests under `robot/` (excluding slow, discovery, code_blocks, wip, E2E, tdd_fixture) |
|
||||
| 7 | `e2e_tests` | `nox -s e2e_tests` | End-to-end Robot tests with real LLM API keys under `robot/e2e/` |
|
||||
| 8 | `coverage` | `nox -s coverage_report` | Slipcover test coverage ≥ **97%** fail-under threshold |
|
||||
| 9 | `build` | `nox -s build` | Python wheel build |
|
||||
| 10 | `docker` | Docker CLI | Docker image build (`Dockerfile` + `Dockerfile.server`) and smoke test |
|
||||
| 11 | `helm` | Helm CLI + kubeconform | Helm chart lint, template render, and Kubernetes manifest validation |
|
||||
|
||||
The `coverage` job additionally depends on `lint`, `typecheck`, `security`, and
|
||||
`quality` passing first. The `docker` job depends on `lint`, `typecheck`,
|
||||
`security`, `quality`, and `unit_tests`.
|
||||
|
||||
---
|
||||
|
||||
## How to Diagnose a Broken Master
|
||||
|
||||
### Step 1: Identify the Failing Jobs
|
||||
|
||||
Navigate to the Forgejo Actions UI for the latest `master` commit and check
|
||||
which jobs are failing. The `status-check` job output lists each job's result:
|
||||
|
||||
```
|
||||
lint: failure
|
||||
typecheck: success
|
||||
security: success
|
||||
quality: success
|
||||
unit_tests: failure
|
||||
integration_tests: success
|
||||
e2e_tests: failure
|
||||
coverage: skipped
|
||||
build: success
|
||||
docker: skipped
|
||||
helm: success
|
||||
```
|
||||
|
||||
Download the log artifact for each failing job (e.g., `ci-logs-lint`,
|
||||
`ci-logs-unit-tests`, `ci-logs-e2e-tests`) from the Actions UI under
|
||||
**Artifacts**.
|
||||
|
||||
### Step 2: Identify the Root Cause Commit
|
||||
|
||||
Check the recent commit history on `master` for any direct pushes (commits not
|
||||
from a PR merge):
|
||||
|
||||
```bash
|
||||
git log --oneline -10 origin/master
|
||||
```
|
||||
|
||||
Direct pushes bypass CI entirely. Look for commits that were not preceded by a
|
||||
PR merge commit. These are the most likely source of regressions.
|
||||
|
||||
### Step 3: Reproduce Locally
|
||||
|
||||
Clone the `master` branch and run the failing nox sessions locally:
|
||||
|
||||
```bash
|
||||
git clone https://git.cleverthis.com/cleveragents/cleveragents-core.git
|
||||
cd cleveragents-core
|
||||
git checkout master
|
||||
|
||||
# Run the specific failing sessions
|
||||
nox -s lint
|
||||
nox -s format -- --check
|
||||
nox -s unit_tests
|
||||
nox -s e2e_tests
|
||||
nox -s coverage_report
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
## Triage by Failure Type
|
||||
|
||||
### Lint Failures (`lint` job)
|
||||
|
||||
**Symptoms:** Ruff reports lint violations or format differences.
|
||||
|
||||
**Reproduce:**
|
||||
```bash
|
||||
nox -s lint
|
||||
nox -s format -- --check
|
||||
```
|
||||
|
||||
**Fix:** Run `nox -s format` to auto-fix formatting, then fix any remaining
|
||||
lint violations reported by `nox -s lint`. Commit the result.
|
||||
|
||||
**Prohibited fixes:**
|
||||
- Adding `# noqa` comments
|
||||
- Modifying `pyproject.toml [tool.ruff]` to disable rules or add ignores
|
||||
|
||||
### Unit Test Failures (`unit_tests` job)
|
||||
|
||||
**Symptoms:** One or more Behave BDD scenarios fail.
|
||||
|
||||
**Reproduce:**
|
||||
```bash
|
||||
nox -s unit_tests
|
||||
# Or run a specific feature file:
|
||||
nox -s unit_tests -- features/failing_feature.feature
|
||||
```
|
||||
|
||||
**Fix:** Identify the failing scenario and fix the **source code** to match the
|
||||
expected behavior. Do **not** modify test expectations or skip scenarios.
|
||||
|
||||
**Prohibited fixes:**
|
||||
- Adding `@skip`, `@xfail`, or `@unittest.skip` tags to scenarios
|
||||
- Deleting or removing test scenarios or assertions
|
||||
- Modifying test expectations to match broken behavior
|
||||
|
||||
### Integration Test Failures (`integration_tests` job)
|
||||
|
||||
**Symptoms:** One or more Robot Framework tests fail.
|
||||
|
||||
**Reproduce:**
|
||||
```bash
|
||||
nox -s integration_tests
|
||||
# Or run a specific suite:
|
||||
nox -s integration_tests -- --suite robot/failing_suite.robot
|
||||
```
|
||||
|
||||
**Note:** Integration tests require real LLM API keys (`ANTHROPIC_API_KEY`,
|
||||
`OPENAI_API_KEY`). Set these in your environment before running locally.
|
||||
|
||||
**Fix:** Identify the failing test and fix the underlying source code. Check
|
||||
`robot/helpers_common.py` for the shared `reset_global_state()` function if
|
||||
tests are failing due to state leakage between test runs.
|
||||
|
||||
### E2E Test Failures (`e2e_tests` job)
|
||||
|
||||
**Symptoms:** End-to-end Robot Framework tests under `robot/e2e/` fail.
|
||||
|
||||
**Reproduce:**
|
||||
```bash
|
||||
nox -s e2e_tests
|
||||
```
|
||||
|
||||
**Note:** E2E tests require real LLM API keys (`ANTHROPIC_API_KEY`,
|
||||
`OPENAI_API_KEY`, `GOOGLE_API_KEY`). These tests exercise full end-to-end
|
||||
workflows with live LLM providers and have a 45-minute timeout in CI.
|
||||
|
||||
**Fix:** Fix the underlying source code. E2E tests must not be skipped or
|
||||
mocked.
|
||||
|
||||
### Coverage Failures (`coverage` job)
|
||||
|
||||
**Symptoms:** `nox -s coverage_report` reports coverage below 97%.
|
||||
|
||||
**Reproduce:**
|
||||
```bash
|
||||
nox -s coverage_report
|
||||
# Open the HTML report to identify uncovered lines:
|
||||
open build/htmlcov/index.html
|
||||
```
|
||||
|
||||
**Fix:** Write new Behave scenarios targeting the uncovered code paths. Coverage
|
||||
must be ≥97% as measured by `nox -s coverage_report`.
|
||||
|
||||
**Prohibited fixes:**
|
||||
- Lowering the `--fail-under` threshold in `noxfile.py`
|
||||
- Adding `# pragma: no cover` comments
|
||||
- Expanding the `omit` list in `pyproject.toml [tool.coverage.run]`
|
||||
|
||||
### Type Check Failures (`typecheck` job)
|
||||
|
||||
**Symptoms:** Pyright reports type errors.
|
||||
|
||||
**Reproduce:**
|
||||
```bash
|
||||
nox -s typecheck
|
||||
```
|
||||
|
||||
**Fix:** Fix the type errors in source code. Add explicit type annotations where
|
||||
missing.
|
||||
|
||||
**Prohibited fixes:**
|
||||
- Adding `# type: ignore` comments
|
||||
- Modifying `pyrightconfig.json` to relax strictness or add exclusions
|
||||
- Adding paths to `pyproject.toml [tool.pyright]` exclusions
|
||||
|
||||
### Security Failures (`security` job)
|
||||
|
||||
**Symptoms:** Bandit reports HIGH-severity findings, Semgrep detects custom rule
|
||||
violations, or Vulture detects dead code.
|
||||
|
||||
**Reproduce:**
|
||||
```bash
|
||||
nox -s security_scan
|
||||
nox -s dead_code
|
||||
```
|
||||
|
||||
**Fix:**
|
||||
- **Bandit:** Fix the security issue in source code. If it is a genuine false
|
||||
positive, consider a safer alternative first. Only as a last resort, add to
|
||||
`[tool.bandit]` `skips` in `pyproject.toml`.
|
||||
- **Semgrep:** Fix the code pattern flagged by the custom rule (see
|
||||
`.semgrep.yml` for rule descriptions).
|
||||
- **Vulture:** If the symbol is intentionally unused (e.g., required by a
|
||||
protocol), add it to `vulture_whitelist.py` with a comment explaining why.
|
||||
|
||||
### Build Failures (`build` job)
|
||||
|
||||
**Symptoms:** `nox -s build` fails to produce a wheel.
|
||||
|
||||
**Reproduce:**
|
||||
```bash
|
||||
nox -s build
|
||||
```
|
||||
|
||||
**Fix:** Fix the build error. Common causes include missing `__init__.py` files,
|
||||
broken imports, or `pyproject.toml` misconfiguration.
|
||||
|
||||
### Docker Failures (`docker` job)
|
||||
|
||||
**Symptoms:** Docker image build fails or the smoke test (`--version`) fails.
|
||||
|
||||
**Reproduce:**
|
||||
```bash
|
||||
docker build -t cleveragents:test .
|
||||
docker run --rm cleveragents:test --version
|
||||
docker build -f Dockerfile.server -t cleveragents-server:test .
|
||||
```
|
||||
|
||||
**Fix:** Fix the Dockerfile or the application code causing the build or smoke
|
||||
test failure.
|
||||
|
||||
### Helm Failures (`helm` job)
|
||||
|
||||
**Symptoms:** Helm lint, template render, or kubeconform validation fails.
|
||||
|
||||
**Reproduce:**
|
||||
```bash
|
||||
helm dependency build ./k8s
|
||||
helm lint ./k8s --set database.url="postgresql+asyncpg://user:pass@db-host:5432/cleveragents"
|
||||
helm template cleveragents ./k8s \
|
||||
--set database.url="postgresql+asyncpg://user:pass@db-host:5432/cleveragents" > /tmp/rendered.yaml
|
||||
kubeconform -strict -ignore-missing-schemas -kubernetes-version 1.29.0 -summary /tmp/rendered.yaml
|
||||
```
|
||||
|
||||
**Fix:** Fix the Helm chart templates or values in `k8s/`.
|
||||
|
||||
---
|
||||
|
||||
## The Fix Branch Workflow
|
||||
|
||||
When `master` is broken, the fix **must** go through the PR process — never
|
||||
push directly to `master` again:
|
||||
|
||||
1. **Create a fix branch** from the current `master` HEAD:
|
||||
```bash
|
||||
git checkout -b fix/master-ci-quality-gates origin/master
|
||||
```
|
||||
|
||||
2. **Fix the actual code** (see triage sections above). Never suppress or bypass
|
||||
quality gates.
|
||||
|
||||
3. **Verify locally** that all nox sessions pass:
|
||||
```bash
|
||||
nox # runs all default sessions
|
||||
```
|
||||
|
||||
4. **Commit** with the conventional commit format:
|
||||
```
|
||||
fix(ci): restore all CI quality gates to passing on master
|
||||
|
||||
- Fixed lint violations in src/...
|
||||
- Fixed failing Behave scenario in features/...
|
||||
- Fixed E2E test failure in robot/e2e/...
|
||||
- Coverage restored to 97.X%
|
||||
|
||||
ISSUES CLOSED: #2597
|
||||
```
|
||||
|
||||
5. **Push** the fix branch and **open a PR** to `master`.
|
||||
|
||||
6. **Wait for CI** to pass on the fix branch before merging.
|
||||
|
||||
7. **After merge**, verify the CI pipeline on the resulting `master` commit
|
||||
passes all 11 jobs.
|
||||
|
||||
---
|
||||
|
||||
## Prohibited Actions
|
||||
|
||||
The following changes are **strictly prohibited** when fixing CI failures.
|
||||
They suppress or bypass quality enforcement rather than fixing the underlying
|
||||
code:
|
||||
|
||||
| Prohibited Change | Why |
|
||||
|---|---|
|
||||
| Adding `# type: ignore` or Pyright suppression directives | Hides type errors instead of fixing them |
|
||||
| Adding `# noqa` or Ruff suppression directives | Hides lint violations instead of fixing them |
|
||||
| Adding `@skip`, `@xfail`, `@unittest.skip` to tests | Hides test failures instead of fixing the code |
|
||||
| Modifying `pyrightconfig.json` to relax strictness | Weakens the type checking gate |
|
||||
| Modifying `pyproject.toml [tool.ruff]` to disable rules | Weakens the lint gate |
|
||||
| Modifying Bandit config to suppress findings | Weakens the security gate |
|
||||
| Modifying `.semgrep.yml` to exclude patterns | Weakens the security gate |
|
||||
| Modifying `vulture_whitelist.py` to suppress legitimate findings | Weakens the dead-code gate |
|
||||
| Reducing the coverage threshold below 97% | Weakens the coverage gate |
|
||||
| Modifying `.forgejo/workflows/ci.yml` to skip or make optional any required job | Weakens the CI gate |
|
||||
| Deleting or removing test files, scenarios, or assertions | Hides test failures |
|
||||
| Adding `success_codes` workarounds to nox sessions | Hides failures |
|
||||
| Pushing directly to `master` without a PR | Bypasses CI entirely |
|
||||
|
||||
---
|
||||
|
||||
## Prevention: No Direct Pushes to Master
|
||||
|
||||
The root cause of issue #2597 was direct pushes to `master` that bypassed CI.
|
||||
The `no-commit-to-branch` pre-commit hook prevents this locally, but it can be
|
||||
bypassed with `--no-verify`.
|
||||
|
||||
**Never push directly to `master`.** All changes must go through a PR with CI
|
||||
passing. This is enforced by branch protection rules in Forgejo (see
|
||||
[CI/CD Pipeline and Branch Protection](ci-cd.md)).
|
||||
|
||||
If you find yourself needing to push directly to `master` for an emergency fix,
|
||||
stop and ask: can this wait for a PR? In almost all cases, the answer is yes.
|
||||
A broken `master` caused by a direct push is far more damaging than the delay
|
||||
of a PR review.
|
||||
|
||||
---
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [CI/CD Pipeline and Branch Protection](ci-cd.md) — Full CI pipeline reference
|
||||
and branch protection rules
|
||||
- [Quality Automation Guide](quality-automation.md) — Pre-commit hooks, nox
|
||||
sessions, and quality gate details
|
||||
- [Testing Guide](testing.md) — Unit tests (Behave), integration tests (Robot
|
||||
Framework), and coverage requirements
|
||||
|
||||
## Related Issues
|
||||
|
||||
- **#2597** — fix(ci): restore all CI quality gates to passing on master
|
||||
- **#2463** — Earlier automated report of CI failures on master (superseded by #2597)
|
||||
@@ -71,17 +71,24 @@ The CI pipeline runs on **Forgejo Actions** (`.forgejo/workflows/ci.yml`).
|
||||
|
||||
### CI Jobs
|
||||
|
||||
| Job | Trigger | Purpose | Failure Impact |
|
||||
| ----------- | ------- | ----------------------------------- | ---------------------- |
|
||||
| `lint` | Push/PR | Ruff format + lint check | Blocks merge |
|
||||
| `typecheck` | Push/PR | Pyright type checking | Blocks merge |
|
||||
| `security` | Push/PR | Bandit + Semgrep + Vulture | Blocks merge |
|
||||
| `quality` | Push/PR | Radon complexity check | Blocks merge (grade F) |
|
||||
| `unit_tests`| Push/PR | Behave BDD tests (Python 3.13) | Blocks merge |
|
||||
| `coverage` | Push/PR | Coverage measurement | Blocks merge (<97%) |
|
||||
| `build` | Push/PR | Wheel build | Blocks release |
|
||||
| `docker` | Push/PR | Docker image build + test | Blocks deployment |
|
||||
| `helm` | Push/PR | Helm chart lint + template | Blocks deployment |
|
||||
All 11 jobs below must pass for the `status-check` consolidation gate to
|
||||
succeed. A failure in any single job blocks all PR merges. See
|
||||
[CI Incident Runbook](ci-incident-runbook.md) for diagnosis and recovery.
|
||||
|
||||
| Job | Trigger | Purpose | Failure Impact |
|
||||
| ------------------- | ------- | ---------------------------------------------- | --------------------------- |
|
||||
| `lint` | Push/PR | Ruff format + lint check | Blocks merge |
|
||||
| `typecheck` | Push/PR | Pyright strict type checking | Blocks merge |
|
||||
| `security` | Push/PR | Bandit + Semgrep + Vulture | Blocks merge |
|
||||
| `quality` | Push/PR | Radon complexity check | Blocks merge (grade F) |
|
||||
| `unit_tests` | Push/PR | Behave BDD tests (Python 3.13) | Blocks merge |
|
||||
| `integration_tests` | Push/PR | Robot Framework integration tests | Blocks merge |
|
||||
| `e2e_tests` | Push/PR | Robot Framework E2E tests (real LLM API keys) | Blocks merge |
|
||||
| `coverage` | Push/PR | Coverage measurement (≥97% threshold) | Blocks merge (<97%) |
|
||||
| `build` | Push/PR | Wheel build | Blocks release |
|
||||
| `docker` | Push/PR | Docker image build + smoke test | Blocks deployment |
|
||||
| `helm` | Push/PR | Helm chart lint, template render, kubeconform | Blocks deployment |
|
||||
| `status-check` | Push/PR | Consolidation gate (requires all 11 above) | Blocks merge (branch guard) |
|
||||
|
||||
### Nightly Quality
|
||||
|
||||
|
||||
@@ -24,6 +24,7 @@ nav:
|
||||
- TUI: api/tui.md
|
||||
- Development:
|
||||
- CI/CD Pipeline: development/ci-cd.md
|
||||
- CI Incident Runbook: development/ci-incident-runbook.md
|
||||
- Quality Automation: development/quality-automation.md
|
||||
- Testing Guide: development/testing.md
|
||||
- Review Playbook: development/review_playbook.md
|
||||
|
||||
Reference in New Issue
Block a user