test_source_distribution.py python
54 lines 2.9 KB
Raw
sha256:f88ec0083b3bcac6a4b7b99c8cc196194ef376aab2c4f2f63e8dfe26256ac6b7 docs: reconcile v1 prerelease publication and operating guides Human 8 days ago
1 """The native snapshot and controlled mirror must retain supported CI dotfiles."""
2 import json
3 import subprocess
4
5 from tests.muse.test_handoffs import init
6 from tests.v1.conftest import KIT, command
7
8
9 def test_native_source_and_mirror_keep_ci_dotfiles(muse_root, muse_python, muse, tmp_path):
10 root = muse_root
11 init(root, muse_python)
12 paths = ['.github/workflows/supported-v1.yml', '.museignore', '.gitignore',
13 'tools/ci/supported_v1.py', 'tools/ci/muse_artifact.py',
14 'tools/ci/muse-rc5-artifact.json', 'tools/ci/muse-rc5-source-files.json',
15 'tools/ci/requirements-muse-rc5.txt', 'tools/ci/MUSE-RC5-RECOVERY.md',
16 'templates/ROADMAP.template.md']
17 for relative in paths:
18 target = root / relative
19 target.parent.mkdir(parents=True, exist_ok=True)
20 target.write_bytes((KIT / relative).read_bytes())
21 tool = root / 'explicit-tool'
22 tool.write_bytes(b'no shebang; mode is explicit\n')
23 tool.chmod(0o755)
24 muse(root, 'code', 'add', '.')
25 # rc5's recursive staging omits new dot-directories; explicitly stage CI.
26 muse(root, 'code', 'add', '.github/workflows/supported-v1.yml')
27 muse(root, 'commit', '--no-verify', '-m', 'source including CI dotfiles', '--json')
28 head = muse(root, 'rev-parse', 'HEAD').stdout.strip()
29 state = json.loads(command('-C', root, 'status', '--json').stdout)
30 plan = {'schema': 1, 'source': {'repo_id': state['source_id'], 'branch': 'main',
31 'revision': head, 'hub_url': 'https://staging.musehub.ai/fixture/ci'},
32 'destination': {'url': 'https://github.com/fixture/ci.git',
33 'repository': 'fixture/ci', 'branch': 'muse-mirror', 'base': 'main',
34 'expected_head': 'absent'}, 'target': str((tmp_path / 'ci-mirror.git').resolve()),
35 'expected_target': 'absent', 'executables': ['explicit-tool']}
36 from cli.v1_io import digest
37 raw = json.dumps(plan).encode()
38 file = root / '.overseer/local/ci-plan.json'
39 file.parent.mkdir(exist_ok=True)
40 file.write_bytes(raw)
41 for operation in ('prepare', 'verify'):
42 result = command('-C', root, 'mirror', operation, '--plan-file',
43 '.overseer/local/ci-plan.json', '--expect-plan', digest(raw))
44 assert result.returncode == 0, result.stderr + result.stdout
45 def git(*args):
46 return subprocess.check_output(['/usr/bin/git', '--git-dir', plan['target'], *args])
47 projected = git('ls-tree', '-r', '--name-only', 'refs/heads/muse-mirror').decode().splitlines()
48 assert set(paths) <= set(projected)
49 for relative in paths:
50 assert git('show', 'refs/heads/muse-mirror:' + relative) == (root / relative).read_bytes()
51 assert git('ls-tree', 'refs/heads/muse-mirror', 'explicit-tool').startswith(b'100755 ')
52 assert not any(p.startswith(('.overseer/', '.cursor/')) or p == 'docs/NEXT.md' for p in projected)
53 assert not (root / '.muse/hooks').exists()
54 assert not (root / '.cursor').exists()
File History 1 commit
sha256:f88ec0083b3bcac6a4b7b99c8cc196194ef376aab2c4f2f63e8dfe26256ac6b7 docs: reconcile v1 prerelease publication and operating guides Human 8 days ago