Add docs/wiki source tree and Gitea Wiki sync helper (#224)
Bootstrap repo-tracked wiki pages (10 required pages), the operator- confirmed sync script, PR template publication gate, and safety tests so Gitea-Tools can publish to the live Gitea Wiki per issue #224. Co-Authored-By: Claude Opus 4.8 (1M context) <[email protected]>
This commit is contained in:
@@ -0,0 +1,112 @@
|
||||
"""Checks for the Gitea Wiki sync helper (issue #224).
|
||||
|
||||
The repo-tracked ``docs/wiki/`` stays the source of truth; the helper
|
||||
mirrors it into the Gitea native wiki only when explicitly invoked.
|
||||
"""
|
||||
import os
|
||||
import subprocess
|
||||
from pathlib import Path
|
||||
|
||||
REPO_ROOT = Path(__file__).resolve().parent.parent
|
||||
SCRIPT = REPO_ROOT / "scripts" / "sync-gitea-wiki.sh"
|
||||
|
||||
REQUIRED_PAGES = [
|
||||
"Home.md",
|
||||
"Operator-Guide.md",
|
||||
"Repositories.md",
|
||||
"Identity-and-Profiles.md",
|
||||
"Workflow.md",
|
||||
"Safety-and-Gates.md",
|
||||
"MCP-Tools.md",
|
||||
"Runbooks.md",
|
||||
"Open-Decisions.md",
|
||||
"History.md",
|
||||
]
|
||||
|
||||
|
||||
def _run(*args, env_extra=None):
|
||||
env = dict(os.environ)
|
||||
env.pop("GITEA_WIKI_SYNC_CONFIRM", None)
|
||||
if env_extra:
|
||||
env.update(env_extra)
|
||||
return subprocess.run(
|
||||
[str(SCRIPT), *args], capture_output=True, text=True, env=env,
|
||||
cwd=str(REPO_ROOT), timeout=30)
|
||||
|
||||
|
||||
def test_script_exists_and_is_executable():
|
||||
assert SCRIPT.is_file(), "missing scripts/sync-gitea-wiki.sh"
|
||||
assert os.access(SCRIPT, os.X_OK), "sync script is not executable"
|
||||
|
||||
|
||||
def test_dry_run_is_default_and_lists_every_page():
|
||||
result = _run()
|
||||
assert result.returncode == 0, result.stderr
|
||||
out = result.stdout
|
||||
assert "dry-run" in out.lower()
|
||||
for page in REQUIRED_PAGES:
|
||||
assert page in out, f"dry-run plan does not list {page}"
|
||||
|
||||
|
||||
def test_dry_run_does_not_push_or_clone():
|
||||
result = _run()
|
||||
blob = (result.stdout + result.stderr).lower()
|
||||
assert "pushing" not in blob
|
||||
assert "cloning" not in blob
|
||||
|
||||
|
||||
def test_push_refused_without_exact_confirmation():
|
||||
result = _run("--push")
|
||||
assert result.returncode != 0
|
||||
blob = result.stdout + result.stderr
|
||||
assert "GITEA_WIKI_SYNC_CONFIRM" in blob
|
||||
assert "cloning" not in blob.lower()
|
||||
|
||||
|
||||
def test_push_refused_with_wrong_confirmation():
|
||||
result = _run("--push", env_extra={"GITEA_WIKI_SYNC_CONFIRM": "yes please"})
|
||||
assert result.returncode != 0
|
||||
assert "cloning" not in (result.stdout + result.stderr).lower()
|
||||
|
||||
|
||||
def test_script_embeds_no_service_urls_or_secrets():
|
||||
text = SCRIPT.read_text(encoding="utf-8")
|
||||
for marker in ("http://", "https://", "token ", "Authorization", "ghp_", "keychain"):
|
||||
assert marker not in text, f"script embeds {marker!r}"
|
||||
|
||||
|
||||
def test_runbook_documents_wiki_sync():
|
||||
runbooks = (REPO_ROOT / "docs" / "wiki" / "Runbooks.md").read_text(encoding="utf-8")
|
||||
assert "sync-gitea-wiki" in runbooks
|
||||
home = (REPO_ROOT / "docs" / "wiki" / "Home.md").read_text(encoding="utf-8")
|
||||
assert "source of truth" in home
|
||||
template = (REPO_ROOT / ".gitea" / "pull_request_template.md").read_text(encoding="utf-8")
|
||||
assert "sync-gitea-wiki" in template
|
||||
|
||||
|
||||
def test_wiki_pages_have_no_local_file_links():
|
||||
for path in (REPO_ROOT / "docs" / "wiki").glob("*.md"):
|
||||
text = path.read_text(encoding="utf-8")
|
||||
assert "file://" not in text, f"{path.name} contains a file:// link"
|
||||
|
||||
|
||||
def test_pr_template_carries_wiki_publication_gate():
|
||||
template = (REPO_ROOT / ".gitea" / "pull_request_template.md").read_text(encoding="utf-8")
|
||||
assert "Wiki tab" in template
|
||||
assert "#224" in template
|
||||
assert "not sufficient to close a wiki issue" in template
|
||||
|
||||
|
||||
def test_runbooks_document_publication_gate_and_closure_rule():
|
||||
runbooks = (REPO_ROOT / "docs" / "wiki" / "Runbooks.md").read_text(encoding="utf-8")
|
||||
assert "Wiki Publication Readiness Gate (#224)" in runbooks or "Wiki publication readiness gate (#224)" in runbooks.lower()
|
||||
assert "Closure prevention" in runbooks
|
||||
assert "GITEA_WIKI_SYNC_CONFIRM" in runbooks
|
||||
|
||||
|
||||
def test_repositories_map_tracks_wiki_publication_status():
|
||||
repositories = (REPO_ROOT / "docs" / "wiki" / "Repositories.md").read_text(encoding="utf-8")
|
||||
assert "Wiki publication status" in repositories or "Wiki Publication Status" in repositories
|
||||
for repo in ("mcp-control-plane", "Gitea-Tools"):
|
||||
assert repo in repositories
|
||||
assert "Gitea Wiki published" in repositories
|
||||
Reference in New Issue
Block a user