Skip to content
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

Merge pull request #1 from alexanderlhicks/update_workflow

Merge pull request #1 from alexanderlhicks/update_workflow #2

Workflow file for this run

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.')
"