BitzOrcas 的流水线已经落地,不再处于“计划中”。它由两条相互独立的证据链组成:常规 CI 判断源码是否达到合并和发布候选标准;Commercial GA 判断某个不可变商业发布批次是否真的可以交付。
关键路径图
下图展示了自动化 CI/CD 质量流水线:从代码提交、ArchUnit 架构门禁扫描、Testcontainers 真实容器测试,到 AOT 编译与 Docker 镜像构建。
常规 CI 的五组 Job
| Job | PR | main push | 手工/夜间 | 预算 | 验证重点 |
|---|---|---|---|---|---|
| Portability gate | ✓ | ✓ | ✓ | 30 分钟 | ubuntu/windows/macos 三 OS 还原与 Release 构建 + 架构门禁测试 |
| Fast gate | ✓ | ✓ | ✓ | 15 分钟 | Secret、格式、IDE0005、OpenAPI 漂移、快速测试、Consumer 合同、XML |
| Release candidate | — | ✓ | ✓ | 30 分钟 | 模板矩阵、无 Docker 集成测试 |
| Publish trim | — | — | ✓ | 15 分钟 | linux-x64 / win-x64 / osx-arm64 三 RID 裁剪发布 |
| Docker contracts | — | — | ✓ | 每片 30 分钟 | 13 个 Testcontainers 合同分片(仅 dispatch/夜间触发) |
Fast gate
Fast gate 优先拦住高频、可快速复现的问题:
Gitleaks → restore → format --verify-no-changes + IDE0005 未用 using 清零 → OpenAPI 漂移检查(check-openapi-drift.sh) → Release build → 分层过滤的非 Integration 测试 → 本地 PackageReference Consumer Contract → XML 文件和 XML 注释检查Consumer Contract 被单独执行,因为它会打包候选 NuGet 包、创建临时 Feed 和隔离缓存,再从仓库外项目完成 restore、build、test 与 trim publish。它证明“包可以被消费”,不证明“包已经正式发布”。
Release candidate
发布候选 Job 执行 canonical 模板组合与升级验证,再运行 Category!=Docker 的集成测试。它不在 PR 上运行,以免每次评审都重复较重的模板矩阵;main push、手工和夜间任务会补齐这层证据。
Publish trim
trim Job 在 linux-x64 / win-x64 / osx-arm64 三个 RID 矩阵上恢复资产并执行 -p:PublishTrimmed=true 发布。未登记的 IL 警告或发布错误会阻断 Job。不要用全局 NoWarn 掩盖新反射路径;先判断依赖是否应该进入 API 主路径。
Docker contracts
真实基础设施合同在 docker-integration-contracts.yml 中拆成 13 片:shared-port-a/b/c/d、shared-repository、shared-readmodel-queryshape、shared-generic、website、webhooks、messaging、authorization-capacity、core 与 workflow。该 workflow 由发布流程或夜间调度调用,不在每次 main push 上常驻。fail-fast: false 允许一次运行收集多个分片的结果。
Commercial GA 做什么
Commercial GA 只能手工触发。它检出 provenance 记录的 commit,从可信 release workflow 下载不可变 artifact,然后验证:
- 包集合、PackageId、版本与商业包目录一致;
- 包 SHA-256、Git commit、provenance 互相匹配;
dotnet nuget verify --all接受签名和可信时间戳;- signer fingerprint 与受控集合完全一致;
- SBOM 覆盖发布包及其依赖;
- 漏洞阈值和第三方许可证策略为 pass;
- 外部 Consumer 使用认证 HTTPS Feed 和短期只读凭据,在空缓存环境完成 restore、build、test、publish。
缺少任何前置输入时,脚本会输出 external prerequisite unavailable 并失败。它不会从产品源码重新 pack,也不会把本地 Feed 当成生产 Feed。
本地如何复现
质量门禁入口在 scripts/build/。GitHub Actions 工作流在 .github/workflows/。客户机 systemd 发版用的 Jenkinsfile 在仓库根 ci/,不要搬进 scripts/。这些检查脚本以 bash 为准,在 Linux CI 或 Git Bash / WSL 中运行,不提供 PowerShell 对等脚本。
合并前完整本地入口:
scripts/build/verify-all.sh只改 workflow 或构建脚本时,先跑最小相关集:
# ① 在仓库根目录执行;每条命令都应能独立验证。dotnet test tests/BitzOrcas.Architecture.Tests \ --configuration Release \ --filter "FullyQualifiedName~CiQualityGateTests"
git diff --check检查 Commercial GA 环境输入是否齐全:
scripts/build/verify-commercial-ga.sh --check-prerequisites常见失败
| 位置 | 常见原因 | 处理顺序 |
|---|---|---|
| Gitleaks | 误提交凭据或测试值误报 | 真实凭据先撤销;确认假阳性后登记最小 allowlist |
| Consumer Contract | 包闭包、Source Mapping、隔离缓存问题 | 从第一个 restore 错误和临时 NuGet.Config 查起 |
| Release candidate | 模板组合或升级路径漂移 | 单独运行 scripts/build/verify-template.sh |
| Docker shard | 镜像、资源、容器就绪或 parity 断言 | 先区分基础设施失败与业务语义失败 |
| Trim | 新反射、RID 资产或不兼容依赖 | 查 trim 状态文档,不要直接压制警告 |
| Commercial GA | 外部输入缺失或发布证据不一致 | 缺输入由发布环境补齐;证据不一致则撤回批次 |