Repository navigation
226 lines (185 loc) · 7.64 KB
/
Copy pathmaintenance.yml
File metadata and controls
226 lines (185 loc) · 7.64 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
name: Pattern Engine Maintenance
on:
schedule:
# Run weekly on Sundays at 2:00 AM UTC
- cron: '0 2 * * 0'
workflow_dispatch:
inputs:
run_enrichment:
description: 'Run AI enrichment on all entities'
required: false
type: boolean
default: false
jobs:
maintenance:
runs-on: ubuntu-latest
name: Weekly Maintenance
permissions:
contents: write
issues: write
steps:
- name: Checkout repository
uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.11'
- name: Install dependencies
run: |
pip install pyyaml openai
- name: Build all indexes
run: |
python3 scripts/build_indexes.py
- name: Generate health report
id: health
run: |
python3 << 'EOF'
import json
import yaml
from pathlib import Path
from datetime import datetime
base_dir = Path('.')
report = {
'timestamp': datetime.utcnow().isoformat() + 'Z',
'issues': [],
'warnings': [],
'stats': {}
}
# Load graph
graph_path = base_dir / 'data' / 'graph.json'
if graph_path.exists():
with open(graph_path) as f:
graph = json.load(f)
report['stats'] = graph['stats']
else:
report['issues'].append('Knowledge graph not found')
# Check for orphan relationships
if graph_path.exists():
all_ids = set()
for p in graph['nodes']['patterns']:
all_ids.add(p['id'])
for l in graph['nodes']['lighthouses']:
all_ids.add(l['id'])
orphan_edges = 0
for edge in graph['edges']:
if edge['target'] not in all_ids:
orphan_edges += 1
if orphan_edges > 0:
report['warnings'].append(f'{orphan_edges} relationships point to non-existent entities')
# Check for patterns without relationships
patterns_without_rels = 0
pattern_ids_with_rels = set()
for edge in graph.get('edges', []):
pattern_ids_with_rels.add(edge['source'])
pattern_ids_with_rels.add(edge['target'])
for p in graph['nodes']['patterns']:
if p['id'] not in pattern_ids_with_rels:
patterns_without_rels += 1
if patterns_without_rels > 10:
report['warnings'].append(f'{patterns_without_rels} patterns have no relationships')
# Check for staging backlog
staging_patterns = list((base_dir / '_staging' / 'patterns').glob('*.md')) if (base_dir / '_staging' / 'patterns').exists() else []
staging_lighthouses = list((base_dir / '_staging' / 'lighthouses').glob('*.md')) if (base_dir / '_staging' / 'lighthouses').exists() else []
if len(staging_patterns) > 0:
report['warnings'].append(f'{len(staging_patterns)} patterns waiting in staging')
if len(staging_lighthouses) > 0:
report['warnings'].append(f'{len(staging_lighthouses)} lighthouses waiting in staging')
# Check for draft patterns
draft_count = report['stats'].get('patterns_by_status', {}).get('draft', 0)
if draft_count > 20:
report['warnings'].append(f'{draft_count} patterns still in draft status')
# Save report
report_path = base_dir / 'data' / 'health_report.json'
report_path.parent.mkdir(parents=True, exist_ok=True)
with open(report_path, 'w') as f:
json.dump(report, f, indent=2)
# Generate summary for GitHub
summary = f"""## Pattern Engine Health Report
**Generated:** {report['timestamp']}
### Statistics
- **Total Patterns:** {report['stats'].get('total_patterns', 0)}
- **Total Lighthouses:** {report['stats'].get('total_lighthouses', 0)}
- **Total Relationships:** {report['stats'].get('total_relationships', 0)}
"""
if report['issues']:
summary += "### ❌ Issues\n"
for issue in report['issues']:
summary += f"- {issue}\n"
summary += "\n"
if report['warnings']:
summary += "### ⚠️ Warnings\n"
for warning in report['warnings']:
summary += f"- {warning}\n"
summary += "\n"
if not report['issues'] and not report['warnings']:
summary += "### ✅ All Clear\nNo issues or warnings detected.\n"
with open('health_summary.md', 'w') as f:
f.write(summary)
print(summary)
EOF
- name: Update embedding index
if: inputs.run_enrichment == true
env:
OPENAI_API_KEY: ${{ secrets.OPENAI_API_KEY }}
run: |
python3 scripts/enrich_entity.py --build-embeddings
- name: Commit updated data files
run: |
git config user.name "github-actions[bot]"
git config user.email "github-actions[bot]@users.noreply.github.com"
git add data/
if git diff --staged --quiet; then
echo "No changes to commit"
else
git commit -m "chore: Weekly maintenance update $(date +%Y-%m-%d)"
git push
fi
- name: Create issue if problems found
uses: actions/github-script@v7
with:
script: |
const fs = require('fs');
if (!fs.existsSync('data/health_report.json')) {
return;
}
const report = JSON.parse(fs.readFileSync('data/health_report.json'));
if (report.issues.length === 0 && report.warnings.length === 0) {
console.log('No issues to report');
return;
}
const summary = fs.readFileSync('health_summary.md', 'utf8');
// Check if there's already an open maintenance issue
const { data: issues } = await github.rest.issues.listForRepo({
owner: context.repo.owner,
repo: context.repo.repo,
labels: 'maintenance',
state: 'open'
});
if (issues.length > 0) {
// Update existing issue
await github.rest.issues.createComment({
owner: context.repo.owner,
repo: context.repo.repo,
issue_number: issues[0].number,
body: summary
});
} else {
// Create new issue
await github.rest.issues.create({
owner: context.repo.owner,
repo: context.repo.repo,
title: `Pattern Engine Maintenance Report - ${new Date().toISOString().split('T')[0]}`,
body: summary,
labels: ['maintenance']
});
}
- name: Upload health report
uses: actions/upload-artifact@v4
with:
name: health-report
path: |
data/health_report.json
data/graph.json
retention-days: 90