09e45573c8
首次 CI 运行(run#1)两个 job 均失败于同一处: Cannot find: pwsh in PATH 根因:workflow 用 shell: pwsh(PowerShell 7,非 Windows 自带), 而 runner 所在机器只有 Windows PowerShell 5.1。 改为 shell: powershell(7 处)。已核验脚本无 PS7 独有语法 (无 ?? / ?: / && / || / -Parallel),PS 5.1 完全兼容。 workflow 头部补该坑说明,防止将来误改回 pwsh。 注:本次 CI 已验证 actions/checkout@v4 可从本实例正常拉取并 成功检出 v2-on-ui,action 拉取链路无需调整。
195 lines
8.4 KiB
YAML
195 lines
8.4 KiB
YAML
# Gitea Actions CI —— STM32F4-Base 持续集成
|
||
#
|
||
# 覆盖范围(**只做不依赖硬件的层**,见 docs/测试说明/测试开发标准流程.md §1/§9):
|
||
# L0 静态门禁 = pre-commit 全部钩子(等价本地 `pre-commit run --all-files`)
|
||
# L0.5 主机侧纯逻辑单测 = test/host/**(MSVC 离线编译,零硬件)
|
||
#
|
||
# ⛔ L1 板端套件(test/board/,需真机 + ST-LINK)/ L2 @test 闭环 / L3 人工目检
|
||
# **不上 CI** —— 需要开发板与烧录器,只能在本地跑。
|
||
#
|
||
# 明确不做的两件事(都是刻意为之):
|
||
# 1. `@build`(Keil UV4)—— 需本机 Keil 授权,runner 上不具备;且 L0 的 cppcheck +
|
||
# 代码规范已覆盖"编译前的静态问题",真编译仍是开发者的本地红线(AGENTS.md)。
|
||
# 2. `mem-numbers` 钩子 —— 它的事实源是 `MDK-ARM/**/*.map`(Keil 构建产物、已 gitignore),
|
||
# 无 `@build` 即无 `.map`。故本 workflow 在**检测不到 .map 时自动跳过该钩子**
|
||
# (见下方 "决定跳过哪些钩子" 步骤),有 .map 的 runner(如自建带 Keil 的机器)则照常跑。
|
||
#
|
||
# 触发:push(除纯文档路径外)与 pull_request。
|
||
#
|
||
# 🔴 shell 用 `powershell` 而非 `pwsh`(2026-10-02 实测修正):
|
||
# `pwsh` = PowerShell 7,**不是 Windows 自带**;本机 runner 只有
|
||
# Windows PowerShell 5.1(`C:\Windows\System32\WindowsPowerShell\v1.0\`),
|
||
# 用 `shell: pwsh` 会直接报 `Cannot find: pwsh in PATH` → job 失败(跑不到任何业务逻辑)。
|
||
# `shell: powershell` 在任意 Windows 上都存在,且本 workflow 的脚本
|
||
# **刻意只用 PS 5.1 兼容语法**(无 `??`/`?:`/`&&`/`||`/`-Parallel`)。
|
||
# ⚠️ 若将来要改回 `pwsh`,须先在所有 runner 上装 PowerShell 7。
|
||
#
|
||
# ⚠️ 前置(部署到 Gitea 时需确认):
|
||
# - 该 Gitea 实例已启用 Actions:`[actions] ENABLED = true`(site admin 配置)
|
||
# - 已注册一个 **Windows** runner(labels 含 `windows`),且装有:
|
||
# Python 3.x、cppcheck、pre-commit、MSVC(VS2019/2022 的 C++ 工具链 + Windows SDK)
|
||
# - 缺 MSVC 时 L0.5 步骤会**降级为提示并跳过**(不硬失败),但会打印醒目 WARNING
|
||
#
|
||
# 本地等价命令(与 CI 同一套判定,见 scripts/ci_local.py):
|
||
# & '.venv\Scripts\python.exe' scripts/ci_local.py
|
||
|
||
name: CI
|
||
|
||
on:
|
||
push:
|
||
branches: ['**']
|
||
paths-ignore:
|
||
- 'docs/**'
|
||
- '**/*.md'
|
||
- '.workbuddy-ai/**'
|
||
pull_request:
|
||
paths-ignore:
|
||
- 'docs/**'
|
||
- '**/*.md'
|
||
- '.workbuddy-ai/**'
|
||
workflow_dispatch:
|
||
|
||
# 同一分支的旧运行自动取消,省 runner
|
||
concurrency:
|
||
group: ci-${{ github.ref }}
|
||
cancel-in-progress: true
|
||
|
||
jobs:
|
||
# ------------------------------------------------------------------
|
||
# L0:静态门禁(pre-commit 钩子全集)
|
||
# ------------------------------------------------------------------
|
||
l0-gates:
|
||
name: L0 静态门禁 (pre-commit)
|
||
runs-on: windows
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
with:
|
||
# 钩子要对比基线与历史(doc-links 等读工作区即可,但 gitlint/cubemx 需完整历史)
|
||
fetch-depth: 0
|
||
|
||
- name: 环境自检(Python / cppcheck / pre-commit)
|
||
shell: powershell
|
||
run: |
|
||
$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
|
||
}
|
||
}
|
||
if ($missing.Count -gt 0) {
|
||
Write-Host "::error::runner 缺少:$($missing -join ', ') —— 请安装后重跑"
|
||
exit 1
|
||
}
|
||
python --version
|
||
cppcheck --version
|
||
|
||
# pre-commit:优先用 `python -m pre_commit`(不依赖 PATH 里的 console script)
|
||
python -m pre_commit --version
|
||
if ($LASTEXITCODE -ne 0) {
|
||
Write-Host "::error::runner 缺少 pre-commit(pip install pre-commit / uv tool install pre-commit)"
|
||
exit 1
|
||
}
|
||
Write-Host "runner 环境自检通过"
|
||
|
||
- name: 安装 pre-commit 钩子到本仓库
|
||
shell: powershell
|
||
run: python -m pre_commit install --install-hooks
|
||
|
||
- name: 决定跳过哪些钩子(Keil 依赖)
|
||
id: skip
|
||
shell: powershell
|
||
run: |
|
||
# mem-numbers 的事实源是 Keil 构建产物 .map(已 gitignore)。
|
||
# 无 .map => 本 runner 不可能跑 L0 的该钩子 => 跳过(不是"通过",是"不适用")。
|
||
$map = Get-ChildItem -Path 'MDK-ARM' -Recurse -Filter '*.map' -ErrorAction SilentlyContinue
|
||
if ($map) {
|
||
Write-Host "找到 .map:$($map[0].FullName) —— mem-numbers 照常运行"
|
||
"value=" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
||
} else {
|
||
Write-Host "::notice::未找到 .map(未做 Keil 构建)—— 跳过 mem-numbers 钩子"
|
||
"value=mem-numbers" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
||
}
|
||
|
||
- name: 运行 L0 门禁(--all-files)
|
||
shell: powershell
|
||
env:
|
||
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
|
||
if ($LASTEXITCODE -ne 0) {
|
||
Write-Host "::error::L0 静态门禁未通过(详见上方输出)"
|
||
exit $LASTEXITCODE
|
||
}
|
||
|
||
# ------------------------------------------------------------------
|
||
# L0.5:主机侧纯逻辑单测(零硬件;缺 MSVC 则跳过)
|
||
# ------------------------------------------------------------------
|
||
l05-host-unit-tests:
|
||
name: L0.5 主机侧单测 (MSVC)
|
||
runs-on: windows
|
||
steps:
|
||
- uses: actions/checkout@v4
|
||
|
||
- name: 探测 MSVC(VS BuildTools / Community 等)
|
||
id: msvc
|
||
shell: powershell
|
||
run: |
|
||
# 与 test/host/common/unit_test_harness.py 的 VS_ROOTS 保持一致
|
||
$roots = @(
|
||
'C:\Program Files (x86)\Microsoft Visual Studio\2019\BuildTools',
|
||
'C:\Program Files\Microsoft Visual Studio\2022\BuildTools',
|
||
'C:\Program Files\Microsoft Visual Studio\2022\Community',
|
||
'C:\Program Files\Microsoft Visual Studio\2022\Professional'
|
||
)
|
||
$found = $false
|
||
foreach ($r in $roots) {
|
||
if (Test-Path $r) {
|
||
$cl = Get-ChildItem -Path $r -Recurse -Filter 'cl.exe' -ErrorAction SilentlyContinue |
|
||
Where-Object { $_.FullName -like '*Hostx64\x64*' } | Select-Object -First 1
|
||
if ($cl) { $found = $true; Write-Host "找到 cl.exe: $($cl.FullName)"; break }
|
||
}
|
||
}
|
||
if ($found) {
|
||
"value=yes" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
||
} else {
|
||
Write-Host "::warning::runner 未安装 MSVC(VS C++ 工具链)—— 跳过 L0.5 单测。请安装 VS BuildTools 后重跑。"
|
||
"value=no" | Out-File -FilePath $env:GITHUB_OUTPUT -Append
|
||
}
|
||
|
||
- name: 运行主机侧单测
|
||
if: steps.msvc.outputs.value == 'yes'
|
||
shell: powershell
|
||
run: |
|
||
# 遍历 test/host/*/run_unit_test.py(各模块自带运行器,统一走 common harness)
|
||
$runners = Get-ChildItem -Path 'test/host' -Recurse -Filter 'run_unit_test.py' |
|
||
Sort-Object FullName
|
||
if (-not $runners) {
|
||
Write-Host "::warning::未找到 test/host/**/run_unit_test.py —— 跳过"
|
||
exit 0
|
||
}
|
||
$fail = 0
|
||
foreach ($r in $runners) {
|
||
Write-Host "================================"
|
||
Write-Host "运行:$($r.FullName)"
|
||
Write-Host "================================"
|
||
python $r.FullName
|
||
if ($LASTEXITCODE -ne 0) {
|
||
Write-Host "::error::单测失败:$($r.FullName)(退出码 $LASTEXITCODE)"
|
||
$fail = 1
|
||
}
|
||
}
|
||
exit $fail
|
||
|
||
- name: L0.5 跳过说明
|
||
if: steps.msvc.outputs.value == 'no'
|
||
shell: powershell
|
||
run: |
|
||
Write-Host "L0.5 未执行:runner 缺 MSVC。"
|
||
Write-Host "本地等价命令:& '.venv\Scripts\python.exe' scripts/ci_local.py"
|
||
exit 0
|