Commit Graph

59 Commits

Author SHA1 Message Date
freemo 72e0db2592 chore(ci): capture nox output as CI artifacts and teach agents to read them
All 8 nox-running CI jobs in .forgejo/workflows/ci.yml now capture
stdout+stderr to build/nox-<job>-output.log via `2>&1 | tee` and upload
the log as a named Forgejo artifact (if: always(), retention-days: 30).
Artifact names follow the pattern ci-logs-<job>:
  ci-logs-lint, ci-logs-typecheck, ci-logs-security, ci-logs-quality,
  ci-logs-unit-tests, ci-logs-integration-tests, ci-logs-e2e-tests,
  ci-logs-coverage

Seven agent definitions updated with a CI Log Artifacts section:
  ca-pr-checker.md: artifact table + curl download instructions; Step 2
    now downloads the relevant artifact before dispatching fix subagents.
  ca-lint-fixer.md, ca-typecheck-fixer.md, ca-unit-test-runner.md,
  ca-integration-test-runner.md, ca-coverage-checker.md,
  ca-pr-self-reviewer.md: each receives a section explaining which
    artifact corresponds to its domain and how to use it.

Design notes:
- tee (not redirect) preserves output in CI job logs AND captures to file
- if: always() ensures artifacts are available even when the job fails
- Multi-session jobs (lint, security) use tee -a to append to one file
- Existing coverage-reports artifact preserved alongside ci-logs-coverage

ISSUES CLOSED: #2750
2026-04-04 19:58:49 +00:00
freemo c38be2eed8 fix(ci): address review feedback on nightly-quality workflow
- Add missing 'nox -s format -- --check' step (parity with ci.yml)
- Add NOX_DEFAULT_VENV_BACKEND: uv to global env and each nox step
- Fix quality gates script invocation (was using invalid nox session '3.13')
- Fix report artifact paths to match actual nox session output locations
  (build/coverage.json and build/bandit-report.json instead of build/reports/)
- Add mkdir for build/reports before writing quality-trend.json

ISSUES CLOSED: #1537
2026-04-03 03:37:10 +00:00
freemo 36ac24f2dd chore(ci): refactor nightly-quality workflow to use nox sessions
- Replaced manual uv pip install with nox invocations for all quality checks
- Mapped workflow steps to nox sessions:
  - Lint: ruff format + ruff check → nox -s lint
  - Type checking: pyright → nox -s typecheck
  - Security: bandit + semgrep → nox -s security_scan
  - Dead code: vulture → nox -s dead_code
  - Complexity: radon → nox -s complexity
  - Tests + coverage: behave → nox -s unit_tests + coverage_report
- Removed explicit dependency installation steps (nox handles this)
- Removed RUFF_VERSION env var (nox uses pinned versions from pyproject.toml)
- Workflow now consistent with ci.yml approach

