Merge pull request #390 from Hawksight-AI/utils

ci: Optimize CI/CD Workflows — Scope Triggers to Avoid Redundant Runs
This commit is contained in:
Mohd Kaif
2026-03-18 01:12:44 +05:30
committed by GitHub
10 changed files with 71 additions and 25 deletions
+7 -3
View File
@@ -2,9 +2,13 @@ name: Semantica Performance Suite
on:
push:
branches: [main, master]
pull_request:
branches: [main, master]
branches: [main]
paths-ignore:
- 'docs/**'
- 'mkdocs.yml'
- 'requirements-docs.txt'
- '**/*.md'
workflow_dispatch:
jobs:
performance-test:
+10
View File
@@ -3,8 +3,18 @@ name: CI
on:
push:
branches: [main]
paths-ignore:
- 'docs/**'
- 'mkdocs.yml'
- 'requirements-docs.txt'
- '**/*.md'
pull_request:
branches: [main]
paths-ignore:
- 'docs/**'
- 'mkdocs.yml'
- 'requirements-docs.txt'
- '**/*.md'
jobs:
build:
+2 -1
View File
@@ -8,11 +8,12 @@ on:
branches: [main]
paths:
- 'docs/**'
- 'semantica/**'
- 'mkdocs.yml'
- 'requirements-docs.txt'
- 'CHANGELOG.md'
- 'RELEASE.md'
release:
types: [published]
workflow_dispatch:
# Permissions needed to deploy to GitHub Pages
+13 -3
View File
@@ -4,9 +4,19 @@ on:
schedule:
- cron: '30 1 * * 1,4' # Mon/Thu 7 AM IST
push:
branches: [ main ]
branches: [main]
paths-ignore:
- 'docs/**'
- 'mkdocs.yml'
- 'requirements-docs.txt'
- '**/*.md'
pull_request:
branches: [ main ]
branches: [main]
paths-ignore:
- 'docs/**'
- 'mkdocs.yml'
- 'requirements-docs.txt'
- '**/*.md'
jobs:
security-scan:
@@ -158,7 +168,7 @@ jobs:
}
// Create summary comment
const comment = `# 🔒 Security Scan Results\\n\\n${safetyResults}\\n\\n${banditResults}\\n\\n${semgrepResults}\\n\\n---\\n\\n*This security scan runs automatically on every PR and bi-weekly.*\\n\\n📊 **Security Policy**: CI fails on vulnerabilities and HIGH severity issues.`;
const comment = `# 🔒 Security Scan Results\\n\\n${safetyResults}\\n\\n${banditResults}\\n\\n${semgrepResults}\\n\\n---\\n\\n*This security scan runs automatically on source-code PRs and bi-weekly (skipped for doc/markdown-only changes).*\\n\\n📊 **Security Policy**: CI fails on vulnerabilities and HIGH severity issues.`;
// Post comment with error handling
try {
+3
View File
@@ -220,3 +220,6 @@ profile = "black"
[tool.pytest.ini_options]
testpaths = ["tests"]
markers = [
"integration: marks tests that require external services or API keys (deselect with '-m not integration')",
]
+4 -3
View File
@@ -951,10 +951,11 @@ class DecisionQuery:
for measure_type, measure_data in centrality_measures.items():
if isinstance(measure_data, dict) and 'centrality' in measure_data:
decision_measures[measure_type] = measure_data['centrality'].get(decision_id, 0.0)
val = measure_data['centrality'].get(decision_id, 0.0)
decision_measures[measure_type] = val if isinstance(val, (int, float)) else 0.0
analysis["centrality_measures"] = decision_measures
# Calculate overall influence score
measures = analysis["centrality_measures"]
analysis["influence_score"] = (
+16 -8
View File
@@ -34,10 +34,6 @@ from datetime import datetime
from typing import Any, Dict, List, Optional
from urllib.parse import urlparse
import sqlalchemy
from sqlalchemy import create_engine, inspect, text
from sqlalchemy.engine import Engine
from ..utils.exceptions import ProcessingError, ValidationError
from ..utils.logging import get_logger
from ..utils.progress_tracker import get_progress_tracker
@@ -101,13 +97,13 @@ class DatabaseConnector:
self.logger = get_logger("database_connector")
self.db_type = db_type.lower() if db_type else ""
self.config = config
self.engine: Optional[Engine] = None
self.engine: Optional[Any] = None
self.logger.debug(
f"Database connector initialized: db_type={db_type or 'auto-detect'}"
)
def connect(self, connection_string: str) -> Engine:
def connect(self, connection_string: str) -> Any:
"""
Establish database connection.
@@ -129,6 +125,14 @@ class DatabaseConnector:
ProcessingError: If connection fails or database type is unsupported
"""
try:
try:
from sqlalchemy import create_engine, text
except ImportError:
raise ProcessingError(
"sqlalchemy is required for database ingestion. "
"Install with: pip install sqlalchemy"
)
# Parse connection string to detect database type
parsed = urlparse(connection_string)
@@ -188,6 +192,7 @@ class DatabaseConnector:
bool: True if connection successful, False otherwise
"""
try:
from sqlalchemy import create_engine, text
engine = create_engine(connection_string)
with engine.connect() as conn:
conn.execute(text("SELECT 1"))
@@ -226,7 +231,7 @@ class DataExporter:
def export_table_data(
self,
connection: Engine,
connection: Any,
table_name: str,
schema: Optional[str] = None,
limit: Optional[int] = None,
@@ -264,6 +269,7 @@ class DataExporter:
ProcessingError: If table export fails
"""
try:
from sqlalchemy import inspect
inspector = inspect(connection)
# Get column information
@@ -379,7 +385,7 @@ class DataExporter:
return transformed
def export_schema(
self, connection: Engine, schema: Optional[str] = None
self, connection: Any, schema: Optional[str] = None
) -> Dict[str, Any]:
"""
Export database schema information.
@@ -406,6 +412,7 @@ class DataExporter:
ProcessingError: If schema export fails
"""
try:
from sqlalchemy import inspect
inspector = inspect(connection)
schema_info = {"tables": [], "views": [], "foreign_keys": []}
@@ -591,6 +598,7 @@ class DBIngestor:
schema = self.analyze_schema(connection_string)
# Get all table names
from sqlalchemy import inspect
inspector = inspect(engine)
all_tables = inspector.get_table_names()
+7 -3
View File
@@ -33,9 +33,6 @@ from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Dict, List, Optional, Union
import pdfplumber
from PIL import Image
from ..utils.exceptions import ProcessingError, ValidationError
from ..utils.logging import get_logger
from ..utils.progress_tracker import get_progress_tracker
@@ -119,6 +116,13 @@ class PDFParser:
raise ValidationError(f"File is not a PDF: {file_path}")
try:
try:
import pdfplumber
except ImportError:
raise ProcessingError(
"pdfplumber is required for PDF parsing. "
"Install with: pip install pdfplumber"
)
with pdfplumber.open(str(file_path)) as pdf:
# Extract metadata
metadata = self._extract_metadata(pdf)
+8 -3
View File
@@ -32,8 +32,6 @@ from dataclasses import dataclass, field
from pathlib import Path
from typing import Any, Dict, List, Optional, Union
from pptx import Presentation
from ..utils.exceptions import ProcessingError, ValidationError
from ..utils.logging import get_logger
from ..utils.progress_tracker import get_progress_tracker
@@ -97,6 +95,13 @@ class PPTXParser:
raise ValidationError(f"File is not a PPTX: {file_path}")
try:
try:
from pptx import Presentation
except ImportError:
raise ProcessingError(
"python-pptx is required for PPTX parsing. "
"Install with: pip install python-pptx"
)
prs = Presentation(str(file_path))
# Extract metadata
@@ -220,7 +225,7 @@ class PPTXParser:
images=images,
)
def _extract_metadata(self, prs: Presentation) -> Dict[str, Any]:
def _extract_metadata(self, prs: Any) -> Dict[str, Any]:
"""Extract presentation metadata."""
metadata = {}
+1 -1
View File
@@ -11,7 +11,7 @@ from semantica.semantic_extract.methods import (
extract_triplets_llm,
)
from semantica.semantic_extract.providers import create_provider
from semantica.semantic_extract.models import Entity
from semantica.semantic_extract import Entity
NOVITA_API_KEY = os.environ.get("NOVITA_API_KEY")
NOVITA_MODEL = "deepseek/deepseek-v3.2"