流水线与自动化:从 workflow 到 artifact 与 runner
0. 元信息
- 主题路径:
docs/topics/ci-cd-and-release/subtopics/pipeline-and-automation/README.md - 主分类:工程技术
- 辅助分类:安全与可靠性
- 适合对象:完成父主题前置,能写 Dockerfile 和 shell 的开发者
- 建议周期:5~8 天,每天 1.5~2 小时
- 前置知识:父主题 §0 列举的前置主题
- 最终目标:能独立写出可重复、可扫描、可发布的 GitHub Actions / GitLab CI pipeline,留存 workflow YAML、runner log 与 artifact 证据
1. 学习路线
workflow 语法(on / jobs / steps / runs-on / needs)
→ matrix / cache / concurrency / artifact
→ self-hosted runner / act 本地跑
→ OIDC 与 secret 管理
→ 扫描与 SBOM 输出(trivy / syft)
→ cosign 签名 + push 到 OCI registry
2. 阶段周数分配
精简子主题不固定周数。按概念、正常路径、失败路径、综合实验四段推进,共 5~8 天。
3. 九阶段表
| 阶段 | 核心知识 | 实践产出 | 可观察学会标准 |
|---|---|---|---|
| 1 | workflow schema、on trigger、jobs、steps、runs-on | 一条 echo + checkout 的 hello world run | 能在 PR 上看到绿勾,理解 on: 的事件触发条件 |
| 2 | needs、if、env、permissions、uses vs run | 两 jobs 顺序依赖图 | 能解释每个 ${{ }} 表达式与 shell 变量的边界 |
| 3 | matrix.include / exclude、concurrency group、cancel-in-progress | 4×2 矩阵 + 自动取消旧 run | 矩阵规模 ≤ 256,超限能拆 workflow |
| 4 | actions/cache@v4、key 设计、restore-keys、跨 job 缓存 | go module / pnpm store 命中证据 | 改一行代码 cache 不失效,改 lockfile 才会失效 |
| 5 | docker/build-push-action、buildx、cache-to / cache-from、multi-platform | multi-arch image(amd64+arm64)推送 GHCR | --platform linux/amd64,linux/arm64 跑通,digest 一致 |
| 6 | actions/upload-artifact@v4、artifact retention、跨 job 下载 | 把 build 产物传给 deploy job | artifact 链接可下载,retention ≤ 90 天可调 |
| 7 | self-hosted runner、act 本地跑 runner label、自定义 image | k8s 里的 actions-runner-controller 或 VM runner | 任务在自托管跑,日志含 label |
| 8 | OIDC、permissions: id-token: write、cloud trust policy、cosign sign | 不存 long-lived key 拿到 cloud token | audit log 出现 role 临时凭证 |
| 9 | SBOM(syft / trivy)、scan、build provenance | artifact 同时含 image + SBOM + signature | cosign verify 拒签伪造制品 |
4. 第一周任务
精简子主题省略逐日表。每天只引入一个变量;先跑正常路径,再做四类失败实验。Day 1 必须明确 runner、permissions 与 secret 来源。
5. 阶段通用验收
采用父主题 §5;本页额外要求保存 workflow YAML、runner log 链接、artifact 下载链接、cache 命中日志、cosign verify 输出与清理命令。
6. 最终验收
完成 1 条生产级 workflow(build / test / scan / sign / push / artifact)、至少 4 类失败实验、一次本地 act 重放、一次 OIDC 部署演练,并用 10 分钟解释 jobs、cache、matrix、OIDC 的边界。
7. 综合项目
把本页产出合入父主题首选项目:GitHub Actions → GHCR → k8s Argo Rollouts 金丝雀发布全链路。单独交付时,提供 workflow 文件、act 重放脚本、notes/retrospective.md。
本主题贡献
本主题把 GitHub Actions 当作 CI 引擎:workflow DAG、matrix/cache/concurrency、self-hosted runner、OIDC 短期凭证、SBOM 生成与 cosign 签名串成可重复、可回放、可验证的流水线。
职责(3 项)
- 设计 workflow YAML(
on/jobs/steps/runs-on/needs/if/env/permissions),画 jobs 之间的 DAG,能解释${{ }}表达式与 shell 变量边界、为什么permissions:默认值要在 job 顶部显式声明、为什么pull_request_target暴露 secrets 给 fork PR 是反模式; - 用
actions/cache@v4+hashfiles('**/go.sum')设计 lockfile 级缓存,用 buildxcache-to/cache-from(type=gha/type=registry) 做 multi-platform(amd64+arm64)缓存,能解释为什么 key 含 lockfile 才命中、为什么@sha256:...锁 commit 而非@main; - 用
permissions: id-token: write+ cloud trust policy(sub限定 repo + workflow)拿 OIDC 短期凭证替代 long-lived AWS access key,用cosign sign --keyless+ Rekor transparency log 签 image。
交付物(4 项)
- 生产级 workflow YAML(build / test / scan / sign / push / artifact 完整 DAG),含
concurrencygroup 自动取消旧 run; act本地重放脚本(nektos/act,Apache-2.0)+ runner log 链接 + artifact 下载链接;- SBOM(Anchore Syft 输出 SPDX)+
cosign verify输出 +grype sbom:漏洞扫描结果,artifact 同时含 image + SBOM + signature; - OIDC 部署演练(
aws-actions/configure-aws-credentials@v4)的 cloud audit log 截图,证明 role 临时凭证而非 long-lived key。
指标(3 项)
- build cache 命中率 ≥ 80%(key 含 lockfile hash 后);
- cosign verify 在 deploy gate 阻断伪造制品率 = 100%;
- 同 commit → 同 image digest 比例 = 100%(锁 base digest、build context 时间戳、
org.opencontainers.image.revision)。
8. 推荐开源资料
GitHub Actions 官方文档作主线;act 仓库(nektos/act,Apache-2.0)作本地 runner;buildx(docker/buildx,Apache-2.0)作多平台;aquasecurity/trivy-action(Apache-2.0)作扫描;sigstore/cosign-installer(Apache-2.0)作签名;actions-runner-controller(GitHub,Apache-2.0)作 k8s 自托管 runner。复制前核对当前 LICENSE。
9. 学习资料汇聚(v0.3 自包含)
9.1 背景与动机
CI 把 commit 变成可发布制品。流水线核心做四件事:build(编译/打包/构建 image)、test(单元/集成/e2e)、scan(漏洞/依赖/配置)、ship(签名/推送/产出 artifact)。每件事都必须可重复、可追溯、可回放。
GitHub Actions 用 YAML 描述 steps,依赖 Docker 容器或 JS 脚本作为 step;GitLab CI 用 .gitlab-ci.yml,依赖 Docker/Ruby 镜像;CircleCI 用 config.yml,依赖 executor。三者语法略有差异,但模型都是 event-driven + DAG + cache + artifact。
今天流水线工程化的关键不是「跑得通」,而是「可重复、可签名、可回放」:同 commit 必须产出同 digest;image 必须带 SBOM 和 provenance;secret 不能用 long-lived key;runner 必须可控。
9.2 概念地图
flowchart LR
Event[on: push / PR / tag / workflow_dispatch] --> Jobs
Jobs --> Job1[build]
Jobs --> Job2[test]
Jobs --> Job3[scan]
Jobs --> Job4[sign]
Jobs --> Job5[push]
Job1 --> Artifact[artifact]
Job2 --> Artifact
Job3 --> SBOM[SBOM]
Job4 --> Sig[cosign sig]
Job5 --> Registry[OCI registry]
Cache[actions/cache] -.缓存.-> Job1
Cache -.缓存.-> Job2
Runner[runner label / self-hosted] --> Jobs
OIDC[OIDC token] -.短时凭证.-> Job5
核心关系:event 触发 jobs,jobs 之间用 needs 形成 DAG;cache 跨 run 复用二进制,artifact 跨 job 传递产物;OIDC 提供短期凭证;sign + SBOM 让制品可验证。
9.3 基础知识讲解
9.3.1 论文 / 规范
| 资料 | 用法 |
|---|---|
| GitHub Actions workflow schema | 查 on / jobs / steps 字段定义 |
| GitLab CI YAML reference | 看 include、extends、needs DAG |
| OCI Distribution Spec | 看 manifest、tag、digest、push/pull 协议 |
| SLSA Build L3 | 对照 GitHub Actions generated provenance |
| in-toto attestation | 查 build provenance 字段 |
9.3.2 书
| 资料 | 用法 |
|---|---|
| Humble & Farley, Continuous Delivery | 第八章「部署流水线」原文 |
| Forsgren 等, Accelerate | CI/CD 与 DORA 的统计关联 |
| Brikman, Terraform: Up & Running | IaC 章节作后续铺垫 |
9.3.3 博客 / 文档
| 资料 | 用法 |
|---|---|
| GitHub Actions 文档 | 主线 |
| GitHub Actions Security Hardening | 必读,避免 pwn request |
| GitLab CI/CD Reference | 对照 Actions 差异 |
| act 仓库 | 本地 runner |
| actions-runner-controller | k8s 自托管 |
| Trivy 文档 | 扫描 |
| cosign 文档 | 签名 |
| Syft 文档 | SBOM |
| Docker BuildKit 文档 | cache mount 与 multi-platform |
9.3.4 人物
| 人物 | 关注点 |
|---|---|
| Jez Humble | Continuous Delivery 原始定义 |
| Kelsey Hightower | k8s / GitOps / The Hard Way |
| Dan Lorenc | Sigstore / SLSA |
| Solomon Hykes | Docker / buildx |
| lukeabrown(GitHub 工程) | Actions 公开演讲 |
9.3.5 方法
| 方法 | 动作 |
|---|---|
| Pin everything | actions/checkout@v4 而不是 @main,@sha256:... 锁 commit |
| Least permissions | job 级 permissions:,避免 write-all |
| OIDC over key | 用 aws-actions/configure-aws-credentials@v4 + OIDC role |
| Cache by lockfile | key = hashfiles('**/go.sum') 而不是 hashfiles('**') |
| Artifact only for outputs | 中间产物走 artifact,二进制依赖走 cache |
| Reproducible build | 锁 base digest、go version、npm version,保留 build provenance |
| Local replay | 用 act 本地重放,定位 fail |
9.4 经典问题与经典案例
| # | 问题 | 最简答案 |
|---|---|---|
| 1 | workflow 写完不触发 | 检查 on: 字段是否在 default branch;PR 来自 fork 时 secrets 不可用 |
| 2 | matrix 超过 256 报错 | 拆 workflow 或用 fromJSON 动态 matrix |
| 3 | cache key 命中率为 0 | key 没含 lockfile hash,加 hashfiles('**/go.sum') |
| 4 | artifact 90 天后清掉 | retention 设 1–90 天,长期归档用 release |
| 5 | self-hosted runner 卡死 | 任务没清理,runner 进程 hang,加 healthcheck 与 timeout |
| 6 | OIDC token 拿不到 | trust policy sub 条件写错,对照 cloud audit log |
| 7 | image digest 每次都不同 | base 没锁、build context 时间戳漂移,用 --label org.opencontainers.image.revision |
| 8 | SBOM 缺语言包 | syft 没装对应 cataloger,加 --source python 等 |
| 9 | cosign verify 失败 | transparency log 不可达或 trust root 没配,配 Fulcio / Rekor |
| 10 | fork PR 拿到 secret | 默认 secrets 不可用于 fork,用 pull_request_target 要谨慎 |
| 11 | buildx cache 命中率低 | cache backend 没配;用 type=gha 或 type=registry |
| 12 | job 间传文件丢失 | 没 actions/upload-artifact 或下载路径错 |
9.5 学习难点
概念难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
${{ }} vs shell 变量 | 表达式与 shell 变量命名冲突 | 把表达式结果赋给 env:,step 内只用 shell 变量 |
| needs vs if | 顺序与条件容易写错 | 先画 DAG,再加 if |
permissions: 默认值 | repo / org 默认不同 | 在 job 顶部显式声明 |
| Tag vs digest | latest 看起来是版本 | 部署用 digest |
思维难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
| 失败定位 | 「红了」不是诊断 | 看 step log、artifact、网络、cache |
| 流水线复杂度爆炸 | 一个 workflow 做太多事 | 拆成可复用 workflow(workflow_call) |
| 缓存策略 | 一刀切 cache 容易失效 | key 分层:lockfile / OS / runner |
工程难点
| 难点 | 为什么会卡 | 突破路径 |
|---|---|---|
| self-hosted 安全 | runner 可读 secrets | 用 ephemeral runner,job 完销毁 |
| OIDC 配置 | trust policy / audience 错 | 先 staging 跑通,看 audit log |
| multi-platform build | QEMU / arm64 runner 缺 | 用 buildx + QEMU 或 GitHub arm64 runner |
| Cache backend | gha cache 大小有限 | 用 type=registry 或 type=s3 |
| SBOM 体积 | cycloneDX 文件过大 | 选 SPDX,只输出 production deps |
9.6 技术标准与接口
9.6.1 Entity
| 名称 | 发布组织 | 角色 | 状态 / 可访问性 |
|---|---|---|---|
| GitHub Actions | GitHub | CI 引擎 | 持续更新,公开 |
| GitLab CI | GitLab | CI 引擎 | 持续更新,公开 |
| CircleCI | CircleCI | CI 引擎 | 持续更新,公开 |
| nektos/act | 社区 | 本地 runner | Apache-2.0 |
| actions-runner-controller | GitHub | k8s 自托管 runner | Apache-2.0 |
| BuildKit | Docker / Moby | 构建引擎 | Apache-2.0 |
| OCI Distribution Spec | OCI | registry 协议 | Apache-2.0 |
| Sigstore cosign | Sigstore | 签名 | Apache-2.0 |
| Anchore Syft | Anchore | SBOM | Apache-2.0 |
| Aqua Trivy | Aqua | 扫描 | Apache-2.0 |
| SLSA | Linux Foundation | 供应链规范 | 公开 |
9.6.2 Scope
CI 引擎负责 workflow 调度与执行;runner 提供执行环境;artifact / cache 提供跨 job 与跨 run 存储;registry 提供 OCI 制品存储;签名 / SBOM 提供完整性证明。它们之间用 OCI、OIDC、SLSA 互通。
9.6.3 Structure
必须掌握 on event 字段(push / pull_request / workflow_dispatch / schedule)、jobs 结构(runs-on / needs / if / env / permissions / steps)、step 字段(uses / run / with / env / id)、cache key 设计(hashfiles)、artifact retention、OIDC trust policy(sub / aud)、cosign sign / verify-blob。
9.6.4 Ecosystem
GitHub Actions 生态最大;GitLab CI 与 GitLab 平台深度集成;CircleCI 在 monorepo 与 orbs 上有优势。BuildKit 是底层构建引擎,docker buildx 是 CLI。Sigstore 提供 cosign、Rekor、Fulcio。扫描工具还有 Snyk、Grype。
9.6.5 Depth Tiers
| 层级 | 可观察能力 |
|---|---|
| L0 | 知道 CI、artifact、cache、matrix、OIDC、SBOM 是什么 |
| L1 | 能读 workflow YAML、cache key、cosign verify 输出 |
| L2 | 能写一条 pipeline,配 cache、matrix、OIDC、SBOM、签名 |
| L3 | 能从 runner log / cache 命中 / artifact 解释失败,并设计 pipeline-as-code |
| L4 | 能设计自定义 action、自托管 runner 平台、跨云 OIDC 联邦 |
本子主题目标是 L3。
9.6.6 Source
- GitHub Actions 文档
- GitHub Actions Security Hardening
- GitLab CI Reference
- BuildKit 文档
- Sigstore cosign
- SLSA v1.0
- 引用版本快照日期:2026-07-30;实作前运行
gh --version、act --version、cosign version。
10. 常见误区
- 缓存 key 用
*命中率低; @main而不是@v4/@sha256:...;- 默认
permissions: write-all; - 用 long-lived AWS access key;
pull_request_target暴露 secrets 给 fork PR;- matrix 不限并发,撞 256;
- artifact 存大文件、retention 不调;
- self-hosted runner 当 long-lived 容器用,泄露 secrets;
- OIDC trust policy
sub写得太宽; - cosign 签了制品但 deploy 不 verify;
- SBOM 输出但没卡 release gate;
- fork PR 跑 workflow 默认 secrets 不可用,写代码时不读文档。
11. 所有知识点分类(统一规则)
- 编程语言;2. 数据结构与算法;3. 计算机基础;4. 工程技术;5. Web 与后端;6. 前端与客户端;7. 数据与人工智能;8. 项目与职业能力;9. 安全与可靠性。
本计划归属:工程技术 主 + 安全与可靠性 辅。