59 lines
3.6 KiB
Python
59 lines
3.6 KiB
Python
"""Build a metadata-manifested overlay of the tested server/admin changes."""
|
|
from pathlib import Path
|
|
import hashlib
|
|
import json
|
|
import shutil
|
|
import tarfile
|
|
|
|
root = Path('C:/kefu')
|
|
release = root / 'deploy/token-usage-20260917'
|
|
old_release = root / 'deploy/ark-chat-config-20260917'
|
|
payload = release / 'payload'
|
|
assert not (release / 'manifest.json').exists(), 'Use a fresh release payload; do not overwrite an uploaded candidate'
|
|
backend = ['admin_backend', 'admin_api', 'model_gateway', 'model_protocol', 'model_usage', 'knowledge_worker']
|
|
tests = ['test_model_usage_collection', 'test_model_usage_recovery', 'test_model_usage_ledger',
|
|
'test_model_gateway', 'test_gateway_guard_audit', 'test_gateway_media_audit',
|
|
'test_gateway_failure_audit', 'test_knowledge_model_output', 'test_knowledge_tasks',
|
|
'test_knowledge', 'test_admin_api', 'test_ark_chat_config']
|
|
files = ['wechat_rpa/' + name + '.py' for name in backend + tests]
|
|
front = 'admin-web/apps/web-antd/src/'
|
|
files += [front + 'api/console.ts', front + 'views/console/call-stats.vue']
|
|
files += [front + 'views/console/' + name for name in (
|
|
'ModelUsageStats.vue', 'model-usage-format.ts', 'use-usage-request.ts',
|
|
'ModelUsageStats.test.ts', 'model-usage.test.ts')]
|
|
files += [str(p.relative_to(root)).replace('\\', '/') for p in (root / 'admin-web/apps/web-antd/dist').rglob('*') if p.is_file()]
|
|
manifest = []
|
|
for name in files:
|
|
source = root / name
|
|
target = payload / name
|
|
target.parent.mkdir(parents=True, exist_ok=True)
|
|
shutil.copyfile(source, target)
|
|
data = source.read_bytes()
|
|
manifest.append({'path': name, 'bytes': len(data), 'sha256': hashlib.sha256(data).hexdigest()})
|
|
(release / 'manifest.json').write_text(json.dumps(manifest, indent=2), encoding='utf-8')
|
|
with tarfile.open(release / 'payload.tar.gz', 'w:gz') as archive:
|
|
for row in manifest:
|
|
archive.add(payload / row['path'], arcname=row['path'])
|
|
|
|
previous_image = json.loads((release / 'baseline.json').read_text())['image']
|
|
for filename in ('01-stage.sh', '02-backup-build.sh', '03-deploy.sh', 'rollback.sh', 'Dockerfile.overlay'):
|
|
text = (old_release / filename).read_text(encoding='utf-8').replace('ark-chat-config-20260917', 'token-usage-20260917')
|
|
text = text.replace('sha256:1d6df0547b32c29ab28c6d96c0a434f5587cb1b62e97c7aaa0a454c4932c1976', previous_image)
|
|
if filename == '02-backup-build.sh':
|
|
text = text.replace('test_ark_chat_config test_model_gateway test_admin_api.ModelTestApiTest', ' '.join(tests))
|
|
if filename == '03-deploy.sh':
|
|
start = text.index("baseline=json.loads(")
|
|
end = text.index('\nPY', start)
|
|
text = text[:start] + '''baseline=json.loads((release/'baseline.json').read_text())['expected']
|
|
for name, expected in baseline.items():
|
|
assert hashlib.sha256((root/'wechat_rpa'/name).read_bytes()).hexdigest()==expected,name+' changed during staging'
|
|
''' + text[end:]
|
|
text = text.replace("print('Model configuration fix source and frontend installed.',flush=True)",
|
|
"print('Token usage source and frontend installed.',flush=True)")
|
|
# Complete in-flight generation where possible before replacing processes.
|
|
text = text.replace('docker compose config --quiet',
|
|
'docker compose config --quiet\ndocker compose stop -t 190 knowledge-worker\ndocker compose stop -t 65 gateway')
|
|
(release / filename).write_text(text, encoding='utf-8', newline='\n')
|
|
print(json.dumps({'files': len(manifest), 'package_bytes': (release / 'payload.tar.gz').stat().st_size,
|
|
'backend_tests': tests}, indent=2))
|