mirror of
https://github.com/rustfs/rustfs.git
synced 2026-09-05 19:55:37 +00:00
ci(upgrade): render an upgrade matrix in the report; fix from default
The upgrade report only ever showed the requested deb URLs and a case table. The nightly chain runs died installing the OLD package (default from_version 1.0.0-rc.4-preview.1 has no .deb asset on its release, and release 1.0.0-rc.4 ships none either), leaving an empty Total: 0 report with no indication of what was upgraded. - Default from_version is now 1.0.0-rc.3 (ships rustfs_1.0.0.rc.3_amd64.deb). Matches the auto-testing default from PR #32. - The report generator also parses the [UPG-TOPO] lines the suite now emits and renders an 'Upgrade Matrix' section: per topology and KMS backend, the versions actually in place before/after (captured via 'rustfs --version' on the node) and the aggregated result. When the suite dies before any topology completes, the matrix says so instead of silently showing nothing.
This commit is contained in:
@@ -18,9 +18,9 @@ on:
|
|||||||
workflow_dispatch:
|
workflow_dispatch:
|
||||||
inputs:
|
inputs:
|
||||||
from_version:
|
from_version:
|
||||||
description: 'OLD RustFS release tag (e.g. 1.0.0-rc.4-preview.1)'
|
description: 'OLD RustFS release tag (must ship a .deb asset, e.g. 1.0.0-rc.3)'
|
||||||
required: false
|
required: false
|
||||||
default: '1.0.0-rc.4-preview.1'
|
default: '1.0.0-rc.3'
|
||||||
from_url:
|
from_url:
|
||||||
description: 'OLD .deb URL. Overrides from_version.'
|
description: 'OLD .deb URL. Overrides from_version.'
|
||||||
required: false
|
required: false
|
||||||
@@ -203,54 +203,75 @@ jobs:
|
|||||||
TO_SOURCE="${RUSTFS_NIGHTLY_PACKAGE_URL}"
|
TO_SOURCE="${RUSTFS_NIGHTLY_PACKAGE_URL}"
|
||||||
fi
|
fi
|
||||||
CASE_TABLE="/tmp/rustfs-upgrade-cases.md"
|
CASE_TABLE="/tmp/rustfs-upgrade-cases.md"
|
||||||
python3 - "${LOG_FILE}" "${CASE_TABLE}" <<'PY'
|
MATRIX_TABLE="/tmp/rustfs-upgrade-matrix.md"
|
||||||
|
python3 - "${LOG_FILE}" "${CASE_TABLE}" "${MATRIX_TABLE}" <<'PY'
|
||||||
import re
|
import re
|
||||||
import sys
|
import sys
|
||||||
|
|
||||||
log_file, out_file = sys.argv[1], sys.argv[2]
|
log_file, out_file, matrix_file = sys.argv[1], sys.argv[2], sys.argv[3]
|
||||||
ansi = re.compile(r'\x1b\[[0-9;]*m')
|
ansi = re.compile(r'\x1b\[[0-9;]*m')
|
||||||
start_re = re.compile(r'^---\s+([A-Z]+-[0-9]+)\s+(.+?)\s+---$')
|
start_re = re.compile(r'^---\s+([A-Z]+-[0-9]+)\s+(.+?)\s+---$')
|
||||||
done_re = re.compile(r'^\[(PASS|FAIL|UNSUPPORTED)\]\s+([A-Z]+-[0-9]+)\b')
|
done_re = re.compile(r'^\[(PASS|FAIL|UNSUPPORTED)\]\s+([A-Z]+-[0-9]+)\b')
|
||||||
|
topo_re = re.compile(
|
||||||
|
r'^\[UPG-TOPO\]\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+)\s+PASS=(\d+)\s+FAIL=(\d+)\s*$')
|
||||||
|
|
||||||
rows = []
|
rows = []
|
||||||
index = {}
|
index = {}
|
||||||
|
topo_rows = []
|
||||||
try:
|
try:
|
||||||
with open(log_file, 'r', encoding='utf-8', errors='replace') as fh:
|
with open(log_file, 'r', encoding='utf-8', errors='replace') as fh:
|
||||||
for raw in fh:
|
for raw in fh:
|
||||||
line = ansi.sub('', raw).strip()
|
line = ansi.sub('', raw).strip()
|
||||||
m = start_re.match(line)
|
m = topo_re.match(line)
|
||||||
if m:
|
if m:
|
||||||
case_id, name = m.group(1), m.group(2)
|
topo_rows.append(m.groups())
|
||||||
if case_id not in index:
|
continue
|
||||||
index[case_id] = len(rows)
|
m = start_re.match(line)
|
||||||
rows.append([case_id, name, 'RUNNING'])
|
if m:
|
||||||
continue
|
case_id, name = m.group(1), m.group(2)
|
||||||
m = done_re.match(line)
|
if case_id not in index:
|
||||||
if m:
|
index[case_id] = len(rows)
|
||||||
status, case_id = m.group(1), m.group(2)
|
rows.append([case_id, name, 'RUNNING'])
|
||||||
if case_id in index:
|
continue
|
||||||
rows[index[case_id]][2] = status
|
m = done_re.match(line)
|
||||||
else:
|
if m:
|
||||||
rows.append([case_id, case_id, status])
|
status, case_id = m.group(1), m.group(2)
|
||||||
index[case_id] = len(rows) - 1
|
if case_id in index:
|
||||||
|
rows[index[case_id]][2] = status
|
||||||
|
else:
|
||||||
|
rows.append([case_id, case_id, status])
|
||||||
|
index[case_id] = len(rows) - 1
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
rows = []
|
rows = []
|
||||||
|
|
||||||
counts = {'PASS': 0, 'FAIL': 0, 'UNSUPPORTED': 0, 'RUNNING': 0}
|
counts = {'PASS': 0, 'FAIL': 0, 'UNSUPPORTED': 0, 'RUNNING': 0}
|
||||||
for _, _, status in rows:
|
for _, _, status in rows:
|
||||||
counts[status] = counts.get(status, 0) + 1
|
counts[status] = counts.get(status, 0) + 1
|
||||||
|
|
||||||
with open(out_file, 'w', encoding='utf-8') as out:
|
with open(out_file, 'w', encoding='utf-8') as out:
|
||||||
out.write('## Case Summary\n\n')
|
out.write('## Case Summary\n\n')
|
||||||
out.write(f"- Total: {len(rows)}\\n")
|
out.write(f"- Total: {len(rows)}\\n")
|
||||||
out.write(f"- PASS: {counts.get('PASS', 0)}\\n")
|
out.write(f"- PASS: {counts.get('PASS', 0)}\\n")
|
||||||
out.write(f"- FAIL: {counts.get('FAIL', 0)}\\n")
|
out.write(f"- FAIL: {counts.get('FAIL', 0)}\\n")
|
||||||
out.write(f"- UNSUPPORTED: {counts.get('UNSUPPORTED', 0)}\\n")
|
out.write(f"- UNSUPPORTED: {counts.get('UNSUPPORTED', 0)}\\n")
|
||||||
out.write('\\n')
|
out.write('\\n')
|
||||||
out.write('| Case | Name | Status |\\n')
|
out.write('| Case | Name | Status |\\n')
|
||||||
out.write('| --- | --- | --- |\\n')
|
out.write('| --- | --- | --- |\\n')
|
||||||
for case_id, name, status in rows:
|
for case_id, name, status in rows:
|
||||||
out.write(f'| {case_id} | {name} | {status} |\\n')
|
out.write(f'| {case_id} | {name} | {status} |\\n')
|
||||||
|
|
||||||
|
# Upgrade matrix: one row per topology/backend with the versions
|
||||||
|
# captured on the nodes (rustfs --version) and the aggregated
|
||||||
|
# result. The dashboard renders this table directly.
|
||||||
|
with open(matrix_file, 'w', encoding='utf-8') as out:
|
||||||
|
out.write('## Upgrade Matrix\n\n')
|
||||||
|
out.write('| Topology | KMS Backend | 升级前版本 | 升级后版本 | 升级结果 |\n')
|
||||||
|
out.write('| --- | --- | --- | --- | --- |\n')
|
||||||
|
for topo, backend, old_v, new_v, npass, nfail in topo_rows:
|
||||||
|
result = 'PASS' if nfail == '0' else 'FAIL'
|
||||||
|
out.write(f'| {topo} | {backend} | {old_v} | {new_v} | {result} (PASS={npass} FAIL={nfail}) |\n')
|
||||||
|
if not topo_rows:
|
||||||
|
out.write('| - | - | - | - | 未执行(套件在升级前失败) |\n')
|
||||||
PY
|
PY
|
||||||
{
|
{
|
||||||
echo "# RustFS upgrade compatibility report"
|
echo "# RustFS upgrade compatibility report"
|
||||||
@@ -261,6 +282,8 @@ jobs:
|
|||||||
echo "- To: ${TO_SOURCE}"
|
echo "- To: ${TO_SOURCE}"
|
||||||
echo "- Test Step Outcome: ${{ steps.test.outcome }}"
|
echo "- Test Step Outcome: ${{ steps.test.outcome }}"
|
||||||
echo ""
|
echo ""
|
||||||
|
cat "${MATRIX_TABLE}" || true
|
||||||
|
echo ""
|
||||||
cat "${CASE_TABLE}" || true
|
cat "${CASE_TABLE}" || true
|
||||||
echo ""
|
echo ""
|
||||||
echo "## Log tail"
|
echo "## Log tail"
|
||||||
|
|||||||
Reference in New Issue
Block a user