[BEZALEL][Epic-001] The Forge CI Pipeline — Gitea Actions + Smoke + Green E2E
Some checks failed
Forge CI / smoke-and-build (pull_request) Failing after 2s
Some checks failed
Forge CI / smoke-and-build (pull_request) Failing after 2s
- Add .gitea/workflows/ci.yml: Gitea Actions workflow for PR/push CI - Add scripts/smoke_test.py: fast smoke tests (<30s) for core imports and CLI entrypoints - Add tests/test_green_path_e2e.py: bare green-path e2e — terminal echo test - Total CI runtime target: <5 minutes - No API keys required for smoke/e2e stages Closes #145 /assign @bezalel
This commit is contained in:
49
.gitea/workflows/ci.yml
Normal file
49
.gitea/workflows/ci.yml
Normal file
@@ -0,0 +1,49 @@
|
||||
name: Forge CI
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
concurrency:
|
||||
group: forge-ci-${{ gitea.ref }}
|
||||
cancel-in-progress: true
|
||||
|
||||
jobs:
|
||||
smoke-and-build:
|
||||
runs-on: ubuntu-latest
|
||||
timeout-minutes: 5
|
||||
steps:
|
||||
- name: Checkout code
|
||||
uses: actions/checkout@v4
|
||||
|
||||
- name: Install uv
|
||||
uses: astral-sh/setup-uv@v5
|
||||
|
||||
- name: Set up Python 3.11
|
||||
run: uv python install 3.11
|
||||
|
||||
- name: Install package
|
||||
run: |
|
||||
uv venv .venv --python 3.11
|
||||
source .venv/bin/activate
|
||||
uv pip install -e ".[all,dev]"
|
||||
|
||||
- name: Smoke tests
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
python scripts/smoke_test.py
|
||||
env:
|
||||
OPENROUTER_API_KEY: ""
|
||||
OPENAI_API_KEY: ""
|
||||
NOUS_API_KEY: ""
|
||||
|
||||
- name: Green-path E2E
|
||||
run: |
|
||||
source .venv/bin/activate
|
||||
python -m pytest tests/test_green_path_e2e.py -q --tb=short
|
||||
env:
|
||||
OPENROUTER_API_KEY: ""
|
||||
OPENAI_API_KEY: ""
|
||||
NOUS_API_KEY: ""
|
||||
54
scripts/smoke_test.py
Executable file
54
scripts/smoke_test.py
Executable file
@@ -0,0 +1,54 @@
|
||||
#!/usr/bin/env python3
|
||||
"""Forge smoke tests — fast checks that core imports resolve and entrypoints load.
|
||||
|
||||
Total runtime target: < 30 seconds.
|
||||
"""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import importlib
|
||||
import subprocess
|
||||
import sys
|
||||
|
||||
CORE_MODULES = [
|
||||
"hermes_cli.config",
|
||||
"hermes_state",
|
||||
"model_tools",
|
||||
"toolsets",
|
||||
"utils",
|
||||
]
|
||||
|
||||
CLI_ENTRYPOINTS = [
|
||||
["python", "cli.py", "--help"],
|
||||
]
|
||||
|
||||
|
||||
def test_imports() -> None:
|
||||
for mod in CORE_MODULES:
|
||||
try:
|
||||
importlib.import_module(mod)
|
||||
except Exception as exc:
|
||||
print(f"FAIL: import {mod} -> {exc}")
|
||||
sys.exit(1)
|
||||
print(f"OK: {len(CORE_MODULES)} core imports")
|
||||
|
||||
|
||||
def test_cli_help() -> None:
|
||||
for cmd in CLI_ENTRYPOINTS:
|
||||
result = subprocess.run(cmd, capture_output=True, timeout=30)
|
||||
if result.returncode != 0:
|
||||
stderr = result.stderr.decode()[:200]
|
||||
print(f"FAIL: {' '.join(cmd)} -> {stderr}")
|
||||
sys.exit(1)
|
||||
print(f"OK: {len(CLI_ENTRYPOINTS)} CLI entrypoints")
|
||||
|
||||
|
||||
def main() -> int:
|
||||
test_imports()
|
||||
test_cli_help()
|
||||
print("Smoke tests passed.")
|
||||
return 0
|
||||
|
||||
|
||||
if __name__ == "__main__":
|
||||
raise SystemExit(main())
|
||||
18
tests/test_green_path_e2e.py
Normal file
18
tests/test_green_path_e2e.py
Normal file
@@ -0,0 +1,18 @@
|
||||
"""Bare green-path E2E — one happy-path tool call cycle.
|
||||
|
||||
Exercises the terminal tool directly and verifies the response structure.
|
||||
No API keys required. Runtime target: < 10 seconds.
|
||||
"""
|
||||
|
||||
import json
|
||||
|
||||
from tools.terminal_tool import terminal_tool
|
||||
|
||||
|
||||
def test_terminal_echo_green_path() -> None:
|
||||
"""terminal('echo hello') -> verify response contains 'hello' and exit_code 0."""
|
||||
result = terminal_tool(command="echo hello", timeout=10)
|
||||
data = json.loads(result)
|
||||
|
||||
assert data["exit_code"] == 0, f"Expected exit_code 0, got {data['exit_code']}"
|
||||
assert "hello" in data["output"], f"Expected 'hello' in output, got: {data['output']}"
|
||||
Reference in New Issue
Block a user