1. 最小 workflow 长什么样?
根目录 .github/workflows/ci.yml 里通常包含:name、on(何时跑)、jobs。 每个 job 指定 runs-on,下面是一串 step:uses 引用现成 action,或 run 直接跑 shell。
记忆:同一 job 内 step 共享文件系统与环境变量;不同 job 默认隔离,要靠 artifact 或缓存传递产物。
2. 事件(on):谁在按门铃?
- push:分支推送;常用于 main 构建与发布。
- pull_request:PR 打开/同步;注意来自 fork 的 PR 默认 GITHUB_TOKEN 只读且不能写 secrets(防窃取)。
- schedule:cron 定时(注意时区 UTC)。
- workflow_dispatch:手动点运行,可带 inputs。
图 1:一次 push 触发 workflow;lint 与 test 可并行,build 依赖二者,deploy 再依赖 build(DAG)。
3. Job 与 Step:同一台 runner 上的顺序剧本
每个 job 分配到一台 runner(一个虚拟机或容器环境)。该 job 内 step 从上到下执行,前一个 step 的目录与 env 对后续可见(除非 step 用了隔离容器)。 常用模式:checkout → setup 语言 → 缓存 → 测试 → 上传 artifact。
图 2:同一 job 内 step 顺序执行,共享 workspace;常用「检出 → 工具链 → 缓存 → 测试」流水线。
4. Runner:hosted 与 self-hosted 的取舍
- GitHub-hosted:免运维、每次干净环境、分钟计费;适合大多数 CI。
- self-hosted:自定义硬件、内网资源、长缓存;需严格隔离与权限(标签匹配防误跑恶意 PR)。
安全:对 self-hosted,务必用 pull_request_target 等高级触发前理解风险;默认应对不可信 fork 使用 hosted runner + 最小权限。
5. GITHUB_TOKEN 与 permissions
每个 workflow run 会注入 GITHUB_TOKEN。默认权限较宽的历史行为已收紧趋势:应在 workflow 顶或 job 级写 permissions: 按需最小化(contents: read 等)。 Secrets 仅在受信任上下文可用;fork PR 工作流不能读取仓库 secrets(设计如此)。
图 3:同一条 workflow 语法,在「同仓」与「fork PR」下 secrets 与 token 能力不同;permissions 应显式最小化。
6. 最小清单
- 每个仓库至少一条 CI workflow:on: pull_request + push main。
- 并行 lint/test job,合并前 required checks。
- 写明 permissions,勿把 secrets 打印到 log。
- 需要矩阵多版本时用 strategy.matrix(下一章可深化)。