Fixes #1537
2026-04-03 03:37:10 +00:00
freemo 6228129919 Merge pull request 'ci(pipeline): parallelize lint, typecheck, security, and quality jobs' (#1633) from task/ci-parallelize-static-analysis into master 2026-04-03 01:08:43 +00:00
freemo 99aa459bad chore(ci): consolidate uv cache key across all workflow jobs
Replace per-job cache key prefixes (uv-lint-, uv-typecheck-, uv-security-,
uv-quality-, uv-tests-, uv-coverage-) with a single shared key
uv-${{ hashFiles('pyproject.toml') }} across all jobs in ci.yml.

Also add a missing uv cache step to the build job and add uv caching
to nightly-quality.yml, which previously had no cache at all.

All jobs now share the same cache entry when pyproject.toml is unchanged,
eliminating redundant package downloads and reducing CI wall-clock time.

ISSUES CLOSED: #1535
2026-04-02 23:20:11 +00:00
freemo 6f7ced1a19 ci(pipeline): parallelize lint, typecheck, security, and quality jobs
The lint, typecheck, security, and quality static analysis jobs already
run in parallel (no needs dependencies between them). However, downstream
jobs only gated on a subset of these jobs, allowing the pipeline to
proceed even when some static analysis checks failed.

Updated needs dependencies for downstream jobs:
- coverage: [lint, typecheck] → [lint, typecheck, security, quality]
- benchmark-regression: [lint, typecheck] → [lint, typecheck, security, quality]
- docker: [lint, typecheck, unit_tests, security] → [lint, typecheck, security, quality, unit_tests]

All four static analysis jobs (lint, typecheck, security, quality) now
run in parallel and all downstream jobs correctly gate on the full set,
ensuring no job proceeds unless all static analysis checks pass.

ISSUES CLOSED: #1536
2026-04-02 23:17:49 +00:00
freemo 4e3b4180fc feat(ci): add Helm chart lint and template validation to CI
Add kubeconform manifest validation to the existing helm CI job.
The helm job already had helm lint and helm template steps (added in
#1085). This commit completes the optional acceptance criterion from
#1089 by adding kubeconform v0.7.0 to validate rendered manifests
against the Kubernetes 1.29.0 schema in strict mode.

Changes:
- Install kubeconform v0.7.0 in the helm CI job
- Add 'Validate rendered manifests with kubeconform' step after
  helm template smoke render (strict mode, ignore-missing-schemas,
  kubernetes-version 1.29.0)
- Add 5 BDD scenarios to ci_workflow_validation.feature covering:
  - helm job existence
  - helm lint step
  - helm template step
  - kubeconform validation step
  - status-check dependency on helm job

ISSUES CLOSED: #1089
2026-04-02 07:47:09 +00:00
brent.edwards 10df485401 test: add TDD bug-capture test for #1039 — missing validation YAML (#1132)
## Summary

This PR adds a Behave TDD bug-capture test that proves bug #1039 exists: the specification references `validations/unit-tests.yaml` as an example validation configuration file (Workflow Examples, Example 1, Step 1) but the file does not exist in the project's `examples/validations/` directory.

## Changes

- **New feature file:** `features/tdd_missing_validation_unit_tests_yaml.feature` — four scenarios tagged `@tdd_expected_fail @tdd_bug @tdd_bug_1039` that verify:
  1. The file `examples/validations/unit-tests.yaml` exists
  2. The YAML config contains `name: local/unit-tests`
  3. The validation mode is `required`
  4. The description field is non-empty
- **New step file:** `features/steps/tdd_missing_validation_unit_tests_yaml_steps.py` — step implementations that locate the project root and check file existence/content

All four scenarios currently fail with `AssertionError` (the file doesn't exist, proving the bug exists). The `@tdd_expected_fail` tag inverts the results so the test suite passes CI.

## Robot Integration Test

N/A — this bug is purely about a missing example file referenced by the specification. There is no integration-level behavior to test.

## Quality Gate Results

| Gate | Result |
|------|--------|
| `nox -s lint` | passed |
| `nox -s typecheck` | passed (0 errors) |
| `nox -s unit_tests` | 462 features, 12234 scenarios, 0 failures |
| `nox -s integration_tests` | 1672 tests, 0 failures |
| `nox -s e2e_tests` | 37 tests, 0 failures |
| `nox -s coverage_report` | 98% (>= 97% threshold) |

Closes #1103

Reviewed-on: cleveragents/cleveragents-core#1132
Reviewed-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-03-28 04:15:49 +00:00
brent.edwards b51df2ee0f feat(server): add Kubernetes Helm chart for server deployment (#1085)
## Summary

This PR adds Kubernetes Helm deployment support for the CleverAgents server.

Closes #928

### What this PR includes

- Helm chart under `k8s/` with Deployment, Service, optional Ingress, ConfigMap,
  ServiceAccount, Secrets, NOTES, and optional Redis subchart configuration.
- Multi-stage `Dockerfile.server` for server runtime deployment.
- Deployment-focused docs in `k8s/README.md`.
- Behave + Robot + benchmark coverage for chart/deployment wiring.

### Review fixes applied (cycle 11 — hurui200320 review #2687)

**Critical fix:**

1. **CI SHA256 checksum verification fixed** — All 3 Helm install blocks (`unit_tests`, `integration_tests`, `helm` jobs) now save the tarball using its original filename (`helm-v3.16.4-linux-amd64.tar.gz`) instead of `helm.tgz`, so the `.sha256sum` file can correctly locate and verify it. This was causing all 3 CI Helm jobs to fail with "No such file or directory".

**Major fixes (test coverage gaps):**

2. **405 Allow header now tested** — The existing "POST to known path returns method not allowed" scenario now asserts that the `Allow: GET` header is present. Added a second 405 scenario testing `POST /live` for broader `_KNOWN_PATHS` coverage (review item #11).
3. **Security-hardening headers now tested** — New scenario "HTTP responses include security-hardening headers" verifies `content-length`, `x-content-type-options: nosniff`, and `cache-control: no-store` headers are present on HTTP responses.
4. **Lifespan warning logging now tested** — New scenario "Unrecognised lifespan message type logs warning and continues" queues `lifespan.startup` → `lifespan.bogus` → `lifespan.shutdown` and verifies: (a) the app completes the lifespan cycle cleanly, (b) a warning is logged mentioning the unrecognised type.

### Review fixes applied (cycle 10)

**Critical/Major fixes (from hurui200320's prior REQUEST_CHANGES):**

1. **Rebased branch onto master** — Removed merge commit per CONTRIBUTING.md rebase-only policy. Clean linear history restored.
2. **Fixed commit message body** — Replaced literal `\n` sequences with actual newlines. `ISSUES CLOSED: #928` footer is now on its own line after a blank separator.
3. **Moved uvicorn import to module top level** — `from uvicorn import run as uvicorn_run` is now at the top of `src/cleveragents/cli/commands/server.py` per Import Guidelines. Updated test mock target from `uvicorn.run` to `cleveragents.cli.commands.server.uvicorn_run`.
4. **Added SHA256 checksum verification** — All three Helm CLI install blocks in `.forgejo/workflows/ci.yml` now download and verify `helm.sha256sum` before extracting the binary.

**Minor fixes:**

5. **Added `Dockerfile.server` build to CI** — New "Build Docker image (Server)" step in the `docker` job validates the server Dockerfile.
6. **ASGI 405 Method Not Allowed** — Known paths (`/`, `/live`, `/ready`, `/health`) now return 405 with `Allow: GET` header for non-GET methods, per RFC 9110 §15.5.6. Added `_KNOWN_PATHS` frozenset.
7. **WebSocket close protocol fix** — App now calls `await receive()` to consume the `websocket.connect` event before closing. Changed close code from 1000 (Normal Closure) to 1008 (Policy Violation).
8. **Lifespan handler logging** — Unrecognised lifespan message types are now logged as warnings instead of silently consumed.
9. **Security-hardening headers** — `_send_response` now includes `content-length`, `x-content-type-options: nosniff`, and `cache-control: no-store` on all HTTP responses.
10. **`.dockerignore` credential patterns** — Added `*.pem`, `*.key`, `*.p12`, `*.pfx`, `credentials*.json`.
11. **`--log-level` validation** — Constrained to `click.Choice(["critical", "error", "warning", "info", "debug", "trace"])` for clean CLI validation errors.
12. **Reverted unrelated semgrep pre-commit change** — `pass_filenames` and `entry` restored to original values per atomic commit hygiene.
13. **Removed unused `ReceiveCallable` type alias** and `Callable`/`Awaitable` imports from `asgi_app_steps.py`.
14. **Fixed redundant `shutil.which("helm")` check** — `_skip_if_helm_missing` now returns `bool` to eliminate the duplicate check in `_render_chart`.
15. **Improved test deque error handling** — Lifespan test receive mock now raises descriptive `AssertionError` instead of opaque `IndexError`.
16. **Scope type dispatch** — Changed `if/if/if` to `if/elif/elif` for mutually exclusive ASGI scope types.
17. **Dockerfile.server base image** — Standardised to `python:3.13-slim` (floating minor) consistent with CLI Dockerfile.
18. **Dockerfile layer caching** — Split `uv pip install build` and `python -m build` into separate `RUN` instructions.
19. **Removed extraneous double blank line** in Dockerfile.server.

### Deferred items (acknowledged, not in scope)

- PodDisruptionBudget, HorizontalPodAutoscaler, NetworkPolicy — Follow-up for production hardening.
- `appVersion: "1.0.0"` placeholder — Needs tracking issue for release versioning alignment.
- Readiness probe with downstream dependency checks — Documented limitation.
- Cross-system test for probe paths matching ASGI routes — Test enhancement.
- Improved benchmarks (helm template timing vs PyYAML parsing) — Benchmark quality improvement.
- CI DRY violation (Helm install 3×) — Code quality improvement, consider composite action.
- File length limits exceeded (`k8s_helm_chart_steps.py` 551 lines, `helper_k8s_helm_chart.py` 678 lines) — Non-blocking, can be split in follow-up.
- `runAsGroup: 1000` in pod security context — Defense-in-depth improvement.
- HEAD method support on known paths — RFC compliance, does not affect K8s probes.
- `click.Choice` log-level validation via CLI runner test — Test gap.

### Scope note: status-check CI gate

The `status-check` job now includes `integration_tests`, `e2e_tests`, and `helm` in its `needs` list. The `helm` job is new in this PR. The `integration_tests` and `e2e_tests` additions fix previously-missing gate checks — included here since this PR modifies both of those jobs to install Helm.

### Quality gates

- `nox -e lint` 
- `nox -e typecheck` 
- `nox -e unit_tests`  (12,321 scenarios passed, 4 skipped)
- `nox -e integration_tests` — 3 pre-existing failures in unrelated areas (plan correction, resource types)
- `nox -e e2e_tests` — pre-existing failures (LLM API keys not available in local env)
- `nox -e coverage_report`  (**97.7%**)

Reviewed-on: cleveragents/cleveragents-core#1085
Reviewed-by: Jeffrey Phillips Freeman <jeffrey.freeman@cleverthis.com>
Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-03-27 23:53:22 +00:00
brent.edwards 00897be24a feat(ci): CI/CD pipeline definitions (#983)
## Summary

Complete CI/CD pipeline definitions: release workflow, caching, status-check consolidation, and documentation.

### Changes

**New: Release pipeline** (`.forgejo/workflows/release.yml`):
- Triggered on `v*` tags
- 3 jobs: `build-wheel` → `build-docker` → `create-release`
- Builds wheel via `nox -s build`, Docker image via multi-stage Dockerfile
- Creates Forgejo release via API with wheel artifact attached
- Configurable registry push via `REGISTRY_*` secrets

**Updated: CI pipeline** (`.forgejo/workflows/ci.yml`):
- Added `actions/cache@v3` for `~/.cache/uv` on all 8 primary jobs (keyed on `pyproject.toml` hash)
- Added `status-check` consolidation job depending on all required checks — single gate for branch protection

**Updated: CONTRIBUTING.md**:
- New CI/CD section: pipeline overview, job table, required merge checks, release process, secrets documentation

**Tests**:
- 13 new Behave scenarios validating workflow YAML structure, tag triggers, job definitions, dependencies
- 9 new Robot tests validating file existence, content, nox session references

### Quality Gates

| Session | Result |
|---|---|
| `nox -s lint` | PASS |
| `nox -s typecheck` | PASS (0 errors) |
| `nox -s unit_tests` | PASS (10,819 scenarios) |
| `nox -s coverage_report` | 97.9% (>= 97%) |

Closes #858

Reviewed-on: cleveragents/cleveragents-core#983
Co-authored-by: Brent E. Edwards <brent.edwards@cleverthis.com>
Co-committed-by: Brent E. Edwards <brent.edwards@cleverthis.com>
2026-03-21 00:29:49 +00:00
CoreRasurae d206b0c5e6 ci: Use docker-benchmark runner for benchmark-publish job
Job takes more time to run,  needing a dedicated runner

ISSUES CLOSED: #1083
2026-03-20 19:33:18 +00:00
CoreRasurae 2809b72b48 ci: Use docker-benchmark runner for benchmark-regression jon
Job takes longes and uses a dedicated runner

ISSUES CLOSED: #1081
2026-03-20 17:23:16 +00:00
freemo ce722ed0ea ops(ci): configure LLM API keys in Forgejo CI for integration test execution
Updated CI pipeline to inject ANTHROPIC_API_KEY and OPENAI_API_KEY
secrets as environment variables during Robot Framework integration
test execution. Added CI setup documentation.

ISSUES CLOSED: #701
2026-03-14 22:34:18 +00:00
freemo d4a1a0d87b test(e2e): set up E2E test infrastructure — nox session, CI job, Robot Framework @E2E tag
Added dedicated E2E test infrastructure completely separate from the existing
integration test suite. E2E tests use zero mocking — they exercise the real
CleverAgents CLI with real LLM API keys.

Key changes:
- New e2e_tests nox session running Robot Framework with --include E2E tag
  filter against robot/e2e/ directory. Uses sequential robot (not pabot)
  since E2E tests hit real API endpoints with rate limits. Propagates
  ANTHROPIC_API_KEY, OPENAI_API_KEY, and GOOGLE_API_KEY from environment.
  Output goes to build/reports/robot-e2e/ to avoid artifact collisions.
- Existing integration_tests session now excludes E2E-tagged tests via
  --exclude E2E on the pabot invocation.
- New robot/e2e/common_e2e.resource provides shared E2E keywords: suite
  setup/teardown with per-suite isolation (no mock AI), graceful skip when
  LLM API keys are absent, CLI runner keyword, flexible output assertions,
  and temporary git repo fixture creation.
- Minimal smoke test (robot/e2e/smoke_test.robot) validates the harness by
  running agents --version and agents --help. Does not require LLM keys.
- Dedicated e2e_tests CI job in .forgejo/workflows/ci.yml injects LLM API
  keys from Forgejo secrets. Runs independently (no needs dependencies)
  and does not block regular CI.
- e2e_tests is deliberately NOT in the default nox sessions list since it
  requires real API keys not present in all environments.

ISSUES CLOSED: #740
2026-03-12 21:11:37 +00:00
freemo 74772280e6 perf(tests): optimize coverage instrumentation and reporting pipeline
Replace coverage.py (sys.settrace-based) with slipcover (bytecode-based
instrumentation) for significantly faster coverage collection:

- Each behave-parallel worker runs under slipcover, producing per-feature
  JSON coverage files with unique UUIDs to avoid write contention.
- After all workers finish, slipcover --merge combines per-worker data
  into a single build/coverage.json report.
- XML report generated via slipcover --merge --xml for CI tooling.
- Terminal report with --fail-under=97 threshold enforcement.
- Robust JSON key-fallback logic handles both slipcover and coverage.py
  output formats.
- CI workflow (ci.yml, nightly-quality.yml) updated with defensive key
  lookup instead of hardcoded coverage.py format.
- Documentation updated to reflect slipcover as the coverage tool.
- CHANGELOG.md updated.

ISSUES CLOSED: #482
2026-03-02 02:01:27 +00:00
CoreRasurae d37cfbe769 test(robot): fix failing integration tests related to safe.directory config and git version 2026-02-21 18:11:31 +00:00
brent.edwards 53902ba718 ci(CI.yml): code changes against develop will run CI
Added `develop-*` to the list of things that run CI
2026-02-19 22:50:30 +00:00
mngrif f727baf5ea testing airspeedvelocity 2026-02-19 13:24:00 -05:00
mngrif 65efa4bc9e testing airspeedvelocity 2026-02-19 12:17:03 -05:00
mngrif d5af40eefd Merge branch 'master' into mngrif-asv-test 2026-02-19 00:03:54 +00:00
mngrif 805a4b9374 testing airspeedvelocity 2026-02-18 18:49:45 -05:00
mngrif e25d73cca0 testing airspeedvelocity 2026-02-18 18:40:44 -05:00
mngrif c4c4fd1544 testing airspeedvelocity 2026-02-18 17:57:27 -05:00
mngrif f9f4503c6c testing airspeedvelocity 2026-02-18 17:45:07 -05:00
mngrif 3960385491 testing airspeedvelocity 2026-02-18 17:41:45 -05:00
mngrif de447d4bd7 testing airspeedvelocity 2026-02-18 17:33:45 -05:00
mngrif 114c798e61 testing airspeedvelocity 2026-02-18 15:22:22 -05:00
mngrif 05f4007462 testing airspeedvelocity 2026-02-18 15:21:22 -05:00
mngrif e9530ffae0 testing airspeedvelocity 2026-02-18 15:13:22 -05:00
mngrif 7c30e5bb6e testing airspeedvelocity 2026-02-18 15:09:39 -05:00
mngrif 8ea70953e9 testing airspeedvelocity 2026-02-18 15:02:15 -05:00
mngrif 41e02ca01c testing airspeedvelocity 2026-02-18 12:51:02 -05:00
mngrif 86604db0d1 testing airspeedvelocity 2026-02-18 10:04:27 -05:00
mngrif 2f74726509 testing airspeedvelocity 2026-02-18 09:57:50 -05:00
mngrif 642f757d02 testing airspeedvelocity 2026-02-17 15:59:21 -05:00
mngrif fb055193c5 testing airspeedvelocity 2026-02-17 15:43:46 -05:00
mngrif 033bfd04a7 testing airspeedvelocity 2026-02-17 15:30:07 -05:00
mngrif 1f0db6e43a testing airspeedvelocity 2026-02-17 14:36:07 -05:00
mngrif f07afb23c7 testing airspeedvelocity 2026-02-17 14:15:04 -05:00
mngrif 8e2cd0f2e8 testing airspeedvelocity 2026-02-17 14:12:52 -05:00
mngrif 4b4df78ff9 testing airspeedvelocity 2026-02-17 14:10:16 -05:00
mngrif b0cb67163c testing airspeedvelocity 2026-02-17 14:01:09 -05:00
brent.edwards 9e86e5e866 fix(ci): create build dir before tee in coverage job 2026-02-14 00:50:25 +00:00
brent.edwards 35c74d1a52 feat(qa): enforce coverage >=97% in CI 2026-02-13 18:54:15 +00:00
brent.edwards bb09434d5e chore(ci): pin ruff version in nox and nightly workflow
Ensures linting uses the same ruff version range in CI and nightly
jobs to avoid rule drift from latest releases.
2026-02-13 04:57:01 +00:00
brent.edwards 3e3530de48 ci(git-merge): Merging from master 2026-02-12 23:01:35 +00:00
brent.edwards e801eb1ee8 feat(ci): add nox-based PR validation workflow
- Rewrite .forgejo/workflows/ci.yml to route all jobs through nox sessions
- Fix coverage_report nox session: serial behave mode replaces broken parallel
  mode (22% -> 97% accuracy), raise fail-under from 85% to 97%
- Pass posargs through format nox session for CI --check support
- Add 11 CI workflow validation scenarios (Behave) + Robot smoke test + ASV bench
- Add 108 new Behave scenarios covering 6 largest coverage gaps to reach 97%:
  yaml_template_engine, actor/config, actor/registry, message_router,
  context_analysis, context_service
- Update docs/development/ci-cd.md with nox-based CI docs and 97% threshold
- Restore implementation_plan.md verbose style, check off completed CI tasks

Verified: 1673 scenarios pass, 97% coverage, lint clean, typecheck clean
2026-02-12 22:01:51 +00:00
CoreRasurae 5d1825fb60 ci: CI jobs need to have git command
Some tests require it
2026-02-12 20:20:00 +00:00
brent.edwards d0f1c8bae3 fix(ci): use docker:dind as main container instead of services
Forgejo act_runner service container networking fails with 'network not
found'. Use docker:dind directly with --privileged and start dockerd
inline to avoid the services networking issue.
2026-02-12 06:26:56 +00:00
brent.edwards 945cced381 fix(ci): fix docker build job and Dockerfile
- Add DinD service container and docker:cli image so docker CLI is available
- Fix Dockerfile: remove missing uv.lock, fix build order (copy source before build)
- Remove helm job (k8s/ directory does not exist yet)
2026-02-12 06:17:36 +00:00