Skip to content

docs: add MUW-formatted review reply + agent review contract #68

docs: add MUW-formatted review reply + agent review contract

docs: add MUW-formatted review reply + agent review contract #68

Workflow file for this run

name: Docs
on:
pull_request:
paths:
- "**/*.md"
- ".github/ISSUE_TEMPLATE/**"
- ".github/PULL_REQUEST_TEMPLATE.md"
- ".github/workflows/docs.yml"
push:
branches: [main]
paths:
- "**/*.md"
- ".github/ISSUE_TEMPLATE/**"
- ".github/PULL_REQUEST_TEMPLATE.md"
- ".github/workflows/docs.yml"
permissions:
contents: read
jobs:
markdown-lint:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
with:
fetch-depth: 0
- name: Collect changed Markdown files
id: changed-markdown
env:
EVENT_NAME: ${{ github.event_name }}
BASE_REF: ${{ github.base_ref }}
BEFORE_SHA: ${{ github.event.before }}
AFTER_SHA: ${{ github.sha }}
run: |
python3 - <<'PY' >> "$GITHUB_OUTPUT"
from pathlib import Path
import os
import subprocess
event_name = os.environ["EVENT_NAME"]
if event_name == "pull_request":
base_ref = os.environ["BASE_REF"]
subprocess.run(["git", "fetch", "origin", base_ref, "--depth=1"], check=True)
diff_range = f"origin/{base_ref}...HEAD"
else:
before = os.environ.get("BEFORE_SHA", "")
after = os.environ["AFTER_SHA"]
if before and set(before) != {"0"}:
diff_range = f"{before}..{after}"
else:
diff_range = f"{after}^..{after}"
result = subprocess.run(
["git", "diff", "--name-only", "--diff-filter=ACMRT", diff_range],
check=True,
text=True,
stdout=subprocess.PIPE,
)
files = [
path
for path in result.stdout.splitlines()
if path.endswith(".md") and Path(path).is_file()
]
print("files<<EOF")
print("\n".join(files))
print("EOF")
print(f"count={len(files)}")
PY
- uses: DavidAnson/markdownlint-cli2-action@v19
if: steps.changed-markdown.outputs.count != '0'
with:
globs: ${{ steps.changed-markdown.outputs.files }}
config: .markdownlint.json
links:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Validate active relative Markdown links
run: |
python3 - <<'PY'
from pathlib import Path
import re
import sys
files = [
Path("README.md"),
Path("use-cases/README.md"),
Path("methods/README.md"),
Path("benchmarks/README.md"),
Path("AGENTS.md"),
Path(".github/CONTRIBUTING.md"),
Path(".github/CODE_OF_CONDUCT.md"),
Path(".github/SECURITY.md"),
]
missing = []
for path in files:
if not path.exists():
continue
text = path.read_text()
active = re.sub(r"<!--.*?-->", "", text, flags=re.S)
for raw in re.findall(r"\[[^\]]*\]\(([^)]+)\)", active):
link = raw.split("#", 1)[0]
if not link or link.startswith(("http://", "https://", "mailto:")):
continue
target = (path.parent / link).resolve()
try:
target.relative_to(Path.cwd().resolve())
except ValueError:
missing.append((path, raw, "outside repository"))
continue
if not target.exists():
missing.append((path, raw, "missing"))
if missing:
for path, raw, reason in missing:
print(f"{path}: {raw} -> {reason}")
sys.exit(1)
print("Active relative Markdown links resolve.")
PY
- name: Validate use-case banner links
run: |
python3 - <<'PY'
from pathlib import Path
import re
import sys
files = {
Path("README.md"): "## Use Cases",
Path("use-cases/README.md"): "## Use Case Catalogue",
}
failures = []
for path, heading in files.items():
text = path.read_text()
start = text.find(heading)
if start == -1:
failures.append(f"{path}: missing {heading}")
continue
table_start = text.find("<table>", start)
table_end = text.find("</table>", table_start)
if table_start == -1 or table_end == -1:
failures.append(f"{path}: missing use-case table")
continue
table = text[table_start:table_end]
cells = re.findall(r"<td[^>]*>(.*?)</td>", table, flags=re.S)
for index, cell in enumerate(cells, start=1):
title_match = re.search(r"####\s+(.+)", cell)
title = title_match.group(1).strip() if title_match else f"use case {index}"
banner_match = re.search(r"\[!\[[^\]]*\]\([^)]+\)\]\(([^)]+)\)", cell)
primary_match = re.search(r"^\[(?:Code|Plugin|Live Demo)\]\(([^)]+)\)", cell, flags=re.M)
if "Coming soon" in cell and not primary_match:
continue
if not banner_match:
failures.append(f"{path}: {title}: missing linked banner")
elif not primary_match:
failures.append(f"{path}: {title}: missing primary link")
elif banner_match.group(1) != primary_match.group(1):
failures.append(
f"{path}: {title}: banner link {banner_match.group(1)} "
f"does not match primary link {primary_match.group(1)}"
)
if failures:
print("\n".join(failures))
sys.exit(1)
print("Use-case banner links match primary links.")
PY
- name: Validate issue template YAML
run: |
ruby -e 'require "yaml"; Dir[".github/ISSUE_TEMPLATE/*.yml"].sort.each { |p| YAML.load_file(p); puts "YAML ok: #{p}" }'