forked from wangbo/easyai
48 lines
2.9 KiB
Python
48 lines
2.9 KiB
Python
#!/usr/bin/env python3
|
|
"""Both command-line shells honor a live stable source even when Git's snapshot differs."""
|
|
from functools import partial
|
|
from http.server import SimpleHTTPRequestHandler, ThreadingHTTPServer
|
|
import json
|
|
import os
|
|
from pathlib import Path
|
|
import subprocess
|
|
import tempfile
|
|
from threading import Thread
|
|
|
|
source = Path(__file__).resolve().parent.parent
|
|
with tempfile.TemporaryDirectory(prefix='easyai-release-source-') as temporary:
|
|
root = Path(temporary)
|
|
manifest = json.loads((source/'system-update/releases/3.29.0.20261014.2.json').read_text())
|
|
manifest['channel'] = 'stable'
|
|
manifest['components'] = [item for item in manifest['components'] if item['key'] in {'server-main','web','ws-gateway'}]
|
|
(root/'release-manifest.json').write_text(json.dumps(manifest))
|
|
class Handler(SimpleHTTPRequestHandler):
|
|
def log_message(self, *args): pass
|
|
server = ThreadingHTTPServer(('127.0.0.1',0),partial(Handler,directory=str(root)))
|
|
thread = Thread(target=server.serve_forever,daemon=True)
|
|
thread.start()
|
|
script = root/'plan.ps1'
|
|
script.write_text('param($Security,$Versions,$Path)\n$ErrorActionPreference="Stop"\n. $Security\n. $Versions\n@(Get-ApplicationVersionPlan -Path $Path) | ConvertTo-Json -Compress\n')
|
|
env = {k:v for k,v in os.environ.items() if not k.startswith(('UPDATE_','DEPLOY_'))}
|
|
try:
|
|
for mode, filename, expected in [('remote','release-manifest.json','3.29.0.20261014.2'),('remote','missing.json',None),('local','missing.json','3.30.2.20261017')]:
|
|
path = root/'.env'
|
|
path.write_text(f'VERSION=latest\nUPDATE_MANIFEST_SOURCE={mode}\nUPDATE_MANIFEST_URL=http://127.0.0.1:{server.server_port}/{filename}?token=synthetic-secret-must-not-appear\n')
|
|
before = path.read_bytes()
|
|
commands = [['python3',str(source/'scripts/resolve-deployment-release.py'),'--env-file',str(path),'--format','json'],
|
|
['pwsh','-NoProfile','-NonInteractive','-File',str(script),str(source/'scripts/Initialize-SecurityEnv.ps1'),str(source/'scripts/Initialize-ApplicationVersions.ps1'),str(path)]]
|
|
for command in commands:
|
|
result = subprocess.run(command,env=env,capture_output=True,text=True,timeout=90)
|
|
assert 'synthetic-secret-must-not-appear' not in result.stdout+result.stderr
|
|
assert (result.returncode==0)==bool(expected),(mode,filename,result.stdout,result.stderr)
|
|
if expected:
|
|
plan=json.loads(result.stdout)
|
|
values={entry['Key']:entry['Version'] for entry in plan}
|
|
assert values['VERSION']==expected
|
|
assert values['SERVER_VERSION'].startswith(expected+'@sha256:')
|
|
assert path.read_bytes()==before
|
|
print(mode+'/'+filename+': both shells selected the authoritative source without stale fallback or credential logging')
|
|
finally:
|
|
server.shutdown()
|
|
server.server_close()
|