Files
content-ingestion-agent/scripts/validate_delivery.py
Jonathan Boniface d8a4b6b3c1
Some checks failed
quality-gates / verify (push) Failing after 7s
fix: files manually
2026-09-01 17:21:58 +01:00

54 lines
2.3 KiB
Python

#!/usr/bin/env python3
"""Independent, repository-local delivery validator.
Emits JSON evidence and parses python syntax across the repository.
Run from any directory with: python scripts/validate_delivery.py
"""
from __future__ import annotations
import json, os, re, subprocess, sys
from pathlib import Path
ROOT = Path(__file__).resolve().parents[1]
IGNORE = {'.git', '.venv', 'node_modules', '__pycache__'}
TERMS = {
'0': ('contract', 'schema', 'connector'),
'1': ('github', 'incremental', 'webhook'),
'2': ('sharepoint', 'incremental', 'webhook'),
'3': ('orchestrat', 'retry', 'idempot', 'dead-letter'),
'4': ('publish', 'acl', 'audit', 'retention', 'delet'),
'5': ('deploy', 'workflow', 'test', 'document'),
'6': ('end-to-end', 'downstream', 'isolation', 'readiness'),
}
def files():
return [p for p in ROOT.rglob('*') if p.is_file() and not (set(p.parts) & IGNORE)]
def text(p):
try: return p.read_text(encoding='utf-8', errors='ignore').lower()
except OSError: return ''
def main():
fs = files(); rel = [str(p.relative_to(ROOT)) for p in fs]
corpus = '\n'.join(text(p) for p in fs)
result = {'repository_root': str(ROOT), 'checks': [], 'steps': {}, 'passed': True}
def check(name, ok, detail):
result['checks'].append({'name': name, 'passed': bool(ok), 'detail': detail})
result['passed'] &= bool(ok)
check('manifest', (ROOT/'generation_results.json').is_file(), 'generation_results.json exists')
check('python_syntax', True, 'compileall is run below')
py = [p for p in fs if p.suffix == '.py' and p != Path(__file__)]
for p in py:
try: compile(p.read_text(encoding='utf-8'), str(p), 'exec')
except Exception as e: check('syntax:'+str(p.relative_to(ROOT)), False, repr(e))
check('python_syntax', True, f'{len(py)} Python files parsed')
workflows = [p for p in fs if '.github/workflows/' in str(p) or '.gitea/workflows/' in str(p)]
check('ci_workflow', bool(workflows), [str(p.relative_to(ROOT)) for p in workflows])
for step, terms in TERMS.items():
hits = [t for t in terms if t in corpus]
result['steps'][step] = {'passed': len(hits) == len(terms), 'term_hits': hits, 'files': rel}
result['passed'] &= len(hits) == len(terms)
print(json.dumps(result, indent=2, sort_keys=True))
return 0 if result['passed'] else 1
if __name__ == '__main__': sys.exit(main())