CI:按 SYSTEM 账户视角修正 Python / cppcheck 探测
CI / L0 静态门禁 (pre-commit) (push) Failing after 16s
CI / L0.5 主机侧单测 (MSVC) (push) Successful in 16s

第三次运行(run#3)已越过 PS 语法问题,环境自检真正执行,
暴露 runner 真实环境缺陷:

1. cppcheck 只在【用户级 PATH】,SYSTEM 账户看不到 →
   报 runner missing cppcheck。已在自检步骤加回落到
   C:\Program Files\Cppcheck 并写入 GITHUB_PATH。

2. 更隐蔽:SYSTEM 的 python 解析到 C:\msys64\ucrt64\bin\python.exe
   (3.14.5),而该解释器【没有 pre-commit】(AGENTS.md 亦明令
   不得用它跑依赖第三方库的脚本)。若不修,自检通过后 L0 会在
   pre-commit 步骤炸。
   处置:在自检步骤按 scripts/ci_local.py 同一探测序
   (PATH python -> .venv -> anaconda3)挑出真正装了 pre-commit
   的解释器,导出 PYTHON 环境变量供后续步骤使用。
   L0.5 是独立 job(GITHUB_ENV 不跨 job),同法就地选一个可用
   python(主机侧单测为纯标准库,任意 python3 均可,已用 msys64
   python 实测 39/39 PASS)。

附带:run 块保持纯 ASCII(上次修正),全部 shell=powershell。
This commit is contained in:
2026-10-02 01:21:10 +08:00
parent e241fea801
commit 8e7b22184e
+59 -20
View File
@@ -78,34 +78,60 @@ jobs:
- name: 环境自检(Python / cppcheck / pre-commit)
shell: powershell
run: |
# NOTE: keep every run: block pure ASCII. The runner writes this block
# to a BOM-less .ps1 executed by Windows PowerShell 5.1, which decodes
# it as GBK -- non-ASCII bytes there break string quoting.
$ErrorActionPreference = 'Stop'
$missing = @()
foreach ($item in @(
@{ name = 'Python'; cmd = 'python' },
@{ name = 'cppcheck'; cmd = 'cppcheck' }
)) {
if (-not (Get-Command $item.cmd -ErrorAction SilentlyContinue)) {
$missing += $item.name
}
# --- pick a Python that actually has pre-commit -------------------
# The runner runs as SYSTEM, whose PATH is NOT the dev user's PATH.
# On this box SYSTEM's `python` is C:\msys64\...\python.exe (3.14.5,
# no pre-commit). Probe the same order as scripts/ci_local.py:
# current interpreter -> .venv -> anaconda3
$repoRoot = (Get-Location).Path
$candidates = @(
(Get-Command python -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source),
(Join-Path $repoRoot '.venv\Scripts\python.exe'),
'C:\ProgramData\anaconda3\python.exe'
)
$py = $null
foreach ($c in $candidates) {
if (-not $c) { continue }
if (-not (Test-Path $c)) { continue }
& $c -m pre_commit --version *> $null
if ($LASTEXITCODE -eq 0) { $py = $c; break }
}
if ($missing.Count -gt 0) {
Write-Host "::error::runner missing: $($missing -join ', ') -- install then re-run"
if (-not $py) {
Write-Host "::error::no Python with pre-commit found. Tried: $($candidates -join ' | ')"
exit 1
}
Write-Host "using python: $py"
& $py --version
& $py -m pre_commit --version
"PYTHON=$py" | Out-File -FilePath $env:GITHUB_ENV -Append
# --- cppcheck -----------------------------------------------------
# cppcheck is often installed with a USER-scope PATH entry, which
# SYSTEM cannot see. Fall back to its default install dir.
$cpp = Get-Command cppcheck -ErrorAction SilentlyContinue
if ($cpp) {
Write-Host "found cppcheck: $($cpp.Source)"
} elseif (Test-Path 'C:\Program Files\Cppcheck\cppcheck.exe') {
$dir = 'C:\Program Files\Cppcheck'
$env:Path = "$env:Path;$dir"
"C:\Program Files\Cppcheck" | Out-File -FilePath $env:GITHUB_PATH -Append
Write-Host "cppcheck not on PATH; added $dir (User-scope PATH is invisible to SYSTEM)"
} else {
Write-Host "::error::runner missing cppcheck -- install it, then re-run"
exit 1
}
python --version
cppcheck --version
# pre-commit: use `python -m pre_commit` (does not rely on PATH console script)
python -m pre_commit --version
if ($LASTEXITCODE -ne 0) {
Write-Host "::error::runner missing pre-commit (pip install pre-commit)"
exit 1
}
Write-Host "runner environment check passed"
- name: 安装 pre-commit 钩子到本仓库
shell: powershell
run: python -m pre_commit install --install-hooks
run: "& $env:PYTHON -m pre_commit install --install-hooks"
- name: 决定跳过哪些钩子(Keil 依赖)
id: skip
@@ -128,7 +154,7 @@ jobs:
SKIP: ${{ steps.skip.outputs.value }}
run: |
if ($env:SKIP) { Write-Host "SKIP=$env:SKIP" }
python -m pre_commit run --all-files --show-diff-on-failure
& $env:PYTHON -m pre_commit run --all-files --show-diff-on-failure
if ($LASTEXITCODE -ne 0) {
Write-Host "::error::L0 static gates failed (see output above)"
exit $LASTEXITCODE
@@ -173,6 +199,19 @@ jobs:
if: steps.msvc.outputs.value == 'yes'
shell: powershell
run: |
# Resolve a working Python first (SYSTEM's PATH python may be unusable).
$repoRoot = (Get-Location).Path
$py = $null
foreach ($c in @(
(Get-Command python -ErrorAction SilentlyContinue | Select-Object -ExpandProperty Source),
(Join-Path $repoRoot '.venv\Scripts\python.exe'),
'C:\ProgramData\anaconda3\python.exe'
)) {
if ($c -and (Test-Path $c)) { $py = $c; break }
}
if (-not $py) { Write-Host "::error::no python found"; exit 1 }
Write-Host "using python: $py"
# Iterate test/host/*/run_unit_test.py (each module ships its own runner via common harness)
$runners = Get-ChildItem -Path 'test/host' -Recurse -Filter 'run_unit_test.py' |
Sort-Object FullName
@@ -185,7 +224,7 @@ jobs:
Write-Host "================================"
Write-Host "run: $($r.FullName)"
Write-Host "================================"
python $r.FullName
& $py $r.FullName
if ($LASTEXITCODE -ne 0) {
Write-Host "::error::unit test failed: $($r.FullName) (exit $LASTEXITCODE)"
$fail = 1