Skip to content

Commit a6be6d1

Browse files
committed
Adding pipeline v1.3.0
1 parent b62cb79 commit a6be6d1

44 files changed

Lines changed: 992 additions & 133 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

.github/workflows/ci.yml

Lines changed: 59 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,59 @@
1+
name: CI
2+
3+
on:
4+
push:
5+
branches: [main]
6+
pull_request:
7+
branches: [main]
8+
9+
jobs:
10+
lint:
11+
name: Lint (ruff)
12+
runs-on: ubuntu-latest
13+
steps:
14+
- uses: actions/checkout@v4
15+
- uses: astral-sh/ruff-action@v3
16+
with:
17+
args: "check"
18+
19+
type-check:
20+
name: Type check (pyright)
21+
runs-on: ubuntu-latest
22+
steps:
23+
- uses: actions/checkout@v4
24+
- uses: actions/setup-python@v5
25+
with:
26+
python-version: "3.12"
27+
cache: "pip"
28+
- name: Install dependencies
29+
run: pip install -r requirements.txt
30+
- name: Run pyright on input_models/
31+
run: pyright
32+
33+
test:
34+
name: Tests
35+
runs-on: ubuntu-latest
36+
steps:
37+
- uses: actions/checkout@v4
38+
- uses: actions/setup-python@v5
39+
with:
40+
python-version: "3.12"
41+
cache: "pip"
42+
- name: Install dependencies
43+
run: pip install -r requirements.txt
44+
- name: Run mock test suites
45+
run: pytest testing/mock/ -v --tb=short --timeout=30
46+
47+
coverage:
48+
name: Coverage
49+
runs-on: ubuntu-latest
50+
steps:
51+
- uses: actions/checkout@v4
52+
- uses: actions/setup-python@v5
53+
with:
54+
python-version: "3.12"
55+
cache: "pip"
56+
- name: Install dependencies
57+
run: pip install -r requirements.txt
58+
- name: Run tests with coverage
59+
run: pytest testing/mock/ --cov=. --cov-report=term-missing --timeout=30

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ __pycache__/
66
dist/
77
build/
88
.pytest_cache/
9+
.coverage
910
*.log
1011
logs/
1112
data/

cli/dblcheck.py

Lines changed: 7 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,17 +33,20 @@
3333
import logging
3434

3535
from core.logging_config import setup_logging
36+
3637
setup_logging()
3738
log = logging.getLogger("dblcheck.cli")
3839

3940
from validation.assertions import AssertionResult
4041
from validation.derivation import derive_assertions
41-
from validation.evaluator import evaluate
42-
from validation.report import format_text, format_run_dict
42+
from validation.evaluator import evaluate
43+
from validation.report import format_run_dict, format_text
44+
4345
# collector transitively imports core.inventory/netbox/vault/settings at module
4446
# scope; suppress the resulting INFO logs (startup banner shows the same info).
4547
logging.getLogger("dblcheck").setLevel(logging.WARNING)
46-
from validation.collector import collect_state
48+
from validation.collector import collect_state
49+
4750
logging.getLogger("dblcheck").setLevel(logging.INFO)
4851

4952
# ── Data directory paths ──────────────────────────────────────────────────────
@@ -272,8 +275,8 @@ def _build_parser() -> argparse.ArgumentParser:
272275

273276

274277
async def _run(args) -> int:
275-
from core.settings import USERNAME, PASSWORD
276278
from core.inventory import devices, inventory_source
279+
from core.settings import PASSWORD, USERNAME
277280
from core.vault import credential_source
278281

279282
def _fail(msg: str) -> None:

core/__init__.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,3 @@
11
from dotenv import load_dotenv
2+
23
load_dotenv()

core/logging_config.py

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,6 @@
1212
import os
1313
from datetime import datetime, timezone
1414

