-
Notifications
You must be signed in to change notification settings - Fork 1
fix: add missing belt workflows to template for consumer repos #963
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
7ae3cf3
e9635e8
cc5a864
b33a8e3
88b7e10
d9acaa1
a1eac76
74ae3c0
5aec033
3f835db
57c7d69
d3061a0
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,43 @@ | ||
| name: Health 73 Template Completeness | ||
|
|
||
| # Validates that workflows intended for consumer repos are in the template and manifest. | ||
| # This catches the case where a workflow is added to Workflows but not synced. | ||
|
|
||
| on: | ||
| push: | ||
| branches: [main] | ||
| paths: | ||
| - '.github/workflows/*.yml' | ||
| - 'templates/consumer-repo/.github/workflows/*.yml' | ||
| - '.github/sync-manifest.yml' | ||
| - 'scripts/validate_template_completeness.py' | ||
| pull_request: | ||
| paths: | ||
| - '.github/workflows/*.yml' | ||
| - 'templates/consumer-repo/.github/workflows/*.yml' | ||
| - '.github/sync-manifest.yml' | ||
| - 'scripts/validate_template_completeness.py' | ||
| workflow_dispatch: | ||
|
|
||
| permissions: | ||
| contents: read | ||
|
|
||
| jobs: | ||
| validate: | ||
| name: Check template completeness | ||
| runs-on: ubuntu-latest | ||
| steps: | ||
| - name: Checkout | ||
| uses: actions/checkout@v6 | ||
|
|
||
| - name: Setup Python | ||
| uses: actions/setup-python@v6 | ||
| with: | ||
| python-version: '3.12' | ||
|
|
||
| - name: Install dependencies | ||
| run: pip install pyyaml | ||
|
|
||
| - name: Validate template completeness | ||
| run: | | ||
| python scripts/validate_template_completeness.py --strict |
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,236 @@ | ||
| diff --git a/adapters/base.py b/adapters/base.py | ||
| index 93e845b..f4a4a64 100644 | ||
| --- a/adapters/base.py | ||
| +++ b/adapters/base.py | ||
| @@ -10,9 +10,11 @@ from importlib import import_module | ||
| from typing import Any, Protocol | ||
|
|
||
| try: | ||
| - import psycopg | ||
| + import psycopg as _psycopg | ||
| except ImportError: # pragma: no cover - optional dependency | ||
| - psycopg = None | ||
| + _psycopg = None # type: ignore[assignment] | ||
| + | ||
| +psycopg = _psycopg | ||
|
|
||
|
|
||
| class AdapterProtocol(Protocol): | ||
| @@ -77,7 +79,8 @@ async def tracked_call(source: str, endpoint: str, *, db_path: str | None = None | ||
| status = getattr(resp, "status_code", 0) | ||
| size = len(getattr(resp, "content", b"")) | ||
| conn = connect_db(db_path) | ||
| - conn.execute("""CREATE TABLE IF NOT EXISTS api_usage ( | ||
| + conn.execute( | ||
| + """CREATE TABLE IF NOT EXISTS api_usage ( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| ts TIMESTAMP DEFAULT CURRENT_TIMESTAMP, | ||
| source TEXT, | ||
| @@ -86,7 +89,8 @@ async def tracked_call(source: str, endpoint: str, *, db_path: str | None = None | ||
| bytes INT, | ||
| latency_ms INT, | ||
| cost_usd REAL | ||
| - )""") | ||
| + )""" | ||
| + ) | ||
| if isinstance(conn, sqlite3.Connection): | ||
| conn.execute( | ||
| "CREATE VIEW IF NOT EXISTS monthly_usage AS " | ||
| diff --git a/adapters/edgar.py b/adapters/edgar.py | ||
| index 4d4ba61..1d80aec 100644 | ||
| --- a/adapters/edgar.py | ||
| +++ b/adapters/edgar.py | ||
| @@ -45,6 +45,10 @@ async def _request_with_retry( | ||
| extra={"url": url, "attempt": attempt, "max_retries": max_retries}, | ||
| ) | ||
| await asyncio.sleep(wait) | ||
| + # Unreachable but satisfies type checker | ||
| + raise RuntimeError("Unreachable") # pragma: no cover | ||
| + # Unreachable but satisfies type checker | ||
| + raise RuntimeError("Unreachable") # pragma: no cover | ||
|
|
||
|
|
||
| async def list_new_filings(cik: str, since: str) -> list[dict[str, str]]: | ||
| diff --git a/api/chat.py b/api/chat.py | ||
| index e2be31d..0c81d91 100644 | ||
| --- a/api/chat.py | ||
| +++ b/api/chat.py | ||
| @@ -96,12 +96,7 @@ def chat( | ||
| q: str = Query( | ||
| ..., | ||
| description="User question", | ||
| - examples={ | ||
| - "basic": { | ||
| - "summary": "Holdings question", | ||
| - "value": "What is the latest holdings update?", | ||
| - } | ||
| - }, | ||
| + examples=["What is the latest holdings update?"], | ||
| ) | ||
| ): | ||
| """Return a naive answer built from stored documents.""" | ||
| diff --git a/api/managers.py b/api/managers.py | ||
| index 2a19661..5128f82 100644 | ||
| --- a/api/managers.py | ||
| +++ b/api/managers.py | ||
| @@ -88,19 +88,23 @@ def _ensure_manager_table(conn) -> None: | ||
| """Create the managers table if it does not exist.""" | ||
| # Use dialect-specific schema to keep SQLite and Postgres aligned. | ||
| if isinstance(conn, sqlite3.Connection): | ||
| - conn.execute("""CREATE TABLE IF NOT EXISTS managers ( | ||
| + conn.execute( | ||
| + """CREATE TABLE IF NOT EXISTS managers ( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| name TEXT NOT NULL, | ||
| email TEXT NOT NULL, | ||
| department TEXT NOT NULL | ||
| - )""") | ||
| + )""" | ||
| + ) | ||
| else: | ||
| - conn.execute("""CREATE TABLE IF NOT EXISTS managers ( | ||
| + conn.execute( | ||
| + """CREATE TABLE IF NOT EXISTS managers ( | ||
| id bigserial PRIMARY KEY, | ||
| name text NOT NULL, | ||
| email text NOT NULL, | ||
| department text NOT NULL | ||
| - )""") | ||
| + )""" | ||
| + ) | ||
|
|
||
|
|
||
| def _insert_manager(conn, payload: ManagerCreate) -> int: | ||
| @@ -111,7 +115,11 @@ def _insert_manager(conn, payload: ManagerCreate) -> int: | ||
| (payload.name, payload.email, payload.department), | ||
| ) | ||
| conn.commit() | ||
| - return int(cursor.lastrowid) | ||
| + return ( | ||
| + int(cursor.lastrowid) | ||
| + if cursor.lastrowid is not None | ||
| + else 0 if cursor.lastrowid is not None else 0 | ||
| + ) | ||
| cursor = conn.execute( | ||
| "INSERT INTO managers(name, email, department) VALUES (%s, %s, %s) RETURNING id", | ||
| (payload.name, payload.email, payload.department), | ||
| diff --git a/embeddings.py b/embeddings.py | ||
| index e75e3f8..2b7f76e 100644 | ||
| --- a/embeddings.py | ||
| +++ b/embeddings.py | ||
| @@ -51,22 +51,26 @@ def store_document(text: str, db_path: str | None = None) -> None: | ||
| if register_vector: | ||
| register_vector(conn) | ||
| conn.execute("CREATE EXTENSION IF NOT EXISTS vector") | ||
| - conn.execute("""CREATE TABLE IF NOT EXISTS documents ( | ||
| + conn.execute( | ||
| + """CREATE TABLE IF NOT EXISTS documents ( | ||
| id SERIAL PRIMARY KEY, | ||
| content TEXT, | ||
| embedding vector(384) | ||
| - )""") | ||
| + )""" | ||
| + ) | ||
| emb = Vector(embed_text(text)) if register_vector else embed_text(text) | ||
| conn.execute( | ||
| "INSERT INTO documents(content, embedding) VALUES (%s,%s)", | ||
| (text, emb), | ||
| ) | ||
| else: | ||
| - conn.execute("""CREATE TABLE IF NOT EXISTS documents ( | ||
| + conn.execute( | ||
| + """CREATE TABLE IF NOT EXISTS documents ( | ||
| id INTEGER PRIMARY KEY AUTOINCREMENT, | ||
| content TEXT, | ||
| embedding TEXT | ||
| - )""") | ||
| + )""" | ||
| + ) | ||
| emb = json.dumps(embed_text(text)) | ||
| conn.execute( | ||
| "INSERT INTO documents(content, embedding) VALUES (?, ?)", | ||
| diff --git a/etl/daily_diff_flow.py b/etl/daily_diff_flow.py | ||
| index 2cca646..918a0b9 100644 | ||
| --- a/etl/daily_diff_flow.py | ||
| +++ b/etl/daily_diff_flow.py | ||
| @@ -20,12 +20,14 @@ def compute(cik: str, date: str, db_path: str) -> None: | ||
| try: | ||
| additions, exits = diff_holdings(cik, db_path) | ||
| conn = connect_db(db_path) | ||
| - conn.execute("""CREATE TABLE IF NOT EXISTS daily_diff ( | ||
| + conn.execute( | ||
| + """CREATE TABLE IF NOT EXISTS daily_diff ( | ||
| date TEXT, | ||
| cik TEXT, | ||
| cusip TEXT, | ||
| change TEXT | ||
| - )""") | ||
| + )""" | ||
| + ) | ||
| for cusip in additions: | ||
| conn.execute( | ||
| "INSERT INTO daily_diff VALUES (?,?,?,?)", | ||
| diff --git a/etl/edgar_flow.py b/etl/edgar_flow.py | ||
| index 6bd964d..6860cb0 100644 | ||
| --- a/etl/edgar_flow.py | ||
| +++ b/etl/edgar_flow.py | ||
| @@ -38,7 +38,8 @@ logger = logging.getLogger(__name__) | ||
| async def fetch_and_store(cik: str, since: str): | ||
| filings = await ADAPTER.list_new_filings(cik, since) | ||
| conn = connect_db(DB_PATH) | ||
| - conn.execute(""" | ||
| + conn.execute( | ||
| + """ | ||
| CREATE TABLE IF NOT EXISTS holdings ( | ||
| cik TEXT, | ||
| accession TEXT, | ||
| @@ -48,7 +49,8 @@ async def fetch_and_store(cik: str, since: str): | ||
| value INTEGER, | ||
| sshPrnamt INTEGER | ||
| ) | ||
| - """) | ||
| + """ | ||
| + ) | ||
| results = [] | ||
| for filing in filings: | ||
| raw = await ADAPTER.download(filing) | ||
| diff --git a/etl/logging_setup.py b/etl/logging_setup.py | ||
| index d05d4d6..b49c500 100644 | ||
| --- a/etl/logging_setup.py | ||
| +++ b/etl/logging_setup.py | ||
| @@ -10,9 +10,11 @@ from typing import Any | ||
| import boto3 | ||
|
|
||
| try: # pragma: no cover - optional dependency for structured logs | ||
| - from pythonjsonlogger import jsonlogger | ||
| + from pythonjsonlogger import jsonlogger as _jsonlogger | ||
| except ImportError: # pragma: no cover | ||
| - jsonlogger = None | ||
| + _jsonlogger = None # type: ignore[assignment] | ||
| + | ||
| +jsonlogger = _jsonlogger | ||
|
|
||
| _LOGGING_CONFIGURED = False | ||
|
|
||
| diff --git a/tests/test_open_issues.py b/tests/test_open_issues.py | ||
| index 2531bfc..f68beae 100644 | ||
| --- a/tests/test_open_issues.py | ||
| +++ b/tests/test_open_issues.py | ||
| @@ -4,13 +4,15 @@ from scripts.open_issues import parse_tasks | ||
|
|
||
|
|
||
| def test_parse_tasks(tmp_path): | ||
| - md = textwrap.dedent(""" | ||
| + md = textwrap.dedent( | ||
| + """ | ||
| ### 4.1 Stage 0 — Bootstrap | ||
| 1. Create docker-compose | ||
| 2. Create schema | ||
| ### 4.2 Stage 1 — Proof | ||
| * Implement adapter | ||
| - """) | ||
| + """ | ||
| + ) | ||
| file = tmp_path / "a.md" | ||
| file.write_text(md) | ||
| tasks = parse_tasks(str(file)) | ||
|
Comment on lines
+1
to
+236
|
||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The onCreateCommand is extremely long (over 400 characters) which makes it difficult to read and maintain. Consider breaking this into multiple commands or using a separate setup script for better readability.