64 lines
4.6 KiB
Python
64 lines
4.6 KiB
Python
"""Prepare v1.4.28 package QA only; never build or alter product files."""
|
|
from pathlib import Path
|
|
import ast
|
|
import hashlib
|
|
import json
|
|
import shutil
|
|
|
|
folder = Path(__file__).resolve().parent
|
|
baseline = folder.parent / 'review-voice-20260918'
|
|
root = Path('C:/wechat_rpa')
|
|
old_sha = '1ef5f2155992423cdb0ac3d3c0f29bcbd5f401baae13d359a98292d02c036fff'
|
|
old = root / 'releases/甄AI客服-安装包-v1.4.27.exe'
|
|
assert hashlib.sha256(old.read_bytes()).hexdigest() == old_sha
|
|
|
|
mapping = {
|
|
'build_review_voice_v1_4_27.ps1': 'build_contact_recovery_v1_4_28.ps1',
|
|
'build_windows_cached_review_voice.ps1': 'build_windows_cached_contact_recovery.ps1',
|
|
'validate_review_voice_v1_4_27.ps1': 'validate_contact_recovery_v1_4_28.ps1',
|
|
'verify_review_voice_frozen.py': 'verify_contact_recovery_frozen.py',
|
|
'run_review_voice_frozen_regressions.py': 'run_contact_recovery_frozen_regressions.py',
|
|
'run_isolated_review_voice.py': 'run_isolated_contact_recovery.py',
|
|
'verify_review_voice_nsis.py': 'verify_contact_recovery_nsis.py',
|
|
'verify_frozen_review_voice_notifications.py': 'verify_frozen_contact_recovery_notifications.py',
|
|
'verify_frozen_offline_asr.py': 'verify_frozen_offline_asr.py',
|
|
}
|
|
for source_name, destination_name in mapping.items():
|
|
content = (baseline / source_name).read_text(encoding='utf-8-sig')
|
|
for before, after in mapping.items():
|
|
content = content.replace(before, after)
|
|
content = content.replace('1.4.27', '1.4.28').replace('1.4.26', '1.4.27')
|
|
content = content.replace('a558c24f7db00ec907be46f8ce67f2d9d7bb1f60992306bfa64020e294818a38', old_sha)
|
|
content = content.replace('review-voice', 'contact-recovery').replace('review and voice release', 'contact recovery release')
|
|
if source_name == 'build_review_voice_v1_4_27.ps1':
|
|
marker = "$taskPython = Join-Path $taskRoot '.build-venv\\Scripts\\python.exe'"
|
|
content = content.replace(marker, "if (([IO.DriveInfo]::new('C:\\')).AvailableFreeSpace -lt 3500000000) { throw 'At least 3.5 GB free disk space required; do not delete user data to build' }\n" + marker)
|
|
content = content.replace("rapidocr_onnxruntime; from Crypto.Cipher import AES", "rapidocr_onnxruntime,faster_whisper,ctranslate2,av,pysilk; from Crypto.Cipher import AES")
|
|
if source_name in {'build_review_voice_v1_4_27.ps1', 'verify_review_voice_frozen.py', 'run_review_voice_frozen_regressions.py'}:
|
|
content = content.replace("'wechat_gui_qt','app_version'", "'wechat_gui_qt','app_version','contact_reply_guard','contact_relation'")
|
|
if source_name == 'validate_review_voice_v1_4_27.ps1':
|
|
marker = "& $taskPython -B (Join-Path $PSScriptRoot 'verify_contact_recovery_nsis.py')"
|
|
content = content.replace(marker, "& $taskPython -I -S (Join-Path $PSScriptRoot 'verify_frozen_offline_asr.py')\nif ($LASTEXITCODE -ne 0) { throw 'Actual frozen offline ASR verification failed' }\n" + marker)
|
|
destination = folder / destination_name
|
|
if destination.exists():
|
|
raise FileExistsError(destination)
|
|
destination.write_text(content, encoding='utf-8-sig' if destination.suffix == '.ps1' else 'utf-8')
|
|
if destination.suffix == '.py':
|
|
ast.parse(content, filename=str(destination))
|
|
|
|
plan = json.loads((baseline / 'review-voice-release-plan.json').read_text(encoding='utf-8-sig'))
|
|
plan.update(finalized=False, version='1.4.28', previousVersion='1.4.27', previousInstallerSha256=old_sha)
|
|
plan['frozenModules'].append('contact_relation')
|
|
plan['windowsTestModules'] = ['test_protocol_contact_recovery', 'test_contact_relation_snapshot', *plan['windowsTestModules']]
|
|
plan['notes'] = 'Prepare only. Root must finish, test and freeze contact re-add reception fixes before finalized=true. Reuse installed ASR dependencies/assets; no downloads. No live messages, settings, queues, installation or uploads.'
|
|
(folder / 'contact-recovery-release-plan.json').write_text(json.dumps(plan, ensure_ascii=False, indent=2), encoding='utf-8')
|
|
for extension in ('wav', 'silk', 'amr'):
|
|
shutil.copy2(baseline / f'synthetic-chinese.{extension}', folder / f'synthetic-chinese.{extension}')
|
|
report = dict(prepared=True, built=False, productFilesChanged=False, version='1.4.28', previousInstaller=str(old),
|
|
previousInstallerBytes=old.stat().st_size, previousInstallerSha256=old_sha,
|
|
freeDiskBytes=shutil.disk_usage(root).free, requiredFreeDiskBytes=3500000000,
|
|
dependenciesInstalled=False, modelsDownloaded=False, installed=False,
|
|
realMessagesSent=0, files=list(mapping.values()))
|
|
(folder / 'package-preparation.json').write_text(json.dumps(report, ensure_ascii=False, indent=2), encoding='utf-8')
|
|
print(json.dumps(report, ensure_ascii=False))
|