15-
1615
# Standard LogRecord attributes that should NOT be forwarded as extra JSON fields.
1716
_STANDARD_ATTRS = frozenset({
1817
"args", "created", "exc_info", "exc_text", "filename", "funcName",

dashboard/ws_bridge.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,8 @@
2626
import urllib.parse
2727
from pathlib import Path
2828

29-
from websockets.asyncio.server import serve, broadcast as ws_broadcast
29+
from websockets.asyncio.server import broadcast as ws_broadcast
30+
from websockets.asyncio.server import serve
3031
from websockets.datastructures import Headers
3132
from websockets.http11 import Response
3233

@@ -51,6 +52,7 @@
5152
# Stored in Vault at dblcheck/dashboard key "token", or DASHBOARD_TOKEN env var.
5253
sys.path.insert(0, str(PROJECT_DIR))
5354
from core.vault import get_secret as _get_secret
55+
5456
_DASHBOARD_TOKEN: str = _get_secret("dblcheck/dashboard", "token",
5557
fallback_env="DASHBOARD_TOKEN", quiet=True) or ""
5658

deploy/dblcheck_daemon.py

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313
import logging
1414
import os
1515
import sys
16-
from datetime import datetime, timezone, timedelta
16+
from datetime import datetime, timedelta, timezone
1717
from pathlib import Path
1818

1919
_PROJECT_ROOT = Path(__file__).resolve().parent.parent
@@ -22,6 +22,7 @@
2222
_STATE_FILE = _PROJECT_ROOT / "data" / "dashboard_state.json"
2323

2424
from core.logging_config import setup_logging
25+
2526
setup_logging()
2627

2728
log = logging.getLogger("dblcheck.daemon")
@@ -146,9 +147,14 @@ async def _validation_loop() -> None:
146147
async def _bridge() -> None:
147148
"""Run the WebSocket dashboard bridge."""
148149
from websockets.asyncio.server import serve
150+
149151
from dashboard.ws_bridge import (
150-
ws_handler, _http_handler, watch_state_file, PORT, HOST,
152+
HOST,
153+
PORT,
154+
_http_handler,
151155
register_stop_callback,
156+
watch_state_file,
157+
ws_handler,
152158
)
153159
register_stop_callback(request_stop)
154160
log.info("Dashboard bridge starting on port %d", PORT)

input_models/models.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
import json
77
import re
88
from typing import Literal
9-
from pydantic import BaseModel, Field, field_validator, model_validator
109

10+
from pydantic import BaseModel, Field, field_validator, model_validator
1111

1212
# Compiled patterns for parameter validation
1313
_VRF_RE = re.compile(r'^[a-zA-Z0-9_-]{1,32}$')

lab_configs/populate_netbox.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,8 @@
1818

1919
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
2020

21-
from dotenv import load_dotenv
2221
import pynetbox
22+
from dotenv import load_dotenv
2323

2424
from core.vault import get_secret
2525

pyproject.toml

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
[tool.ruff]
2+
line-length = 120
3+
target-version = "py312"
4+
5+
[tool.ruff.lint]
6+
select = [
7+
"E", # pycodestyle errors — style violations (indentation, whitespace, line length)
8+
"F", # pyflakes — logic errors (undefined names, unused imports, redefined variables)
9+
"W", # pycodestyle warnings — less severe style issues (trailing whitespace, blank lines)
10+
"I", # isort — import ordering and grouping
11+
]
12+
13+
[tool.ruff.lint.per-file-ignores]
14+
"testing/**" = ["E501"] # Allow long lines in test files (embedded CLI output fixtures)
15+
16+
# Entry-point files insert the project root into sys.path before importing project
17+
# modules — imports after sys.path manipulation are intentional (E402).
18+
"cli/dblcheck.py" = ["E402", "E501"] # sys.path insert + long diagnostic strings
19+
"server/MCPServer.py" = ["E402"]
20+
"deploy/dblcheck_daemon.py" = ["E402"]
21+
"dashboard/ws_bridge.py" = ["E402"]
22+
"testing/live/**" = ["E402"] # Live test files also manipulate sys.path
23+
"testing/mock/unit/test_vault.py" = ["E402"] # Loads real vault module via importlib
24+
"testing/mock/unit/test_jira_client.py" = ["E402"] # Loads real jira module via importlib
25+
26+
# Long lines in platform command maps and tool error messages are unavoidable —
27+
# breaking these strings across lines harms readability.
28+
"platforms/platform_map.py" = ["E501"]
29+
"tools/**" = ["E501"]
30+
31+
32+
[tool.pyright]
33+
include = ["input_models"]
34+
pythonVersion = "3.12"
35+
typeCheckingMode = "basic"

0 commit comments

Comments
 (0)