This repository was archived by the owner on Jul 3, 2026. It is now read-only.
Merge pull request #1 from alexanderlhicks/update_workflow #2
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| name: CI | |
| on: | |
| push: | |
| branches: [main] | |
| pull_request: | |
| branches: [main] | |
| jobs: | |
| lint: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| cache: pip | |
| - name: Install dependencies | |
| run: | | |
| pip install -r requirements.txt | |
| pip install ruff==0.9.* | |
| - name: Lint with ruff | |
| run: ruff check summary.py | |
| validate-action: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| - name: Install PyYAML | |
| run: pip install pyyaml | |
| - name: Validate action.yml structure | |
| run: python -c "import yaml; yaml.safe_load(open('action.yml'))" | |
| - name: Verify prompt templates exist | |
| run: | | |
| for f in triage.md triage_tiered.md summarize_file.md check_style.md synthesize_summary.md refine_summary.md; do | |
| test -f "prompts/$f" || { echo "Missing prompt template: $f"; exit 1; } | |
| done | |
| - name: Verify action.yml env vars match summary.py expectations | |
| run: | | |
| python -c " | |
| import yaml, re | |
| with open('action.yml') as f: | |
| action = yaml.safe_load(f) | |
| # Collect env vars the action passes to summary.py | |
| steps = action['runs']['steps'] | |
| summary_step = [s for s in steps if 'summary.py' in s.get('run', '')] | |
| assert summary_step, 'Could not find summary.py step in action.yml' | |
| env_vars = set(summary_step[0].get('env', {}).keys()) | |
| # Collect env vars summary.py reads | |
| with open('summary.py') as f: | |
| src = f.read() | |
| # Match os.environ.get/os.environ[]/os.getenv patterns | |
| read_vars = set(re.findall(r'os\.environ(?:\.get)?\(?[\"\\']([A-Z_]+)', src)) | |
| read_vars |= set(re.findall(r'os\.getenv\([\"\\']([A-Z_]+)', src)) | |
| # GITHUB_TOKEN is checked via 'in os.environ' — also capture that | |
| read_vars |= set(re.findall(r'[\"\\']([A-Z_]+)[\"\\'] in os\.environ', src)) | |
| # Every var summary.py reads should be provided by action.yml | |
| missing = read_vars - env_vars | |
| if missing: | |
| print(f'FAIL: summary.py reads env vars not provided by action.yml: {missing}') | |
| exit(1) | |
| print(f'OK: all {len(read_vars)} env vars summary.py reads are provided by action.yml') | |
| " | |
| dry-run: | |
| runs-on: ubuntu-latest | |
| steps: | |
| - uses: actions/checkout@v4 | |
| - uses: actions/setup-python@v5 | |
| with: | |
| python-version: "3.13" | |
| cache: pip | |
| - name: Install dependencies | |
| run: pip install -r requirements.txt | |
| - name: Create minimal test diff | |
| run: | | |
| cat > pr.diff << 'DIFF' | |
| diff --git a/Test.lean b/Test.lean | |
| --- a/Test.lean | |
| +++ b/Test.lean | |
| @@ -1,3 +1,4 @@ | |
| import Mathlib | |
| +theorem test_thm : True := sorry | |
| def foo := 1 | |
| def bar := 2 | |
| DIFF | |
| - name: Verify core logic without API calls | |
| run: | | |
| python -c " | |
| import summary | |
| # --- DiffAnalyzer --- | |
| analyzer = summary.DiffAnalyzer(['def', 'theorem', 'lemma']) | |
| with open('pr.diff') as f: | |
| diff = f.read() | |
| stats, added, removed, affected, ad, rd, afd, warnings = analyzer.analyze(diff) | |
| assert stats['files_changed'] == 1, f'Expected 1 file, got {stats[\"files_changed\"]}' | |
| assert stats['lines_added'] >= 1, 'Expected at least 1 line added' | |
| print('DiffAnalyzer: OK') | |
| # --- split_diff_into_files --- | |
| files = summary.split_diff_into_files(diff) | |
| assert 'Test.lean' in files, f'Expected Test.lean in files, got {list(files.keys())}' | |
| print('split_diff_into_files: OK') | |
| # --- Config fingerprint --- | |
| fp1 = summary._compute_config_fingerprint('model-a', 'prompt-a') | |
| fp2 = summary._compute_config_fingerprint('model-b', 'prompt-a') | |
| fp3 = summary._compute_config_fingerprint('model-a', 'prompt-b') | |
| assert fp1 != fp2, 'Fingerprint should change when model changes' | |
| assert fp1 != fp3, 'Fingerprint should change when prompt changes' | |
| print('Config fingerprint: OK') | |
| # --- Prompt templates load --- | |
| for name in ['triage.md', 'triage_tiered.md', 'summarize_file.md', 'check_style.md', 'synthesize_summary.md', 'refine_summary.md']: | |
| t = summary._read_prompt_template(name) | |
| assert len(t) > 0, f'Prompt template {name} is empty' | |
| print('Prompt templates: OK') | |
| # --- Title validation --- | |
| ok, t, msg = summary.validate_pr_title('feat(Sumcheck): add completeness proof') | |
| assert ok and t == 'feat', f'Expected valid feat, got {ok}, {t}' | |
| ok3, t3, msg3 = summary.validate_pr_title('fix: correct off-by-one') | |
| assert ok3 and t3 == 'fix', f'Expected valid fix without scope, got {ok3}, {t3}' | |
| ok2, t2, msg2 = summary.validate_pr_title('random title') | |
| assert not ok2 and msg2, f'Expected invalid, got {ok2}' | |
| print('Title validation: OK') | |
| # --- Sorry delta formatting --- | |
| delta = summary._format_sorry_delta(['a'], ['b', 'c']) | |
| assert 'delta: -1' in delta, f'Expected negative delta in: {delta}' | |
| empty = summary._format_sorry_delta([], []) | |
| assert empty == '', 'Expected empty string for no sorries' | |
| print('Sorry delta: OK') | |
| print('All checks passed.') | |
| " |