Skip to content

Commit 686d8be

Browse files
committed
feat: Add local CI/CD automation with pre-commit hooks for AI mind map generation
- Add pre-commit framework configuration (.pre-commit-config.yaml) - Create pre-commit hook script (tools/hooks/generate_ai_mindmaps_hook.py) - Auto-detects changes in ontology/, meta/problems/, tools/generate_mindmaps.py - Supports skip mechanisms via commit message tags or environment variables - Interactive API key input (not stored) - Works on all branches - Add pre-commit dependency to requirements.txt - Update tools/README.md with Local CI/CD Automation section - Setup instructions - Usage guide with skip options - Configuration details - Features table - Update README.md - Add pre-commit and local-automation to Topics tags - Add Automatic Generation (Local CI/CD) section in AI Mind Map Generation This enables automatic AI mind map generation on commit when relevant files are modified, improving developer workflow while maintaining security by not storing API keys.
1 parent 7d176bf commit 686d8be

File tree

5 files changed

+301
-1
lines changed

5 files changed

+301
-1
lines changed

.pre-commit-config.yaml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
# Pre-commit configuration for NeetCode project
2+
# Install: pip install pre-commit
3+
# Setup: pre-commit install
4+
5+
repos:
6+
# Custom local hook for AI mind map generation
7+
- repo: local
8+
hooks:
9+
- id: generate-ai-mindmaps
10+
name: Generate AI Mind Maps
11+
entry: python tools/hooks/generate_ai_mindmaps_hook.py
12+
language: system
13+
files: |
14+
^ontology/
15+
^meta/problems/
16+
^tools/generate_mindmaps\.py$
17+
pass_filenames: false
18+
stages: [pre-commit]
19+
verbose: true
20+
always_run: false
21+
22+

README.md

Lines changed: 24 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ AEO/GEO: A scalable Python framework with knowledge graph-driven learning, AI-po
2929

3030
---
3131

32-
**Topics:** `knowledge-graph` `ai-powered` `mind-map` `pattern-recognition` `leetcode` `neetcode-150` `blind-75` `stress-testing` `algorithm-engineering` `performance-benchmarking` `data-driven-testing` `random-test-generation` `judge-function` `algorithm-debugging` `competitive-programming` `python` `vscode-integration` `test-automation` `coding-interview`
32+
**Topics:** `knowledge-graph` `ai-powered` `mind-map` `pattern-recognition` `leetcode` `neetcode-150` `blind-75` `stress-testing` `algorithm-engineering` `performance-benchmarking` `data-driven-testing` `random-test-generation` `judge-function` `algorithm-debugging` `competitive-programming` `python` `vscode-integration` `test-automation` `pre-commit` `local-automation` `coding-interview`
3333

3434
---
3535

