为什么锁定工作流依赖项?
工作流通常通过标记或分支(例如 uses: octo-org/deploy-action@v3 或 uses: octo-org/deploy-action@main)引用操作。
GitHub Actions 将该引用解析为该标签或分支在运行时指向的提交。
标记和分支可以移动。 因此,无法保证运行的代码是工作流作者最初审阅的代码。 如果上游维护者的帐户遭到入侵并且标签被重新指向,则存储库可能会运行恶意代码。
工作流依赖项锁定文件将提交 SHA 固定到工作流所依赖的每个操作,包括可传递依赖项。 它不会将调用锁定到可重用工作流(jobs.<job_id>.uses)。 若要固定可重用的工作流,请通过完整提交 SHA 来引用它。 锁文件控制在运行器上运行的操作代码。 它不控制其他构建输入,例如输入参数、机密或运行器映像。 锁文件可为其涵盖的操作代码提供以下内容:
- 操作依赖项的可重现解决
- 可查看的依赖项更改和 Dependabot 版本更新
- CI/CD 系统操作依赖项的可审核清单
lockfile 的工作原理是什么?
lockfile 在位于 .github/workflows/actions.lock 的存储库中定义。 它由 gh actions-lock 生成,这是一个 GitHub CLI 扩展,且绝不应手动编辑。
可以将存储库的工作流逐个或一次性载入锁文件。 载入工作流后:
- 工作流使用的每个操作依赖项都必须存在于 lockfile 中。
- 锁定的提交是工作流执行时运行的提交,也是允许的操作策略检查的对象。
- 在操作自身的存储库中,此提交必须可从锁定文件中为其记录的分支或标记到达。 工作流运行时,仅存在于分叉中或无法从该分支或标记访问的提交将被拒绝。
锁文件涵盖其自身仓库中的工作流,包括传递依赖项(_你的操作依赖项_所使用的操作),但不包括可重用工作流调用的依赖项。 可重用工作流也可以有自己的锁文件。 可重用工作流的依赖项由定义该工作流的存储库的锁文件(而不是调用它的存储库的锁文件)涵盖。
锁定文件记录了什么?
lockfile 有两个部分。
workflows 记录每个已接入的工作流使用的依赖项,以及 dependencies 记录这些引用中的每一个解析到哪个提交。
# This file is machine-generated by `gh actions-lock`.
# Do not edit by hand; run `gh actions-lock` to update.
# Docs: https://gh.io/actions-lockfile
version: 'v0.0.3'
workflows:
'.github/workflows/ci.yml':
- 'octo-org/deploy-action@v3.1.0'
dependencies:
'octo-org/deploy-action@v3.1.0':
ref: 'v3.1.0'
commit: 'sha1-...'
owner_id: 44036562
repo_id: 197814629
每个依赖项记录:
ref:提交解析自的标记或分支。commit:该引用解析到的确切提交。 这是将运行的代码。owner_id和repo_id:源存储库的数字标识。 GitHub Actions 在运行时使用它们来确认该名称对应的存储库仍然是你锁定的存储库。
这种结构化格式为诸如 Dependabot 之类的工具提供机器可读的记录,可用于管理依赖项更新,而无需依赖 YAML 注释作为版本注释。
锁文件与 SHA 固定相比如何?
GitHub 历来建议将第三方操作固定到工作流文件中的完整提交 SHA。 对于采用锁定文件的存储库,不再需要在工作流文件中固定 SHA。 锁文件是更好的选择,因为它:
- 支持可传递依赖项
- 使工作流文件更易于阅读
- 记录源存储库的标识
锁文件还满足针对已采用该策略的工作流的单独 要求操作固定到完整长度提交 SHA 策略。 请参阅“管理GitHub Actions工作流的执行”。
后续步骤
若要为存储库创建锁文件,请参阅 锁定存储库工作流中的 GitHub Actions 依赖项。