用途
gh-deploy-pipeline 用于为正在运行的应用或服务搭建或对齐 GitHub Actions 部署流水线,帮助仓库统一到“先验证、后部署”的形态。其核心是推送至 main 后,检测变更、构建一次产物、对构建产物运行端到端测试,再通过 GitHub Environment 将同一产物提升部署。部署的具体实现属于目标平台或基础设施仓库,本技能负责工作流契约、信任边界与验证闭环。
流水线形态
标准流程为:
- push to main
- detect-changes(paths-filter 或图感知的受影响检测)
- verify-<lane>(lint + typecheck + test + build,并上传产物)
- e2e-<lane>(下载产物,对其运行 e2e)
- deploy-<env>-<lane>(环境作用域凭据 + OIDC,提升产物)
- smoke-<env>-<lane>(只读任务,无部署凭据,访问已部署 URL)
每个 lane 相互独立:仅 web 变更时只构建和部署 web,不影响 api。verify 与 e2e 任务可取消被取代的运行;deploy 任务使用按(environment, lane)划分的不可取消并发组,避免两次推送竞争同一目标。
另可提供独立的 deploy.yml(workflow_dispatch),针对已验证的 ref、environment 和 lane 重新部署已有产物或镜像。它复用相同的 environment、并发组与来源校验,不会重新构建任意输入代码。
使用方式
- 先检查仓库:现有 .github/workflows/*、环境名称、部署脚本、基础设施入口、发布看板及近期失败运行。仅当现有工作流已使用环境门禁、OIDC 或作用域凭据、不可变产物和部署后验证时,才保留其契约。
- 确认前置条件:部署分支、默认分支合并策略、目标环境、环境保护规则、OIDC 信任策略或环境作用域凭据、产物/镜像保留策略、smoke 端点。
- 按 references/workflows.md 编写 .github/workflows/main.yml,可选 .github/workflows/deploy.yml。保持 changes -> verify -> e2e -> deploy -> smoke;手动触发用于提升已有已验证产物/镜像。
- 在自造检查前先加入标准加固栈:actionlint 检查语法,zizmor 检查 GitHub Actions 安全,以及扫描器支持的 secret/安全检查门禁。
- 建立变更检测:简单按应用规则可用固定到完整 SHA 的 dorny/paths-filter;monorepo 可用图感知的受影响遍历器。每个部署 lane 输出一个布尔值。
- 按 references/environments.md 与 references/secrets.md 连接信任边界:GitHub Environments 保存部署作用域的 secrets/vars,OIDC 在可用时处理云身份,仓库级 secrets 仅用于引导。
- 保持部署步骤对提供商依赖最小。优先使用仓库自有的部署层,如 SST、IaC apply、发布环境提升 API 或小型平台 CLI 包装,且仅在加载环境凭据并校验产物来源后执行。
- 设置并发:verify/e2e 可取消,deploy 不可取消。按(environment, lane)分组,使 staging web 部署不阻塞 production web,但两个 production web 部署串行。
- 部署后添加独立 smoke 任务:访问环境 URL 或健康端点,不携带云/部署凭据,不健康则失败。部署成功但不服务流量即视为失败。
- 端到端验证:PR(仅 verify,不部署)-> 合并 lane 作用域变更 -> 观察 detect -> verify -> e2e -> deploy -> smoke -> 汇总。确认仅受影响的 lane 和目标环境运行。
- 当部署卡住、竞争或发布错误产物时,参考 references/troubleshooting.md。
加固栈
- 运行 actionlint 检查工作流语法与表达式错误。
- 在编写自定义 grep、awk 或 TypeScript 工作流校验器前,先运行 zizmor 检查 GitHub Actions 安全。
- 优先使用扫描器支持的门禁(zizmor、actionlint、gitleaks、TruffleHog、CodeQL、依赖扫描器),除非扫描器无法表达该风险。
- 将 zizmorcore/zizmor-action 固定到完整 SHA,并附同行版本注释。示例:zizmorcore/zizmor-action@5f14fd08f7cf1cb1609c1e344975f152c7ee938d # v0.5.6。
- 对于没有 GitHub Advanced Security 的仓库,设置 advanced-security: false、annotations: true,并至少以 min-severity: medium 加 min-confidence: medium 阻断。
最小锚点示例
deploy-web: needs: [verify-web, e2e-web] if: ${{ needs.verify-web.result == 'success' && needs.e2e-web.result == 'success' }} environment: name: production url: ${{ steps.smoke.outputs.url }} concurrency: group: deploy-production-web cancel-in-progress: false permissions: contents: read id-token: write env: AWS_DEPLOY_ROLE_ARN: ${{ vars.AWS_DEPLOY_ROLE_ARN }} AWS_REGION: ${{ vars.AWS_REGION }} steps: - uses: actions/download-artifact@<full-sha> # v8.x.y with: { name: web-dist, path: apps/web/dist } - run: vp exec -- sst --config infra/web/sst.config.ts deploy --stage production
smoke-web: needs: deploy-web if: ${{ needs.deploy-web.result == 'success' }} runs-on: ubuntu-latest permissions: contents: read steps: - run: ./scripts/assert-no-cloud-credentials - run: ./scripts/smoke-web --environment production
护栏
- 端到端使用同一产物:e2e 与 deploy 都消费 verify 上传的产物。
- 默认分支合并策略属于部署面。若必须允许直接推送到 main,优先使用仅启用 required_conversation_resolution 的分支保护。仅当意图是让默认分支变更走 PR 时,才使用组织或仓库规则集处理对话解决。更改分支策略时保留现有审批、状态检查、签名提交和参与者限制。
- 部署凭据为环境作用域。优先 OIDC 或短期联合;仅当提供商不支持联合路径时使用静态令牌。
- 若仓库已使用 SST 或希望应用自有基础设施,SST 是良好默认。将其作为部署层,置于相同的 Environment、OIDC、产物来源、并发和独立无凭据 smoke 规则之后。
- 对于使用静态 Cloudflare 令牌的 Cloudflare/SST 部署,将令牌放在 GitHub Environment 上,并拆分 staging 与 production 的 stage/项目/状态,使一条部署路径无法删除或变更另一环境的资源。
- 仓库级 secrets 仅用于引导。运行时和生产部署 secrets 位于 GitHub Environments 或提供商的密钥系统。
- 部署并发按(environment, lane)不可取消,并在 main.yml 与 deploy.yml 之间共享。
- 在独立只读 smoke 任务访问已部署环境之前,部署流水线不算通过。
- 携带密钥的手动部署任务在 checkout 或加载凭据前验证输入,然后部署具有已知来源的先前构建产物或不可变镜像。
适用场景与限制
适用于需要标准化 GitHub Actions 部署流程、按 lane 独立构建部署、使用环境门禁与 OIDC、要求部署后 smoke 验证的仓库。限制方面:部署细节需由目标平台或基础设施仓库提供;具体环境名称、凭据、端点等需按仓库实际情况确认;资料未提供具体收费、价格或平台支持范围。