Skip to content

Commit 9f86aa3

Browse files
committed
ci: strengthen verifier with link checks
1 parent acdeff6 commit 9f86aa3

1 file changed

Lines changed: 28 additions & 0 deletions

File tree

scripts/verify_repo.py

Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
from pathlib import Path
2+
import re
23

34
ROOT = Path(__file__).resolve().parents[1]
45

@@ -11,16 +12,22 @@
1112
'VERSIONING.md',
1213
'CHANGELOG.md',
1314
'CODEOWNERS',
15+
'AGENTS.md',
1416
'.github/PULL_REQUEST_TEMPLATE.md',
17+
'.github/copilot-instructions.md',
1518
'.github/workflows/ci-docs.yml',
1619
'.github/workflows/sync-wiki.yml',
20+
'docs/README.md',
21+
'docs/methodology/quickstart.md',
1722
'docs/methodology/continuous-improvement-loop.md',
1823
'docs/methodology/definition-of-done.md',
24+
'docs/methodology/maturity-model.md',
1925
'docs/diagrams/README.md',
2026
'docs/loops/feature.md',
2127
'docs/loops/bugfix-loop.md',
2228
'docs/loops/release.md',
2329
'docs/verifiers/README.md',
30+
'docs/evaluations/README.md',
2431
'prompts/master-system-prompt.md',
2532
'prompts/chatgpt-web.md',
2633
'prompts/continuous-improvement.md',
@@ -32,14 +39,19 @@
3239
]
3340

3441
REQUIRED_MERMAID = [
42+
'AGENTS.md',
3543
'docs/methodology/continuous-improvement-loop.md',
3644
'docs/methodology/definition-of-done.md',
45+
'docs/methodology/maturity-model.md',
3746
'docs/diagrams/README.md',
3847
'docs/loops/feature.md',
3948
'docs/loops/release.md',
4049
'wiki/Home.md',
4150
]
4251

52+
LINK_RE = re.compile(r'\[[^\]]+\]\(([^)]+)\)')
53+
SKIP_PREFIXES = ('http://', 'https://', 'mailto:', '#')
54+
4355

4456
def fail(title, items):
4557
if items:
@@ -66,6 +78,22 @@ def fail(title, items):
6678
without_mermaid.append(p)
6779
fail('Required diagram docs without Mermaid:', without_mermaid)
6880

81+
broken_links = []
82+
for md in markdown:
83+
text = md.read_text(encoding='utf-8')
84+
for match in LINK_RE.finditer(text):
85+
target = match.group(1).split('#', 1)[0].strip()
86+
if not target or target.startswith(SKIP_PREFIXES):
87+
continue
88+
resolved = (md.parent / target).resolve()
89+
try:
90+
resolved.relative_to(ROOT.resolve())
91+
except ValueError:
92+
continue
93+
if not resolved.exists():
94+
broken_links.append(f'{md.relative_to(ROOT)} -> {target}')
95+
fail('Broken relative links:', broken_links)
96+
6997
print('Repository structure OK')
7098
print('Required files checked:', len(REQUIRED))
7199
print('Markdown files checked:', len(markdown))

0 commit comments

Comments
 (0)