fix: deploy verify parsing must ignore ssh warning lines (#55)
Co-authored-by: host <host@test.local>
This commit is contained in:
1 parent
32125f7a98
commit
84ff968111
2 files changed
+45
-2
No files matched your search
+16
-2
@@ -35,6 +35,7 @@ import argparse
|
|||||||
import hashlib
|
import hashlib
|
||||||
import json
|
import json
|
||||||
import os
|
import os
|
||||||
|
import re
|
||||||
import shutil
|
import shutil
|
||||||
import subprocess
|
import subprocess
|
||||||
import sys
|
import sys
|
||||||
@@ -183,11 +184,24 @@ def scp_cmd(host, user, local, remote):
|
|||||||
|
|
||||||
|
|
||||||
def remote_sha(host, user, remote_path):
|
def remote_sha(host, user, remote_path):
|
||||||
|
"""远端 sha256sum 的输出里取 64 位 hex。不能取 split()[0]:经 pty
|
||||||
|
的 ssh helper 会把 stderr 的 Warning(例如 Permanently added to
|
||||||
|
the list of known hosts)合并进 stdout 放在 sha 行前面,首 token
|
||||||
|
于是变成 Warning:,导致传输明明成功却被判验真失败(2026-10-27
|
||||||
|
新链路首推实测)。"""
|
||||||
r = subprocess.run(ssh_cmd(host, user, "sha256sum %s" % remote_path),
|
r = subprocess.run(ssh_cmd(host, user, "sha256sum %s" % remote_path),
|
||||||
capture_output=True, text=True)
|
capture_output=True, text=True)
|
||||||
if r.returncode != 0:
|
if r.returncode != 0:
|
||||||
return None
|
return None
|
||||||
return r.stdout.split()[0] if r.stdout.split() else None
|
m = re.search(r"\b[0-9a-f]{64}\b", r.stdout)
|
||||||
|
return m.group(0) if m else None
|
||||||
|
|
||||||
|
|
||||||
|
def live_commit(text):
|
||||||
|
"""从 ssh 输出里取 40 位 commit。理由同 remote_sha:helper 的
|
||||||
|
Warning 行会混进 stdout,直接 strip() 比对必失败。"""
|
||||||
|
m = re.search(r"\b[0-9a-f]{40}\b", text)
|
||||||
|
return m.group(0) if m else None
|
||||||
|
|
||||||
|
|
||||||
def remote_rm(host, user, remote_path):
|
def remote_rm(host, user, remote_path):
|
||||||
@@ -312,7 +326,7 @@ def main(argv=None):
|
|||||||
live = subprocess.run(
|
live = subprocess.run(
|
||||||
ssh_cmd(host, user, "cat /opt/codex-app-server/DEPLOYED_COMMIT"),
|
ssh_cmd(host, user, "cat /opt/codex-app-server/DEPLOYED_COMMIT"),
|
||||||
capture_output=True, text=True)
|
capture_output=True, text=True)
|
||||||
if live.stdout.strip() != commit:
|
if live_commit(live.stdout) != commit:
|
||||||
print("二次核对失败:live DEPLOYED_COMMIT=%s,期望 %s。"
|
print("二次核对失败:live DEPLOYED_COMMIT=%s,期望 %s。"
|
||||||
"请立即用 deploy/rollback.sh 检查,不要再推新版。"
|
"请立即用 deploy/rollback.sh 检查,不要再推新版。"
|
||||||
% (live.stdout.strip(), commit), file=sys.stderr)
|
% (live.stdout.strip(), commit), file=sys.stderr)
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import sys
|
|||||||
import tarfile
|
import tarfile
|
||||||
import tempfile
|
import tempfile
|
||||||
import unittest
|
import unittest
|
||||||
|
from unittest import mock
|
||||||
|
|
||||||
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(
|
REPO_ROOT = os.path.dirname(os.path.dirname(os.path.dirname(
|
||||||
os.path.abspath(__file__))))
|
os.path.abspath(__file__))))
|
||||||
@@ -52,6 +53,34 @@ class TestDeployPure(unittest.TestCase):
|
|||||||
finally:
|
finally:
|
||||||
os.unlink(path)
|
os.unlink(path)
|
||||||
|
|
||||||
|
def test_remote_sha_ignores_ssh_warning_lines(self):
|
||||||
|
# 2026-10-27 新链路首推实测:pty helper 把 ssh 的 Warning 行
|
||||||
|
# 合并进 stdout 放在 sha 行前面,旧 split()[0] 取到 Warning:
|
||||||
|
# 导致传输明明成功却被判验真失败、两路都“失败”。
|
||||||
|
sha = "5d0645b85a65b2d58d0d5812f9e8020bdafe15d60dc440e763cfcc7cd178148b"
|
||||||
|
fake = subprocess.CompletedProcess(
|
||||||
|
args=[], returncode=0,
|
||||||
|
stdout="Warning: Permanently added 'x' (ED25519) to the list of known hosts.\n"
|
||||||
|
+ sha + " /tmp/x.tar.gz\n", stderr="")
|
||||||
|
with mock.patch.object(deploy_mod.subprocess, "run",
|
||||||
|
return_value=fake):
|
||||||
|
self.assertEqual(deploy_mod.remote_sha("h", "u", "/tmp/x"), sha)
|
||||||
|
|
||||||
|
def test_remote_sha_none_without_hash(self):
|
||||||
|
fake = subprocess.CompletedProcess(args=[], returncode=0,
|
||||||
|
stdout="Warning: something\n",
|
||||||
|
stderr="")
|
||||||
|
with mock.patch.object(deploy_mod.subprocess, "run",
|
||||||
|
return_value=fake):
|
||||||
|
self.assertIsNone(deploy_mod.remote_sha("h", "u", "/tmp/x"))
|
||||||
|
|
||||||
|
def test_live_commit_ignores_ssh_warning_lines(self):
|
||||||
|
commit = "32125f7a980e24fd28664a60701d7c1123beb63e"
|
||||||
|
out = "Warning: Permanently added 'x' (ED25519) to the list of known hosts.\n" \
|
||||||
|
+ commit + "\n"
|
||||||
|
self.assertEqual(deploy_mod.live_commit(out), commit)
|
||||||
|
self.assertIsNone(deploy_mod.live_commit("Warning: something\n"))
|
||||||
|
|
||||||
|
|
||||||
class TestBuildRelease(unittest.TestCase):
|
class TestBuildRelease(unittest.TestCase):
|
||||||
def test_build_from_temp_git_repo(self):
|
def test_build_from_temp_git_repo(self):
|
||||||
|
|||||||
Reference in new issue
Block a user