Skip to content

build: Bump the minor-and-patch group with 8 updates #162

build: Bump the minor-and-patch group with 8 updates

build: Bump the minor-and-patch group with 8 updates #162

Workflow file for this run

# 日常 push / PR 的构建与测试门禁;发布流水线见 release.yml。
name: ci
on:
push:
branches: [main]
pull_request:
branches: [main]
permissions:
contents: read
jobs:
build-test:
strategy:
fail-fast: false
matrix:
include:
# 现代 .NET 在 linux 跑(附带覆盖率收集);net48(验证 netstandard2.0 资产)需要 Windows 运行时
- os: ubuntu-latest
frameworks: "net8.0 net10.0"
- os: windows-latest
frameworks: "net48"
runs-on: ${{ matrix.os }}
steps:
- uses: actions/checkout@v7
- name: Set up .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
10.0.x
- name: Build
run: dotnet build StreamFrame.slnx -c Release
- name: Test (${{ matrix.frameworks }})
shell: bash
env:
FRAMEWORKS: ${{ matrix.frameworks }}
# 覆盖率只在 Ubuntu 收集(矩阵值不进 job 名,避免必需检查名随之变化)
COLLECT_COVERAGE: ${{ matrix.os == 'ubuntu-latest' }}
run: |
for fw in $FRAMEWORKS; do
if [ "$COLLECT_COVERAGE" = "true" ]; then
dotnet test StreamFrame.slnx -c Release --no-build -f $fw \
--collect:"XPlat Code Coverage" --results-directory "coverage/$fw"
else
dotnet test StreamFrame.slnx -c Release --no-build -f $fw
fi
done
# 覆盖率摘要写入 job Summary(自包含,不依赖外部服务);原始 cobertura XML 附为 artifact
- name: Coverage summary
if: matrix.os == 'ubuntu-latest'
shell: bash
run: |
python3 - <<'PYEOF'
import glob, os, xml.etree.ElementTree as ET
def fmt(rate):
return f"{rate * 100:.1f}%"
lines = ["", "## 测试覆盖率(XPlat Code Coverage)", "",
"| 目标 | Line | Branch | 覆盖行/总行 |", "|---|---|---|---|"]
for tfm_dir in sorted(glob.glob("coverage/*")):
tfm = os.path.basename(tfm_dir)
reports = glob.glob(os.path.join(tfm_dir, "**", "coverage.cobertura.xml"), recursive=True)
if not reports:
continue
# 同一 TFM 只应有一份(单一测试项目);防御性取第一份
root = ET.parse(reports[0]).getroot()
line_rate = float(root.get("line-rate", "0"))
branch_rate = float(root.get("branch-rate", "0"))
all_lines = list(root.iter("line"))
covered_lines = sum(1 for l in all_lines if int(l.get("hits", "0")) > 0)
lines.append(f"| {tfm} | {fmt(line_rate)} | {fmt(branch_rate)} | {covered_lines}/{len(all_lines)} |")
if tfm.endswith("net8.0"):
detail = ["", f"<details><summary>按程序集({tfm})</summary>", "",
"| 程序集 | Line | Branch |", "|---|---|---|"]
for pkg in root.iter("package"):
detail.append(f"| {pkg.get('name', '?')} | "
f"{fmt(float(pkg.get('line-rate', '0')))} | "
f"{fmt(float(pkg.get('branch-rate', '0')))} |")
detail += ["", "</details>", ""]
lines += detail
summary = "\n".join(lines) + "\n"
print(summary)
with open(os.environ.get("GITHUB_STEP_SUMMARY", "/dev/stdout"), "a", encoding="utf-8") as f:
f.write(summary)
PYEOF
- name: Upload coverage artifacts
if: matrix.os == 'ubuntu-latest'
uses: actions/upload-artifact@v7
with:
name: coverage-${{ github.run_number }}
path: coverage/
retention-days: 14
# NativeAOT/裁剪兼容性门禁(非必需检查):发布引用库的冒烟工程(PublishAot 在工程内开启,
# 涵盖裁剪分析)。IL2026/IL3050 等警告经 TreatWarningsAsErrors 变为错误,防止库悄悄
# 引入反射/动态代码。ubuntu runner 自带 AOT 原生工具链。
aot:
runs-on: ubuntu-latest
timeout-minutes: 15
steps:
- uses: actions/checkout@v7
- name: Set up .NET
uses: actions/setup-dotnet@v6
with:
dotnet-version: |
8.0.x
10.0.x
- name: PublishAot(NativeAOT + 裁剪警告门禁)
run: dotnet publish samples/StreamFrame.AotSmoke -c Release -r linux-x64 -o artifacts/aot
- name: Run NativeAOT smoke(连接、会话发送、普通发送与内容校验)
run: timeout 40s ./artifacts/aot/StreamFrame.AotSmoke
- name: Verify NativeAOT failure exit codes
shell: bash
run: |
set -euo pipefail
for fault in connect missing consumer content; do
category="$fault"
case "$fault" in
connect) category=connection ;;
missing) category=messages ;;
esac
status=0
timeout 40s ./artifacts/aot/StreamFrame.AotSmoke "--fault=$fault" > "$fault.log" 2>&1 || status=$?
cat "$fault.log"
# 只接受程序自身报告的指定故障:0、崩溃、启动失败或 timeout 的 124 均失败。
if [ "$status" -ne 1 ] || ! grep -Fq "AOT smoke FAILED [$category]:" "$fault.log"; then
echo "::error::Fault $fault was not detected correctly (exit=$status)"
exit 1
fi
echo "Verified expected failure: $fault (exit=$status)" | tee -a "$GITHUB_STEP_SUMMARY"
done