feat(playbook): add install_mode deployment config

BREAKING CHANGE: [vendor] and playbook.deploy_root are no longer supported. Use [playbook].install_mode and playbook.playbook_root instead.
This commit is contained in:
csh
2026-06-01 10:49:16 +08:00
parent 2c3a559a30
commit f2ab57b39f
15 changed files with 376 additions and 184 deletions
+126 -42
View File
@@ -125,7 +125,8 @@ class PlaybookCliTests(unittest.TestCase):
config_body = f"""
[playbook]
project_root = "."
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[format_md]
@@ -142,7 +143,7 @@ langs = ["tsl"]
self.assertIn("sync_standards", output)
self.assertIn("format_md", output)
def test_format_md_only_does_not_require_deploy_root(self):
def test_format_md_only_does_not_require_playbook_root(self):
with tempfile.TemporaryDirectory() as tmp_dir:
config_body = f"""
[playbook]
@@ -157,15 +158,55 @@ project_root = "{tmp_dir}"
self.assertEqual(result.returncode, 0)
def test_vendor_creates_snapshot(self):
def test_vendor_section_is_rejected(self):
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[vendor]
langs = ["tsl"]
"""
config_path = write_config(root, "playbook.toml", config_body)
result = run_cli("-config", str(config_path))
self.assertNotEqual(result.returncode, 0)
self.assertIn("[vendor]", result.stdout + result.stderr)
def test_deploy_root_is_rejected(self):
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[vendor]
[sync_standards]
langs = ["tsl"]
"""
config_path = write_config(root, "playbook.toml", config_body)
result = run_cli("-config", str(config_path))
self.assertNotEqual(result.returncode, 0)
self.assertIn("deploy_root", result.stdout + result.stderr)
self.assertIn("playbook_root", result.stdout + result.stderr)
def test_snapshot_install_creates_snapshot(self):
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_standards]
langs = ["tsl"]
"""
config_path = write_config(root, "playbook.toml", config_body)
@@ -176,15 +217,16 @@ langs = ["tsl"]
self.assertEqual(result.returncode, 0)
self.assertTrue(snapshot.is_file())
def test_vendor_docs_index_uses_new_tsl_entrypoints(self):
def test_snapshot_docs_index_uses_new_tsl_entrypoints(self):
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[vendor]
[sync_standards]
langs = ["tsl"]
"""
config_path = write_config(root, "playbook.toml", config_body)
@@ -201,14 +243,15 @@ langs = ["tsl"]
self.assertIn("`tsl/reference/index.md`", text)
self.assertNotIn("`tsl/syntax_book/index.md`", text)
def test_external_clone_requires_explicit_deploy_root(self):
def test_external_clone_requires_explicit_playbook_root(self):
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
install_mode = "snapshot"
[vendor]
[sync_standards]
langs = ["tsl"]
"""
config_path = write_config(root, "playbook.toml", config_body)
@@ -216,14 +259,34 @@ langs = ["tsl"]
result = run_cli("-config", str(config_path))
self.assertNotEqual(result.returncode, 0)
self.assertIn("deploy_root", result.stdout + result.stderr)
self.assertIn("playbook_root", result.stdout + result.stderr)
def test_subtree_mode_requires_project_local_script(self):
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "subtree"
[sync_standards]
langs = ["tsl"]
"""
config_path = write_config(root, "playbook.toml", config_body)
result = run_cli("-config", str(config_path))
self.assertNotEqual(result.returncode, 0)
self.assertIn("project-local Playbook script", result.stdout + result.stderr)
def test_sync_memory_bank_creates_memory_bank(self):
with tempfile.TemporaryDirectory() as tmp_dir:
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
@@ -242,7 +305,8 @@ project_name = "Demo"
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_standards]
langs = ["tsl"]
@@ -265,7 +329,8 @@ langs = ["tsl"]
f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_standards]
langs = ["tsl"]
@@ -282,7 +347,8 @@ no_backup = true
f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_standards]
langs = ["tsl", "cpp"]
@@ -304,7 +370,8 @@ no_backup = true
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_standards]
langs = ["tsl", "markdown"]
@@ -326,7 +393,8 @@ langs = ["tsl", "markdown"]
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_standards]
langs = ["tsl"]
@@ -352,7 +420,8 @@ langs = ["tsl"]
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[install_skills]
agents_home = "{target}"
@@ -453,7 +522,8 @@ skills = ["brainstorming"]
config_body = f"""
[playbook]
project_root = "{tmp_root}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[install_skills]
agents_home = "{target}"
@@ -475,7 +545,8 @@ skills = ["karpathy-guidelines"]
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[install_skills]
agents_home = "{target}"
@@ -496,7 +567,8 @@ skills = ["tsl-guide"]
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[install_skills]
codex_home = "{target}"
@@ -511,17 +583,15 @@ skills = ["brainstorming"]
self.assertNotEqual(result.returncode, 0)
self.assertIn("codex_home", result.stdout + result.stderr)
def test_external_clone_flow_rewrites_links_with_configured_deploy_root(self):
def test_external_clone_flow_rewrites_links_with_configured_playbook_root(self):
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
agents_home = root / "agents-home"
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
[vendor]
langs = ["tsl"]
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_standards]
langs = ["tsl"]
@@ -545,23 +615,28 @@ skills = ["style-cleanup"]
def test_deployed_snapshot_rewrites_links_from_snapshot_location(self):
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
vendor_config = write_config(
install_config = write_config(
root,
"vendor.toml",
"install.toml",
f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[vendor]
[sync_standards]
langs = ["tsl"]
""",
)
vendor_result = run_cli("-config", str(vendor_config))
self.assertEqual(vendor_result.returncode, 0, msg=vendor_result.stdout + vendor_result.stderr)
install_result = run_cli("-config", str(install_config))
self.assertEqual(
install_result.returncode,
0,
msg=install_result.stdout + install_result.stderr,
)
vendored_script = root / CUSTOM_DEPLOY_ROOT / "scripts" / "playbook.py"
snapshot_script = root / CUSTOM_DEPLOY_ROOT / "scripts" / "playbook.py"
agents_home = root / "local-agents"
sync_config = write_config(
root,
@@ -569,7 +644,8 @@ langs = ["tsl"]
f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_standards]
langs = ["tsl"]
@@ -582,7 +658,7 @@ skills = ["style-cleanup"]
""",
)
sync_result = run_script(vendored_script, "-config", str(sync_config))
sync_result = run_script(snapshot_script, "-config", str(sync_config))
self.assertEqual(sync_result.returncode, 0, msg=sync_result.stdout + sync_result.stderr)
self.assert_style_cleanup_tsl_docs_prefix(
root, agents_home, f"{CUSTOM_DEPLOY_ROOT}/docs"
@@ -593,7 +669,8 @@ skills = ["style-cleanup"]
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
@@ -619,7 +696,8 @@ project_name = "Demo"
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
@@ -650,7 +728,8 @@ project_name = "Demo"
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
@@ -682,7 +761,8 @@ project_name = "Demo"
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
@@ -708,7 +788,8 @@ project_name = "Demo"
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[sync_memory_bank]
project_name = "Demo"
@@ -730,7 +811,8 @@ project_name = "Demo"
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[install_skills]
agents_home = "{agents_home}"
@@ -759,7 +841,8 @@ skills = ["commit-message"]
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[install_skills]
agents_home = "{agents_home}"
@@ -784,7 +867,8 @@ no_backup = true
config_body = f"""
[playbook]
project_root = "{tmp_dir}"
deploy_root = "{CUSTOM_DEPLOY_ROOT}"
playbook_root = "{CUSTOM_DEPLOY_ROOT}"
install_mode = "snapshot"
[install_skills]
agents_home = "{agents_home}"