Skip to main content
Skip to content

锁定存储库工作流中的 GitHub Actions 依赖项

生成一个锁文件,用于将工作流使用的每个操作固定到已验证的提交,并在依赖项更改时保持最新状态。

谁可以使用此功能?

People with write access to a repository

GitHub Enterprise Cloud

锁定工作流的依赖项可确保引用的操作包含最初审阅的相同代码。 有关详细信息,请参阅“工作流依赖项锁定文件”。

1. 检查操作参考

创建锁文件会根据当前分支或标记引用将依赖项固定到提交。 请确保这些是您要固定的版本。

检查工作流中的每个uses引用是否指向受支持的当前版本的操作。 有关最佳做法,请参阅 安全使用指南。

如果任何工作流调用另一个存储库中的可重用工作流,也请检查这些引用。 可重用工作流的依赖项由定义该工作流的存储库中的锁文件涵盖,而不是由你的锁文件涵盖。 该源存储库需要其自己的锁文件来全面覆盖。 如果组织维护共享工作流,请先载入这些仓库。 请参阅“重用工作流配置”。

建议允许 Dependabot 管理 GitHub Actions 依赖项。 如果尚未启用,请在创建 lockfile 之前启用它。 请参阅“使用 Dependabot 保持操作的最新状态”。

2.安装 actions-lock 扩展

  1. 安装GitHub CLI。

  2. 安装扩展。

    Bash
    gh extension install github/gh-actions-lock
    

提示

若要稍后更新扩展,请运行 gh extension upgrade gh-actions-lock。

3. 生成锁文件

从存储库的根目录中,不带任何参数运行该扩展。 它将扫描 .github/workflows/ 下的每个工作流,将每个可解析操作固定到提交 SHA,并写入 lockfile。

Bash
gh actions-lock

若要导入单个工作流而不是整个目录,请指定其路径。

Bash
gh actions-lock .github/workflows/ci.yml

该扩展永远不会跟随或锁定本地路径操作(uses: ./…)。 ./ 路径会运行 runner 工作区中签出的任何内容,因此扩展无法锁定其版本,也无法查看它使用的内容。 $/路径在工作流引用的提交处运行存储库自己的操作,因此被固定到该提交,并且其使用的操作也可以被锁定。 有关两者比较,请参阅 GitHub Actions 的工作流语法。

如果检出中的本地操作使用其他操作,则扩展会报告 local-action 错误,并且不会写入任何内容,因为缺少锁文件条目,这些操作会在运行时失败。 若要将本地操作锁定为同仓库引用,请运行:

Bash
gh actions-lock --migrate-local-actions

若要保留 ./ 引用并将其报告为警告,请传递 --ignore-local-actions。 请参阅 保持本地路径操作。

对于完整的选项集,请运行 gh actions-lock --help。 有关特定错误或警告的帮助,请参阅 gh-actions-lock 故障排除指南。

保持本地路径操作

如果传入 --ignore-local-actions,运行时发生的情况取决于本地操作使用的操作:

  • 它不使用其他操作,例如,仅包含 run: 步骤:工作流正常运行。
  • 它使用对同一工作流具有锁记录的操作:工作流正常运行。
  • 它使用了一个在该工作流中没有锁文件条目的操作:作业在到达本地操作的步骤时失败,并出现错误,例如 lockfile missing pin for octo-org/setup-tool@v2.0.0。 前面的步骤已执行。

我们建议改用 --migrate-local-actions,因此该操作会以固定的 $/ 引用形式运行。 如果需要保留 ./ 引用,请为本地操作使用的操作提供工作流锁定文件条目。 添加一个使用相同操作和相同引用的复合操作,并在工作流中一个永远不会运行的步骤里调用它。 然后运行 gh actions-lock --ignore-local-actions。

# .github/actions/lock-local-deps/action.yml
name: Lock local action dependencies
description: Never runs. Lists the actions that ./.github/actions/build uses.
runs:
  using: composite
  steps:
    - uses: octo-org/setup-tool@v2.0.0
