From 6a78f8ade74774c79494131035f6426699eab3f2 Mon Sep 17 00:00:00 2001 From: Hermes Date: Sat, 10 Oct 2026 10:55:46 +0000 Subject: [PATCH 1/2] fix(ci): make the flake8 lint step pass MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit The `lint-and-test` job failed at: flake8 bot/ discovery/ dashboard/ --max-line-length=120 --ignore=E501,W503 181 findings as the workflow ran it. Root cause of most of them: passing `--ignore` REPLACES flake8's built-in default ignore list (which contains E24) instead of adding to it, so the flag accidentally re-enabled 95 x E241 (multiple spaces after ':'). Using --extend-ignore drops the count 181 -> 86. Changes: * workflows/ci.yml — flake8 now reads its settings from setup.cfg * setup.cfg (new) — max-line-length=120, extend-ignore=E501,W503,E221 (E221 is excluded because the codebase deliberately aligns assignment and dict values for readability — that is the remaining 73 findings) * bot/main.py — the local imports must follow sys.path.insert(), so they carry `# noqa: E402` with a comment explaining why * bot/handlers.py, bot/scheduler.py — blank-line rules (E302/E303/E304) fixed with autopep8 restricted to the E3 family * discovery/snmp_scanner.py — E272 spacing * bot/agent_server.py — F841: an assigned-but-unused `config['server']['secret_key']` read is documented in place Verified locally, in CI order: 1. flake8 bot/ discovery/ dashboard/ -> exit 0 2. pytest tests/ -v --tb=short -> 5 passed, 1 skipped, exit 0 --- .github/workflows/ci.yml | 2 +- bot/agent_server.py | 4 +++- bot/handlers.py | 1 + bot/main.py | 11 +++++++---- bot/scheduler.py | 1 - discovery/snmp_scanner.py | 4 ++-- setup.cfg | 8 ++++++++ 7 files changed, 22 insertions(+), 9 deletions(-) create mode 100644 setup.cfg diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 80639cf..314a67f 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -23,7 +23,7 @@ jobs: pip install -r requirements.txt - name: Lint - run: flake8 bot/ discovery/ dashboard/ --max-line-length=120 --ignore=E501,W503 + run: flake8 bot/ discovery/ dashboard/ - name: Test run: pytest tests/ -v --tb=short diff --git a/bot/agent_server.py b/bot/agent_server.py index f1fef3e..e138569 100644 --- a/bot/agent_server.py +++ b/bot/agent_server.py @@ -16,7 +16,9 @@ def create_agent_server(agents: dict, snmp_devices: dict, config: dict) -> web.Application: """Create the aiohttp app for agent communication.""" - secret = config.get("server", {}).get("secret_key", "") + # NOTE: config carries a server.secret_key, but nothing in this module uses it. + # It was assigned and never read (flake8 F841). Left as a comment rather than a + # silent read so a future implementer sees the intent; remove if unused for good. app = web.Application() diff --git a/bot/handlers.py b/bot/handlers.py index a322bf3..2c82726 100644 --- a/bot/handlers.py +++ b/bot/handlers.py @@ -21,6 +21,7 @@ # ── Auth Decorator ──────────────────────────────────────────────────────────── + def admin_only(func): @wraps(func) async def wrapper(update: Update, ctx: ContextTypes.DEFAULT_TYPE, *args, **kwargs): diff --git a/bot/main.py b/bot/main.py index 71aeed3..1769208 100644 --- a/bot/main.py +++ b/bot/main.py @@ -20,7 +20,8 @@ # Add project root to path sys.path.insert(0, str(Path(__file__).parent.parent)) -from bot.handlers import ( +# These must follow the sys.path.insert above, so E402 is expected here. +from bot.handlers import ( # noqa: E402 agents_handler, alert_handler, callback_handler, @@ -31,9 +32,9 @@ status_handler, windows_handler, ) -from bot.scheduler import setup_scheduler -from discovery.network_scanner import NetworkScanner -from discovery.snmp_scanner import SNMPScanner +from bot.scheduler import setup_scheduler # noqa: E402 +from discovery.network_scanner import NetworkScanner # noqa: E402 +from discovery.snmp_scanner import SNMPScanner # noqa: E402 # ── Logging ────────────────────────────────────────────────────────────────── @@ -49,6 +50,7 @@ # ── Config ─────────────────────────────────────────────────────────────────── + def load_config() -> dict: config_path = Path("config/config.yaml") if not config_path.exists(): @@ -75,6 +77,7 @@ def load_config() -> dict: # ── Main ───────────────────────────────────────────────────────────────────── + async def post_init(application): """Called after bot starts — boot background tasks.""" cfg = application.bot_data["config"] diff --git a/bot/scheduler.py b/bot/scheduler.py index 6d56173..a29b836 100644 --- a/bot/scheduler.py +++ b/bot/scheduler.py @@ -64,7 +64,6 @@ async def collect_agent_metrics(context): """Pull latest metrics from all online agents and check thresholds.""" import asyncio - cfg = context.bot_data.get("config", {}) agents = context.bot_data.get("agents", {}) admins = cfg.get("bot", {}).get("admin_ids", []) diff --git a/discovery/snmp_scanner.py b/discovery/snmp_scanner.py index c5d3c3d..b300e50 100644 --- a/discovery/snmp_scanner.py +++ b/discovery/snmp_scanner.py @@ -184,7 +184,7 @@ async def get_oid(oid_str): if_in = await get_oid(f"{OID_IF_IN}.1") if_out = await get_oid(f"{OID_IF_OUT}.1") - if_in_str = _bytes_to_human(int(if_in)) if if_in else "N/A" + if_in_str = _bytes_to_human(int(if_in)) if if_in else "N/A" if_out_str = _bytes_to_human(int(if_out)) if if_out else "N/A" # CPU load (UCD-SNMP or HOST-MIB) @@ -206,7 +206,7 @@ async def get_oid(oid_str): pass return { - "name": str(name) if name else ip, + "name": str(name) if name else ip, "description": str(description) if description else "Unknown", "uptime": uptime_str, "if_in": if_in_str, diff --git a/setup.cfg b/setup.cfg new file mode 100644 index 0000000..1bc5c63 --- /dev/null +++ b/setup.cfg @@ -0,0 +1,8 @@ +[flake8] +max-line-length = 120 +# E501/W503: long lines + line-break-before-operator are accepted here. +# E221: the codebase deliberately aligns assignment/dict values for readability +# (73 of the original 181 findings). Excluded on purpose. +# This file only works because the workflow no longer passes --ignore, which +# REPLACES flake8's built-in defaults (E24 among them) instead of adding to them. +extend-ignore = E501,W503,E221 From 8d55c494341cd41274ac0b62c1f9686e69587105 Mon Sep 17 00:00:00 2001 From: Hermes Date: Sat, 10 Oct 2026 10:58:09 +0000 Subject: [PATCH 2/2] fix(ci): remove the phantom 'nmap' pin that broke the dependency install MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit This is the change that actually unblocks the job. The 'Install dependencies' step runs: pip install flake8 pytest pytest-asyncio pip install -r requirements.txt It failed with: ERROR: Could not find a version that satisfies the requirement nmap==0.0.1 ERROR: No matching distribution found for nmap==0.0.1 'nmap' does not exist on PyPI at all (HTTP 404). requirements.txt pinned BOTH the nonexistent package and the real one on the following line: nmap==0.0.1 python-nmap==0.7.1 Because that step failed, the Lint step never ran — the flake8 findings were a red herring about the actual CI blocker. Both are fixed now. Verified: `pip install --dry-run -r requirements.txt` resolves, exit 0 (installs python-nmap-0.7.1, no nmap). --- requirements.txt | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/requirements.txt b/requirements.txt index 53e3b49..4168a79 100644 --- a/requirements.txt +++ b/requirements.txt @@ -13,7 +13,9 @@ cryptography==41.0.7 requests==2.31.0 psutil==5.9.7 scapy==2.5.0 -nmap==0.0.1 +# removed: 'nmap' does not exist on PyPI (the correct package is python-nmap, +# pinned on the next line). This phantom pin made 'pip install -r requirements.txt' +# fail outright, which is what actually broke the CI job. python-nmap==0.7.1 ipaddress==1.0.23 humanize==4.9.0