ci: enable ruff linting and pytest in CI pipeline
Uncomment the ruff check and pytest steps in the Gitea Actions build workflow so that linting violations and test failures block image builds. Fix all pre-existing ruff violations (E402 import ordering in analyzer.py, F821 undefined name in api.py, I001 unsorted imports in test files, F401 unused import in test_rate_limit.py). Closes leeworks-agents/SPARC#1559 Closes leeworks-agents/SPARC#1560 Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
This commit is contained in:
+15
-14
@@ -28,10 +28,10 @@ jobs:
|
|||||||
run: |
|
run: |
|
||||||
pip3 install -r requirements.txt ruff
|
pip3 install -r requirements.txt ruff
|
||||||
|
|
||||||
# - name: Run ruff linter
|
- name: Run ruff linter
|
||||||
# shell: sh
|
shell: sh
|
||||||
# run: |
|
run: |
|
||||||
# ruff check SPARC/ tests/
|
ruff check SPARC/ tests/
|
||||||
|
|
||||||
- name: Install Node.js and check TypeScript types
|
- name: Install Node.js and check TypeScript types
|
||||||
shell: sh
|
shell: sh
|
||||||
@@ -47,16 +47,17 @@ jobs:
|
|||||||
fi
|
fi
|
||||||
npx tsc --noEmit
|
npx tsc --noEmit
|
||||||
|
|
||||||
# - name: Run pytest
|
- name: Run pytest
|
||||||
# shell: sh
|
shell: sh
|
||||||
# env:
|
env:
|
||||||
# DATABASE_URL: "sqlite://"
|
DATABASE_URL: "sqlite://"
|
||||||
# API_KEY: "test-key"
|
API_KEY: "test-key"
|
||||||
# OPENROUTER_API_KEY: "test-key"
|
OPENROUTER_API_KEY: "test-key"
|
||||||
# JWT_SECRET: "test-secret-for-ci"
|
JWT_SECRET: "test-secret-for-ci"
|
||||||
# APP_ENV: "development"
|
APP_ENV: "development"
|
||||||
# run: |
|
run: |
|
||||||
# python3 -m pytest tests/ -v --tb=short -x
|
pip3 install pytest
|
||||||
|
python3 -m pytest tests/ -v --tb=short -x
|
||||||
|
|
||||||
build-api:
|
build-api:
|
||||||
needs: test
|
needs: test
|
||||||
|
|||||||
+2
-2
@@ -10,13 +10,13 @@ from concurrent.futures import ThreadPoolExecutor, as_completed
|
|||||||
from typing import Callable
|
from typing import Callable
|
||||||
|
|
||||||
from SPARC import config
|
from SPARC import config
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
|
||||||
from SPARC.database import DatabaseClient
|
from SPARC.database import DatabaseClient
|
||||||
from SPARC.llm import LLMAnalyzer
|
from SPARC.llm import LLMAnalyzer
|
||||||
from SPARC.serp_api import SERP
|
from SPARC.serp_api import SERP
|
||||||
from SPARC.types import BatchAnalysisResult, CompanyAnalysisResult, Patent, Patents
|
from SPARC.types import BatchAnalysisResult, CompanyAnalysisResult, Patent, Patents
|
||||||
|
|
||||||
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
class CompanyAnalyzer:
|
class CompanyAnalyzer:
|
||||||
"""Orchestrates end-to-end company performance analysis via patents."""
|
"""Orchestrates end-to-end company performance analysis via patents."""
|
||||||
|
|||||||
+6
-2
@@ -3,9 +3,14 @@
|
|||||||
Provides REST API endpoints for analyzing company patent portfolios.
|
Provides REST API endpoints for analyzing company patent portfolios.
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
from contextlib import asynccontextmanager
|
from contextlib import asynccontextmanager
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
from typing import Annotated, List
|
from typing import TYPE_CHECKING, Annotated, List
|
||||||
|
|
||||||
|
if TYPE_CHECKING:
|
||||||
|
from SPARC.database import DatabaseClient
|
||||||
|
|
||||||
from fastapi import BackgroundTasks, Depends, FastAPI, HTTPException, Query, Request
|
from fastapi import BackgroundTasks, Depends, FastAPI, HTTPException, Query, Request
|
||||||
from fastapi.middleware.cors import CORSMiddleware
|
from fastapi.middleware.cors import CORSMiddleware
|
||||||
@@ -653,7 +658,6 @@ async def export_company_pdf(
|
|||||||
PDF file download
|
PDF file download
|
||||||
"""
|
"""
|
||||||
import io
|
import io
|
||||||
import textwrap
|
|
||||||
|
|
||||||
from reportlab.lib import colors
|
from reportlab.lib import colors
|
||||||
from reportlab.lib.pagesizes import letter
|
from reportlab.lib.pagesizes import letter
|
||||||
|
|||||||
@@ -175,6 +175,7 @@ class TestGetMe:
|
|||||||
from datetime import timedelta
|
from datetime import timedelta
|
||||||
|
|
||||||
import jwt as pyjwt
|
import jwt as pyjwt
|
||||||
|
|
||||||
from SPARC.auth import JWT_ALGORITHM, JWT_SECRET
|
from SPARC.auth import JWT_ALGORITHM, JWT_SECRET
|
||||||
|
|
||||||
payload = {
|
payload = {
|
||||||
|
|||||||
@@ -1,7 +1,8 @@
|
|||||||
"""Tests for rate limiting on auth endpoints."""
|
"""Tests for rate limiting on auth endpoints."""
|
||||||
|
|
||||||
|
from unittest.mock import MagicMock, patch
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from unittest.mock import Mock, patch, MagicMock
|
|
||||||
from fastapi.testclient import TestClient
|
from fastapi.testclient import TestClient
|
||||||
|
|
||||||
from SPARC.api import app
|
from SPARC.api import app
|
||||||
|
|||||||
@@ -14,6 +14,7 @@ class TestJWTSecretStartupCheck:
|
|||||||
with patch.dict(os.environ, {"APP_ENV": "production"}):
|
with patch.dict(os.environ, {"APP_ENV": "production"}):
|
||||||
# Reload config to pick up the new APP_ENV
|
# Reload config to pick up the new APP_ENV
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
import SPARC.config
|
import SPARC.config
|
||||||
importlib.reload(SPARC.config)
|
importlib.reload(SPARC.config)
|
||||||
|
|
||||||
@@ -31,6 +32,7 @@ class TestJWTSecretStartupCheck:
|
|||||||
"""Starting with default secret and APP_ENV=development must not raise."""
|
"""Starting with default secret and APP_ENV=development must not raise."""
|
||||||
with patch.dict(os.environ, {"APP_ENV": "development"}):
|
with patch.dict(os.environ, {"APP_ENV": "development"}):
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
import SPARC.config
|
import SPARC.config
|
||||||
importlib.reload(SPARC.config)
|
importlib.reload(SPARC.config)
|
||||||
|
|
||||||
@@ -46,6 +48,7 @@ class TestJWTSecretStartupCheck:
|
|||||||
"""Starting with a custom secret in production must not raise."""
|
"""Starting with a custom secret in production must not raise."""
|
||||||
with patch.dict(os.environ, {"APP_ENV": "production"}):
|
with patch.dict(os.environ, {"APP_ENV": "production"}):
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
import SPARC.config
|
import SPARC.config
|
||||||
importlib.reload(SPARC.config)
|
importlib.reload(SPARC.config)
|
||||||
|
|
||||||
@@ -65,6 +68,7 @@ class TestJWTSecretStartupCheck:
|
|||||||
env.pop("APP_ENV", None)
|
env.pop("APP_ENV", None)
|
||||||
with patch.dict(os.environ, env, clear=True):
|
with patch.dict(os.environ, env, clear=True):
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
import SPARC.config
|
import SPARC.config
|
||||||
importlib.reload(SPARC.config)
|
importlib.reload(SPARC.config)
|
||||||
|
|
||||||
@@ -84,6 +88,7 @@ class TestCORSConfig:
|
|||||||
"""When CORS_ORIGINS is unset, defaults to localhost origins."""
|
"""When CORS_ORIGINS is unset, defaults to localhost origins."""
|
||||||
with patch.dict(os.environ, {"CORS_ORIGINS": ""}):
|
with patch.dict(os.environ, {"CORS_ORIGINS": ""}):
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
import SPARC.config
|
import SPARC.config
|
||||||
importlib.reload(SPARC.config)
|
importlib.reload(SPARC.config)
|
||||||
assert SPARC.config.cors_origins == [
|
assert SPARC.config.cors_origins == [
|
||||||
@@ -95,6 +100,7 @@ class TestCORSConfig:
|
|||||||
"""Setting CORS_ORIGINS configures allowed origins."""
|
"""Setting CORS_ORIGINS configures allowed origins."""
|
||||||
with patch.dict(os.environ, {"CORS_ORIGINS": "https://sparc.example.com,https://app.example.com"}):
|
with patch.dict(os.environ, {"CORS_ORIGINS": "https://sparc.example.com,https://app.example.com"}):
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
import SPARC.config
|
import SPARC.config
|
||||||
importlib.reload(SPARC.config)
|
importlib.reload(SPARC.config)
|
||||||
assert SPARC.config.cors_origins == [
|
assert SPARC.config.cors_origins == [
|
||||||
@@ -109,6 +115,7 @@ class TestCORSConfig:
|
|||||||
"""A single origin without comma works correctly."""
|
"""A single origin without comma works correctly."""
|
||||||
with patch.dict(os.environ, {"CORS_ORIGINS": "https://sparc.example.com"}):
|
with patch.dict(os.environ, {"CORS_ORIGINS": "https://sparc.example.com"}):
|
||||||
import importlib
|
import importlib
|
||||||
|
|
||||||
import SPARC.config
|
import SPARC.config
|
||||||
importlib.reload(SPARC.config)
|
importlib.reload(SPARC.config)
|
||||||
assert SPARC.config.cors_origins == ["https://sparc.example.com"]
|
assert SPARC.config.cors_origins == ["https://sparc.example.com"]
|
||||||
|
|||||||
Reference in New Issue
Block a user