# In the workflow
steps:
  - uses: actions/checkout@v6
  - if: false
    uses: $/.github/actions/lock-local-deps
  - uses: ./.github/actions/build

必须记录同一工作流的条目。 仅为其他工作流记录的条目不计数。 当本地操作的依赖项发生更改时,请更新复合操作并再次运行 gh actions-lock --ignore-local-actions 。

4.查看更改并提交

该扩展所做的更改不止锁定文件,因此请在提交之前查看完整的差异。 它还将你的工作流中对 uses 的引用改写为其解析到的特定版本,因此,此类 octo-org/deploy-action@v3 引用可能会变为 octo-org/deploy-action@v3.1.0。 这使得引用更具体,而不改变其解析到的提交。

重要

如果存储库、组织或企业仅允许指定操作,请在提交前检查允许列表。 工作流完成引入后,将针对锁定的提交 SHA 而不是标记检查允许列表,因为标记可以移动到不同的代码,但锁定的 SHA 无法。 固定到标签的条目,例如 actions/checkout@v6,在接入工作流后不再匹配。 请改用通配符或完整的提交 SHA。 请参阅“管理存储库的GitHub Actions设置”。

如果你传递了 --migrate-local-actions,该扩展还会在你的工作流和你的仓库中的 action.yml 文件中,将对你自己的仓库中操作的引用从 uses: ./… 重写为 uses: $/…。 它仅在传递选项时执行此操作,因为两种形式的行为方式不同。 ./路径针对运行程序工作区中的任意内容解析,而$/…引用始终在工作流自己的提交处运行,因此无需锁定文件条目。 查看重写后的每一行。

5. 使锁文件保持最新状态

使锁定文件与存储库的工作流文件和安全更新保持同步。

  1. 更改依赖项时重新运行扩展。 每当添加具有uses依赖项的工作流,或在现有工作流中添加或删除gh actions-lock依赖项时,请再次运行uses。

  2. 让 Dependabot 处理版本升级。 当 Dependabot 为你已接入的工作流中的某个操作打开版本更新时,它还会在同一拉取请求中重新生成匹配的锁文件条目。 工作流文件和锁文件不能不同步。

Dependabot 仅更新已接入的工作流的锁文件条目。 如果它升级了某个未包含在锁文件中的工作流 action,它会像往常一样更新工作流文件,并保持锁文件不变。

  1. 重新解析已移动的引用。 扩展如何处理移动的引用取决于该引用:

    • 分支或部分版本(例如 main 或 v3)保留其锁定的提交,扩展报告 ref-moved 警告。 若要推进,请检查上游历史记录,然后运行 gh actions-lock --relock。
    • 完整版本标记(例如 v3.1.0)必须指向其锁定的提交。 如果标记已移动,扩展会报告错误,直到运行 gh actions-lock --relock 或更改 uses: 这一行。
    • 重写的历史记录(其中锁定的提交不再位于引用的历史记录中,例如在强制推送之后)是一个 --relock 无法修复的错误。 查看上游历史记录后,运行 gh actions-lock --accept-moved。 不要 --accept-moved 在自动化中使用。

查看锁文件更改

查看锁文件更改,就像任何其他依赖项更改一样:

  • 已更改的内容 commit 是工作流将运行的代码。 按照对待任何其他依赖项版本的方式处理它。
  • 已更改的owner_id或repo_id 应很少见。 这意味着该名称对应的存储库 不是 你最初锁定的那个存储库,因此请在合并之前进行调查。

如果锁定文件看起来不正确,请修复工作流文件并重新生成它。 切勿手动编辑锁文件。

后续步骤

为存储库生成锁文件后,请确保它被强制执行并保持最新状态,而无需开发人员记住运行命令。 请参阅“为操作项依赖项强制实施锁文件”。