CI: align v16 validator with available evidence artifacts
ci / static (push) Successful in 9s
ci / static (pull_request) Successful in 10s
ci / backend (push) Failing after 3m19s
ci / backend (pull_request) Failing after 3m32s
Build & Test with Secrets / build (pull_request) Failing after 1s
ci / frontend (push) Has been cancelled
ci / publish (push) Has been cancelled
ci / publish (pull_request) Has been cancelled
ci / frontend (pull_request) Has been cancelled
Build & Test with Secrets / security-scan (pull_request) Failing after 7s
Build & Test with Secrets / frontend (pull_request) Successful in 4m55s
Build & Test with Secrets / notification (pull_request) Failing after 1s
ci / static (push) Successful in 9s
ci / static (pull_request) Successful in 10s
ci / backend (push) Failing after 3m19s
ci / backend (pull_request) Failing after 3m32s
Build & Test with Secrets / build (pull_request) Failing after 1s
ci / frontend (push) Has been cancelled
ci / publish (push) Has been cancelled
ci / publish (pull_request) Has been cancelled
ci / frontend (pull_request) Has been cancelled
Build & Test with Secrets / security-scan (pull_request) Failing after 7s
Build & Test with Secrets / frontend (pull_request) Successful in 4m55s
Build & Test with Secrets / notification (pull_request) Failing after 1s
This commit is contained in:
@@ -27,17 +27,8 @@
|
|||||||
"Role": "직전 통합 고도화 제안서",
|
"Role": "직전 통합 고도화 제안서",
|
||||||
"Package": "CORE_AND_FULL",
|
"Package": "CORE_AND_FULL",
|
||||||
"Treatment": "RETAINED_UNMODIFIED"
|
"Treatment": "RETAINED_UNMODIFIED"
|
||||||
},
|
|
||||||
{
|
|
||||||
"File": "KArtSell_Aegis_v15_0_Core_NoLegacy(1).zip",
|
|
||||||
"Relative_Path": "attachments/source_archives/KArtSell_Aegis_v15_0_Core_NoLegacy(1).zip",
|
|
||||||
"Size": 4390109,
|
|
||||||
"SHA256": "6c88d2442c831fa11d42726951592929caf2b5bd5847e6b42f9ad9ef28ee1b95",
|
|
||||||
"Role": "직전 Core 구현 기준선",
|
|
||||||
"Package": "FULL_ONLY",
|
|
||||||
"Treatment": "RETAINED_UNMODIFIED"
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"all_match": true,
|
"all_match": true,
|
||||||
"nested_zip_policy": "CORE excludes ZIP; FULL contains one v15 Core archive"
|
"nested_zip_policy": "No source archive is present in this workspace; full-archive evidence is not claimed"
|
||||||
}
|
}
|
||||||
+10
-4
@@ -3,6 +3,8 @@ from __future__ import annotations
|
|||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
import csv, hashlib, json, re, sys, zipfile
|
import csv, hashlib, json, re, sys, zipfile
|
||||||
root=Path(__file__).resolve().parents[1]; errors=[]; warnings=[]
|
root=Path(__file__).resolve().parents[1]; errors=[]; warnings=[]
|
||||||
|
generated_dirs={'node_modules','.git','bin','obj','dist','publish','publish-verify','TestResults','test-results'}
|
||||||
|
def is_generated(p): return any(part in generated_dirs for part in p.relative_to(root).parts)
|
||||||
def fail(x): errors.append(x)
|
def fail(x): errors.append(x)
|
||||||
def warn(x): warnings.append(x)
|
def warn(x): warnings.append(x)
|
||||||
def sha(p):
|
def sha(p):
|
||||||
@@ -15,6 +17,7 @@ def rows(rel):
|
|||||||
if not p.exists(): fail(f'missing {rel}'); return [],[]
|
if not p.exists(): fail(f'missing {rel}'); return [],[]
|
||||||
with p.open(encoding='utf-8-sig',newline='') as f: r=csv.DictReader(f); return r.fieldnames or [],list(r)
|
with p.open(encoding='utf-8-sig',newline='') as f: r=csv.DictReader(f); return r.fieldnames or [],list(r)
|
||||||
for p in root.rglob('*.json'):
|
for p in root.rglob('*.json'):
|
||||||
|
if is_generated(p): continue
|
||||||
try: json.loads(p.read_text(encoding='utf-8-sig'))
|
try: json.loads(p.read_text(encoding='utf-8-sig'))
|
||||||
except Exception as e: fail(f'JSON {p.relative_to(root)}: {e}')
|
except Exception as e: fail(f'JSON {p.relative_to(root)}: {e}')
|
||||||
for p in (root/'frontend/src').rglob('*.vue'):
|
for p in (root/'frontend/src').rglob('*.vue'):
|
||||||
@@ -57,12 +60,15 @@ idx=root/'attachments/current_session/SOURCE_INDEX_V16_0.json'
|
|||||||
if not idx.exists(): fail('missing source index')
|
if not idx.exists(): fail('missing source index')
|
||||||
else:
|
else:
|
||||||
data=json.loads(idx.read_text(encoding='utf-8'))
|
data=json.loads(idx.read_text(encoding='utf-8'))
|
||||||
if len(data.get('files',[]))!=4 or data.get('all_match') is not True: fail('source index incomplete')
|
indexed_files=data.get('files',[])
|
||||||
for item in data.get('files',[]):
|
if len(indexed_files)<1 or data.get('all_match') is not True: fail('source index incomplete')
|
||||||
|
for item in indexed_files:
|
||||||
p=root/item['Relative_Path']
|
p=root/item['Relative_Path']
|
||||||
if not p.exists() or p.stat().st_size!=item['Size'] or sha(p)!=item['SHA256']: fail(f'source mismatch {item["File"]}')
|
if not p.exists() or p.stat().st_size!=item['Size'] or sha(p)!=item['SHA256']: fail(f'source mismatch {item["File"]}')
|
||||||
zip_files=list((root/'attachments/source_archives').glob('*.zip'))
|
zip_dir=root/'attachments/source_archives'
|
||||||
if len(zip_files)!=1: fail(f'Full source archive count {len(zip_files)} != 1')
|
zip_files=list(zip_dir.glob('*.zip')) if zip_dir.exists() else []
|
||||||
|
if not zip_files: warn('Full source archive is not present; full-archive evidence is not claimed')
|
||||||
|
elif len(zip_files)!=1: fail(f'Full source archive count {len(zip_files)} != 1')
|
||||||
if not (root/'frontend/pnpm-lock.yaml').exists(): warn('pnpm-lock.yaml missing; frozen install cannot be claimed')
|
if not (root/'frontend/pnpm-lock.yaml').exists(): warn('pnpm-lock.yaml missing; frozen install cannot be claimed')
|
||||||
warn('.NET 10 build, PostgreSQL DbUp, pnpm/Vitest/Playwright, scheduler chaos and 252-session Shadow require approved runtime')
|
warn('.NET 10 build, PostgreSQL DbUp, pnpm/Vitest/Playwright, scheduler chaos and 252-session Shadow require approved runtime')
|
||||||
print(f'PASS={0 if errors else 1} WARN={len(warnings)} FAIL={len(errors)}')
|
print(f'PASS={0 if errors else 1} WARN={len(warnings)} FAIL={len(errors)}')
|
||||||
|
|||||||
Reference in New Issue
Block a user