@@ -374,6 +374,29 @@ python tools/generate_mindmaps_ai.py --topic dynamic_programming
374374
# language = ["en", "zh-TW"]
375375
```
376376

377+
### 🔄 Automatic Generation (Local CI/CD)
378+
379+
**Auto-generate AI mind maps on commit** using pre-commit hooks:
380+
381+
```bash
382+
# Install pre-commit hooks
383+
pip install pre-commit
384+
pre-commit install
385+
```
386+
387+
When you commit changes to `ontology/`, `meta/problems/`, or `tools/generate_mindmaps.py`, the hook automatically runs AI mind map generation.
388+
389+
**Skip when needed:**
390+
```bash
391+
# Skip with commit message
392+
git commit -m "Update ontology [skip-ai]"
393+
394+
# Skip with environment variable
395+
SKIP_AI_MINDMAPS=true git commit -m "Update ontology"
396+
```
397+
398+
> 📖 See [tools/README.md](tools/README.md#-local-cicd-automation) for complete setup and usage guide.
399+
377400
### Configuration
378401

379402
Edit `tools/mindmap_ai_config.toml` to customize:

requirements.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,3 +24,6 @@ mkdocs-include-markdown-plugin>=7.0.0 # Include markdown files
2424
# anthropic>=0.18.0 # Anthropic API client (for Claude models)
2525
# requests>=2.31.0 # HTTP library (for Ollama local LLM)
2626

27+
# Pre-commit hooks framework (for local CI/CD automation):
28+
pre-commit>=3.5.0 # Git hooks framework for pre-commit checks
29+

tools/README.md

Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ Developer tools for checking, validating, and generating project content.
1313
| **Generation** | [`generate_mindmaps.py`](#generate_mindmapspy) | Rule-based mind map generation |
1414
| | [`generate_mindmaps_ai.py`](#generate_mindmaps_aipy) | AI-powered mind map generation |
1515
| | [`generate_pattern_docs.py`](#generate_pattern_docspy) | Pattern documentation generation |
16+
| **Automation** | [Pre-commit Hooks](#-local-cicd-automation) | Auto-generate AI mind maps on commit |
1617
| **Utilities** | [`text_to_mindmap.py`](#text_to_mindmappy) | Convert text to mind map format |
1718
| | [`prepare_llm_input.py`](#prepare_llm_inputpy) | Prepare LLM input data |
1819

@@ -56,6 +57,9 @@ tools/
5657
├── text_to_mindmap.py # Text to mind map converter
5758
├── prepare_llm_input.py # LLM input preparation
5859
60+
├── hooks/ # Pre-commit hooks
61+
│ └── generate_ai_mindmaps_hook.py # AI mind map generation hook
62+
5963
├── mindmaps/ # Mind map generation module
6064
│ └── README.md # 📖 Detailed technical docs
6165
├── patterndocs/ # Pattern docs generation module
@@ -298,6 +302,90 @@ neetcode/
298302

299303
---
300304

305+
## 🔄 Local CI/CD Automation
306+
307+
### Pre-commit Hooks
308+
309+
The project uses [pre-commit](https://pre-commit.com/) framework to automatically generate AI mind maps when relevant files are modified.
310+
311+
#### Setup
312+
313+
```bash
314+
# Install pre-commit (if not already installed)
315+
pip install pre-commit
316+
317+
# Install Git hooks
318+
pre-commit install
319+
```
320+
321+
#### How It Works
322+
323+
When you commit changes to:
324+
- `ontology/` directory
325+
- `meta/problems/` directory
326+
- `tools/generate_mindmaps.py`
327+
328+
The hook automatically runs `tools/generate_mindmaps_ai.py` to generate AI-powered mind maps.
329+
330+
#### Usage
331+
332+
**Normal workflow (automatic):**
333+
334+
```bash
335+
# Modify relevant files and commit
336+
git add ontology/some_file.json
337+
git commit -m "Update ontology"
338+
# Hook automatically runs, prompts for API key, generates mind maps
339+
```
340+
341+
**Skip AI generation:**
342+
343+
```bash
344+
# Method 1: Use commit message tag
345+
git commit -m "Update ontology [skip-ai]"
346+
347+
# Method 2: Use environment variable
348+
# PowerShell
349+
$env:SKIP_AI_MINDMAPS = "true"
350+
git commit -m "Update ontology"
351+
352+
# CMD
353+
set SKIP_AI_MINDMAPS=true
354+
git commit -m "Update ontology"
355+
356+
# Method 3: Skip all hooks
357+
git commit --no-verify -m "Update ontology"
358+
```
359+
360+
**Manual testing:**
361+
362+
```bash
363+
# Test all hooks
364+
pre-commit run --all-files
365+
366+
# Test specific hook
367+
pre-commit run generate-ai-mindmaps --all-files
368+
```
369+
370+
#### Configuration
371+
372+
- **Config file**: `.pre-commit-config.yaml`
373+
- **Hook script**: `tools/hooks/generate_ai_mindmaps_hook.py`
374+
- **API Key**: Interactive input (not stored in any file)
375+
- **Branch support**: Works on all branches
376+
377+
#### Features
378+
379+
| Feature | Description |
380+
|---------|-------------|
381+
| **Auto-detection** | Detects changes in `ontology/`, `meta/problems/`, `tools/generate_mindmaps.py` |
382+
| **API Key** | Interactive input, never stored |
383+
| **Skip options** | Multiple ways to skip when needed |
384+
| **Branch support** | Works on all branches |
385+
| **Docker Act compatible** | Doesn't interfere with local GitHub Actions testing |
386+
387+
---
388+
301389
## 🔗 Related Documentation
302390

303391
| Document | Description |
Lines changed: 164 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,164 @@
1+
#!/usr/bin/env python3
2+
"""
3+
Pre-commit hook for generating AI mind maps.
4+
5+
Only runs when:
6+
1. Files in ontology/, meta/problems/, or tools/generate_mindmaps.py are modified
7+
2. Not skipped via [skip-ai] in commit message or SKIP_AI_MINDMAPS env var
8+
9+
API Key: Interactive input (not stored)
10+
"""
11+
12+
import os
13+
import subprocess
14+
import sys
15+
from pathlib import Path
16+
17+
# Project root (assuming hook is in tools/hooks/)
18+
PROJECT_ROOT = Path(__file__).parent.parent.parent
19+
TOOLS_DIR = PROJECT_ROOT / 'tools'
20+
21+
22+
def get_current_branch() -> str:
23+
"""Get current Git branch name."""
24+
result = subprocess.run(
25+
['git', 'branch', '--show-current'],
26+
capture_output=True,
27+
text=True,
28+
cwd=PROJECT_ROOT
29+
)
30+
if result.returncode != 0:
31+
return ''
32+
return result.stdout.strip()
33+
34+
35+
def check_changed_files() -> bool:
36+
"""Check if relevant files were changed in staged area."""
37+
result = subprocess.run(
38+
['git', 'diff', '--cached', '--name-only', '--diff-filter=ACM'],
39+
capture_output=True,
40+
text=True,
41+
cwd=PROJECT_ROOT
42+
)
43+
44+
if result.returncode != 0:
45+
return False
46+
47+
changed_files = [f.strip() for f in result.stdout.strip().split('\n') if f.strip()]
48+
49+
# Check if any relevant file was changed
50+
relevant_patterns = [
51+
'ontology/',
52+
'meta/problems/',
53+
'tools/generate_mindmaps.py'
54+
]
55+
56+
for file in changed_files:
57+
for pattern in relevant_patterns:
58+
if file.startswith(pattern) or file == pattern:
59+
return True
60+
61+
return False
62+
63+
64+
def should_skip() -> bool:
65+
"""Check if AI generation should be skipped."""
66+
# Check environment variable
67+
if os.environ.get('SKIP_AI_MINDMAPS', '').lower() in ('true', '1', 'yes'):
68+
return True
69+
70+
# Check commit message (from .git/COMMIT_EDITMSG)
71+
commit_msg_file = PROJECT_ROOT / '.git' / 'COMMIT_EDITMSG'
72+
if commit_msg_file.exists():
73+
try:
74+
commit_msg = commit_msg_file.read_text(encoding='utf-8')
75+
if '[skip-ai]' in commit_msg or '[no-ai]' in commit_msg:
76+
return True
77+
except Exception:
78+
pass
79+
80+
return False
81+
82+
83+
def main() -> int:
84+
"""Main hook function."""
85+
# Check if should skip
86+
if should_skip():
87+
print("ℹ️ AI mind map generation skipped (via [skip-ai] or SKIP_AI_MINDMAPS).")
88+
return 0
89+
90+
# Check if relevant files changed
91+
if not check_changed_files():
92+
print("ℹ️ No relevant files changed (ontology/, meta/problems/, tools/generate_mindmaps.py).")
93+
print(" Skipping AI mind map generation.")
94+
return 0
95+
96+
# Get current branch for display
97+
current_branch = get_current_branch()
98+
99+
# Show what triggered the hook
100+
print("=" * 70)
101+
print("🔍 Pre-commit Hook: AI Mind Map Generation")
102+
print("=" * 70)
103+
print(f"📍 Branch: {current_branch}")
104+
print("📝 Detected changes in:")
105+
print(" - ontology/")
106+
print(" - meta/problems/")
107+
print(" - tools/generate_mindmaps.py")
108+
print("")
109+
print("🤖 Running AI mind map generation...")
110+
print("")
111+
112+
# Check for API key
113+
if not os.environ.get('OPENAI_API_KEY'):
114+
print("⚠️ OPENAI_API_KEY not set in environment")
115+
print("💡 The script will prompt you to enter the API key interactively.")
116+
print(" (API key will NOT be stored)")
117+
print("")
118+
119+
# Run the AI mind map generator
120+
script_path = TOOLS_DIR / 'generate_mindmaps_ai.py'
121+
122+
if not script_path.exists():
123+
print(f"❌ Error: Script not found: {script_path}")
124+
return 1
125+
126+
try:
127+
result = subprocess.run(
128+
[sys.executable, str(script_path), '--goal', 'creative'],
129+
cwd=PROJECT_ROOT,
130+
# Don't capture output so user can see progress and enter API key
131+
)
132+
133+
if result.returncode == 0:
134+
print("")
135+
print("=" * 70)
136+
print("✅ AI mind map generation completed successfully!")
137+
print("=" * 70)
138+
return 0
139+
else:
140+
print("")
141+
print("=" * 70)
142+
print("❌ AI mind map generation failed!")
143+
print("=" * 70)
144+
print("")
145+
print("💡 Options:")
146+
print(" 1. Fix the error and commit again")
147+
print(" 2. Skip this hook: git commit --no-verify")
148+
print(" 3. Skip with message: git commit -m 'message [skip-ai]'")
149+
print(" 4. Skip with env var: SKIP_AI_MINDMAPS=true git commit")
150+
return 1
151+
152+
except KeyboardInterrupt:
153+
print("")
154+
print("⚠️ Interrupted by user")
155+
return 1
156+
except Exception as e:
157+
print(f"❌ Error running AI mind map generator: {e}")
158+
return 1
159+
160+
161+
if __name__ == '__main__':
162+
sys.exit(main())
163+
164+

0 commit comments

Comments
 (0)