fix(deploy): 通过更新脚本恢复受控仓库镜像定义
Test deployment public URL (Linux) / test-linux (push) Canceled after 0s

This commit is contained in:
easyai02
2026-10-05 11:35:47 +08:00
parent 125b12a1d8
commit e3d760c5ab
5 changed files with 146 additions and 5 deletions
+15 -1
View File
@@ -30,6 +30,10 @@ def git(*args):
upstream = git('rev-parse', '--abbrev-ref', '@{upstream}').strip()
subprocess.run(['git', 'fetch', '--quiet', upstream.split('/')[0]], check=True)
subprocess.run(['git', 'merge-base', '--is-ancestor', 'HEAD', upstream], check=True)
restore_images = set(os.environ.get('UPDATE_RESTORE_REPOSITORY_IMAGES', '').split())
selected_services = set(os.environ.get('UPDATE_SERVICES', '').split())
if restore_images - {'easyai-server', 'easyai-web', 'ws-gateway'} or restore_images - selected_services:
sys.exit('❌ 恢复仓库镜像只支持本次 UPDATE_SERVICES 中的核心服务;尚未修改配置或容器')
changed = set(git('diff', 'HEAD', '--name-only').splitlines())
if changed - {'docker-compose.yml'}:
sys.exit('❌ 存在部署配置以外的本地代码修改;尚未修改配置或容器')
@@ -125,6 +129,14 @@ base = canonical(yaml.safe_load(git('show', 'HEAD:docker-compose.yml')))
local = canonical(yaml.safe_load((root / 'docker-compose.yml').read_text()))
remote_text = git('show', upstream + ':docker-compose.yml')
remote = canonical(yaml.safe_load(remote_text))
# Explicitly release reviewed local image pins through the deployment project.
# Other local settings and pins on services outside this update remain intact.
for service in sorted(restore_images):
remote_service = remote.get('services', {}).get(service, {})
local_service = local.get('services', {}).get(service, {})
if not isinstance(remote_service.get('image'), str) or not isinstance(local_service, dict) or not local_service:
sys.exit('❌ 无法读取目标服务的仓库镜像定义;尚未修改配置或容器')
local_service['image'] = remote_service['image']
# Early managed deployments removed Watchtower's old token while disabling its
# HTTP trigger. Current deployments require a shared internal token; restore the
# upstream reference, whose value is initialized by update.sh, rather than
@@ -180,7 +192,9 @@ for name in collisions:
(root / name).unlink()
if changed:
subprocess.run(['git', 'restore', '--source=HEAD', '--staged', '--worktree', '--', 'docker-compose.yml'], check=True)
(backup / 'migration.json').write_text(json.dumps({'from': git('rev-parse', 'HEAD').strip(), 'to': git('rev-parse', upstream).strip(), 'preservedFields': preserved, 'files': sorted(changed | collisions)}, indent=2))
(backup / 'migration.json').write_text(json.dumps({'from': git('rev-parse', 'HEAD').strip(), 'to': git('rev-parse', upstream).strip(), 'preservedFields': preserved, 'restoredRepositoryImages': sorted(restore_images), 'files': sorted(changed | collisions)}, indent=2))
(backup / 'migration.json').chmod(0o600)
print('✅ 已备份旧配置并迁移本地差异;新版部署字段由仓库继续管理')
print(' 备份目录: ' + str(backup))
if restore_images:
print(' 已恢复仓库镜像定义: ' + ', '.join(sorted(restore_images)))