GitHub Actionsのworkflow lockfileがGA。更新漏れとオンボードし忘れを、CI・Dependabot・ポリシーでどう止めるか試す

GitHub Actionsのworkflow lockfileがGA。更新漏れとオンボードし忘れを、CI・Dependabot・ポリシーでどう止めるか試す

GitHub Actionsのworkflow lockfileがGAになりました。更新漏れとオンボードし忘れを、CIの--verify、Dependabot、Require lockfileでどこで止められるかを試し、Freeプランでの代わりの手段まで整理します。
2026.11.03

どうも!オペ部の西村祐二です!

GitHub Actionsのworkflow lockfileが、2026年10月28日にGAになりました。ワークフローが参照するアクションと、その中で呼ばれるアクションのコミットを.github/workflows/actions.lockに記録し、実行時はそのコミットで取得する仕組みです。GAの告知では、lockfileの生成に加えて次の3つが紹介されています。CIでの古いlockfileの検出、Dependabotによる更新、lockfileを必須にするRequire lockfileポリシーです。

lockfileを作るだけなら、gh actions-lockを1回実行すれば済みます。ワークフローをlockfileに登録することを、ドキュメントでは「オンボード」と呼んでいます。ただ、運用に乗せるには、lockfileの更新漏れをどこで見つけるか、オンボードし忘れたワークフローをどう止めるかを決める必要があります。しかもRequire lockfileは、プランとリポジトリの公開設定によっては強制されません。この記事では、CI、Dependabot、Require lockfileを組み合わせて動かし、強制されない環境でのSHAピン留めの強制との使い分けまで整理します。

確認したのは2026年11月2日です。環境は次のとおりです。

  • Freeプランのアカウントに作ったリポジトリ(プライベートで作り、Require lockfileを試すためにパブリックへ変更)
  • GitHubホストのubuntu-latestランナー
  • 手元のgh 2.103.2とgh actions-lock v0.4.0(gh extension install github/gh-actions-lockで導入)

次の条件は試していません。

  • Organizationでのポリシー設定と、プライベートリポジトリでの強制。強制される範囲は、画面の案内とドキュメントの記述からの判断です
  • Require lockfileの対象を一部のワークフローに絞る設定と、違反を記録するだけのEvaluateモード。段階的に導入する手順は、この記事からは分かりません
  • 別のリポジトリにある再利用ワークフロー
  • verifyのチェックをブランチ保護やrulesetで必須にしたときの、マージの止まり方
  • Dependabotのセキュリティアップデートやグループ化

lockfileそのものの仕組みは、パブリックプレビューのときに以前の記事で試しています。

先に結論:おすすめの構成

今回の結果から、次の組み合わせが良さそうです。

仕組み 役割 設定と注意
lockfile(gh actions-lock) アクションと、その中の依存をコミットで固定する 最新のgh actions-lockでオンボードする。新しいワークフローは自分でオンボードする
CIでの--verify lockfileとワークフローのずれや、オンボードし忘れを、PRのチェックとして表示する 公式サンプルの--pin v0.2.0を、確認時点の最新の--pin v0.4.0に上げる
Dependabot バージョン更新のPRで、lockfileも一緒に更新する github-actionsを設定するだけ
Require lockfileポリシー オンボードしていないワークフローを、起動前にすべて止める 「All workflows」なら、アクションを使わないワークフローもオンボードが要る
SHAピン留めの強制 オンボードしていないワークフローの、フルSHAでない参照(タグやブランチ)を止める オンボード済みのワークフローは、タグ参照のままでも通る

Require lockfileが強制されるのは、パブリックリポジトリと、GitHub TeamかGitHub Enterpriseのプライベートリポジトリです(ドキュメントの記述と画面の案内による)。強制されるかどうかで、オンボードし忘れの止め方を変えます。

  • パブリックリポジトリ、Team以上のプライベートリポジトリ: lockfile、CIの--verify、Dependabotに、Require lockfileを組み合わせる
  • Freeのプライベートリポジトリ: Require lockfileの代わりに、SHAピン留めの強制を有効にする。フルSHAで書いたワークフローはオンボードしていなくても動くので、CIの--verifyで拾う

落とし穴は2つありました。1つは、lockfileの更新を忘れたPRで、オンボード済みのワークフローが起動に失敗しても、PRのチェック一覧には出てこないことです。もう1つは、公式サンプルのCIがgh actions-lock v0.2.0に固定されていて、v0.2.0の--verifyは、実行時に失敗するlockfileを通してしまうことがあることです。どちらも、最新のgh actions-lockでCIの--verifyを回すと拾えました。

次の図は自作した概念図で、公式の構成図ではありません。左が変更の入口、中央がPRのチェック、右が実行時の結果です。

自作した、lockfileの運用でチェックがかかる場所の概念図。左に、gh actions-lockでワークフローとlockfileを一緒に変更する場合、Dependabotの更新PR、lockfileの更新し忘れの3つの入口がある。中央のverify-lockfile(CI)は、gh actions-lock --verifyでずれをPRのチェックとして表示する。v0.2.0固定だと、composite actionの中の参照が抜けたlockfileを通してしまう。右の実行時は3つに分かれる。lockfileと一致すれば、lockfileのコミットで取得し、タグのままでもSHA強制を満たす。lockfileが古ければstartup_failureになり、PRのチェック一覧には出ない。オンボードしていなければ、Require lockfileが強制されている場合はstartup_failure、SHA強制だけならタグ参照がSet up jobで失敗する。下に、Require lockfileが強制されるのはパブリックリポジトリと、GitHub Team・Enterpriseのプライベートリポジトリで、Freeのプライベートリポジトリでは強制されないため、SHAピン留めの強制で代わりに使うと書かれている

検証用のリポジトリにCI・verify・Dependabotを置く

検証用のリポジトリには、次の3つを置きました。CI用のci.yml、gh actions-lockの公式サンプルのverify-lockfile.yml、Dependabotの設定です。

.github/workflows/ci.yml
name: ci
on:
  push:
    branches: [main]
  pull_request:
jobs:
  build:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v6
      - run: echo "build"
.github/dependabot.yml
version: 2
updates:
  - package-ecosystem: github-actions
    directory: /
    schedule:
      interval: daily

公式サンプルは、v0.4.0のタグのものをそのまま使いました。

.github/workflows/verify-lockfile.yml
# Fails when .github/workflows/actions.lock is out of sync with the
# workflows or a locked pin no longer verifies upstream.

name: verify-lockfile

on:
  pull_request:
  push:
    branches:
      - main

permissions:
  contents: read

jobs:
  verify:
    runs-on: ubuntu-latest
    env:
      GH_TOKEN: ${{ github.token }}
    steps:
      - uses: actions/checkout@v7.0.1
        with:
          persist-credentials: false
      - run: gh extension install github/gh-actions-lock --pin v0.2.0
      - run: gh actions-lock --verify

手元で引数を付けずにgh actions-lockを実行すると、2本ともオンボードされました。今回は、ci.ymlの@v6が完全なバージョンのタグ@v6.1.0に書き換わりました。

gh actions-lock
Scanning 2 workflows
Planning pins
Pinned 2 actions across 2 workflows
  actions/checkout@v6.1.0 (d23441a)
    └─ .github/workflows/ci.yml
  actions/checkout@v7.0.1 (3d3c42e)
    └─ .github/workflows/verify-lockfile.yml

ワークフローとlockfileをpushすると、ciとverify-lockfileの両方が成功しました。

lockfileが古いPRで、チェックに出るのはverifyの失敗だけ

ci.ymlにactions/cache@v4のステップを足し、lockfileを更新しないままPRを出しました。このときは、リポジトリをパブリックに変えた後で、Require lockfileもSHAピン留めの強制もまだ有効にしていません。

gh pr checksで見ると、PRのチェックに出たのはverify-lockfileの失敗だけでした。gh pr view --json statusCheckRollupでも、verifyの1件だけです。PRの画面では確認していません。

gh pr checks 2
verify	fail	6s	https://github.com/ynishimura/blog-verify-lockfile-ops/actions/runs/41453374622/job/125303855861

verify-lockfileのログでは、lockfileに記録されていないアクションが指摘されています。

1 of 2 workflows failed
✗ Not pinned actions/cache@v4
  used in workflow but not pinned in lockfile (actions/cache@v4)

一方、変更したci.ymlそのものの実行はstartup_failureでした。ジョブは1つも作られておらず、PRのチェックにも出ていません。ただし、Actionsの実行一覧には残っています。

gh run list --branch add-cache-without-lock --json workflowName,event,conclusion --jq '.[]|[.workflowName,.event,.conclusion]|@tsv'
ci	pull_request	startup_failure
verify-lockfile	pull_request	failure

以前の記事でも、プライベートリポジトリのまま、lockfileを更新せずにpushした実行がstartup_failureになっていました。lockfileが古いことによる起動失敗は、ポリシーや公開設定に関係なく起きます。今回、lockfileの更新漏れがPRのチェックとして出たのは、verify-lockfileだけでした。マージを止めるには、verifyのチェックをブランチ保護やrulesetで必須にする必要がありそうですが、今回は試していません。

公式サンプルのCIは--pinを上げて使う

公式サンプルは--pin v0.2.0で、gh actions-lockのバージョンを固定しています。2026年11月2日時点の最新はv0.4.0です。v0.3.0で--verifyの判定が変わり、リリースノートには「Some lockfiles that passed --verify on v0.2.0 now fail it」と書かれています。

SHAピン留めの強制を試したときに、v0.2.0で作ったlockfileを使うワークフローが、実行時にlockfile missing pin for actions/checkout@v7というエラーで失敗しました。このワークフローは、内部でactions/checkout@v7を使うcomposite actionを参照していました。v0.2.0は、composite actionの中のactions/checkout@v7をactions/checkout@v7.0.1として記録したため、実行時に@v7のエントリが見つからなかったと読めます。

このlockfileに対して、v0.2.0とv0.4.0の--verifyを実行して比べました。v0.2.0は、gh拡張の保存先(XDG_DATA_HOME)を一時ディレクトリに向けて入れ、手元のv0.4.0とは分けています。

gh actions-lock --verify .github/workflows/t13-locked.yml

v0.2.0では、問題なしと判定されました。

Scanning 1 workflow
All 1 workflow valid

v0.4.0では、composite actionの中の参照がlockfileに記録されていないことが検出されました(出力の抜粋)。

Scanning 1 workflow
1 of 1 workflow failed
✗ Lockfile doesn't match locked manifest actions/checkout@v7
  ynishimura/blog-verify-sha-pinning/.github/actions/composite-tag@v1 at locked commit b49117c7d739 uses actions/checkout@v7, but its lockfile entry ynishimura/blog-verify-sha-pinning@v1 does not record it
  ! restore the edge from version control, or run `gh actions-lock --relock`
  see: https://github.com/github/gh-actions-lock/blob/main/docs/troubleshooting.md#incomplete-lockfile

サンプルを--pin v0.2.0のまま使うと、composite actionの中の参照が抜けたlockfileを、CIが通してしまうことがあります。今回は--pin v0.4.0に変えて動かし、このあと有効にするRequire lockfileとSHAピン留めの強制が両方オンの状態でも、verify-lockfileが成功することを確かめました。

.github/workflows/verify-lockfile.yml(変更箇所)
      - run: gh extension install github/gh-actions-lock --pin v0.4.0

v0.2.0のころに作ったlockfileは、--pinを上げると--verifyでincomplete-lockfileになることがあります。その場合は、gh actions-lock --relockで作り直します(SHAピン留めの強制を試した記事で確認)。バージョンを固定しておけば、gh actions-lockの更新で判定の内容が急に変わることはありません。その代わり、gh actions-lockのリリースに合わせて--pinの値を上げていく運用になります。

Dependabotはlockfileも同じPRで更新する

dependabot.ymlを置いてpushすると、Dependabotがすぐにactions/checkoutを6.1.0から7.0.1に上げるPR(#1)を開きました。変わったファイルはci.ymlとactions.lockの2つです。lockfileでは、ci.ymlのエントリがactions/checkout@v7.0.1に変わり、使われなくなったactions/checkout@v6.1.0のエントリが削除されていました。v7.0.1のエントリは、verify-lockfile.yml用にもともとありました。

.github/workflows/actions.lock(PR #1の差分の抜粋)
 workflows:
     '.github/workflows/ci.yml':
-        - 'actions/checkout@v6.1.0'
+        - 'actions/checkout@v7.0.1'
     '.github/workflows/verify-lockfile.yml':
         - 'actions/checkout@v7.0.1'
 dependencies:
-    'actions/checkout@v6.1.0':
-        ref: 'v6.1.0'
-        commit: 'sha1-d23441a48e516b6c34aea4fa41551a30e30af803'
-        owner_id: 44036562
-        repo_id: 197814629

PR上のbuildとverifyは成功しました。ポリシーを有効にした状態での結果は、後の節で書きます。

ただし、Locking action dependencies in a repository's workflowsには「Dependabot only updates lockfile entries for workflows that are already onboarded.」とあります。Dependabotは、新しいワークフローのオンボードまではしてくれません。

Require lockfileで何が止まるか

Freeのプライベートリポジトリでは強制されない

Require lockfileは、「Settings」→「Actions」→「Policies」で作るポリシーです。プライベートリポジトリのままこの画面を開くと、次の案内が出ていました。赤枠は追記です。

FreeプランのプライベートリポジトリのActions policies画面。「Your rulesets won't be enforced on this private repository until you move to GitHub Team organization account.」という警告が赤枠で囲まれている

Governing execution of GitHub Actions workflowsの「Who can use this feature?」の欄にも、「All public repositories, and private repositories on GitHub Team or GitHub Enterprise.」とあります。プライベートのままポリシーを作って実行することは試していません。今回は、検証用のリポジトリをパブリックに変えてから進めました。パブリックにすると、この案内は消えました。

ポリシーを作る

「New policy」から、名前を付けて「Require lockfile」にチェックを入れ、Enforcement statusを「Active」にしました。Target workflowsは「All workflows」のままです。赤枠は追記です。

新しいActionsポリシーの作成画面。Enforcement statusの「Active」と、Workflow execution protectionsの「Require lockfile」(Previewラベル付き)のチェックボックスが赤枠で囲まれている

Enforcement statusの選択肢はActiveとDisabledの2つでした。Evaluateは、ドキュメントではGitHub Enterprise Cloudでのみ使えるとされています。また、2026年11月2日時点の画面では、GAの告知後もRequire lockfileに「Preview」のラベルが付いていました。

オンボードしていないワークフローは、アクションの有無やSHA固定に関係なく止まる

ポリシーを有効にした状態で、オンボードしていないワークフローを2本足しました。1本はactions/checkout@v7.0.1を使うもの、もう1本はrunステップだけでアクションを使わないものです。どちらもstartup_failureになりました。オンボード済みのci.ymlは成功しています。赤枠は追記です。

オンボードしていないnew-run-onlyワークフローの実行画面。StatusがStartup failureで、Annotationsに「Workflow is not in the repository's lockfile. Run  in the repository and commit the result.」から始まるエラーが表示され、どちらも赤枠で囲まれている

注釈の全文は次のとおりです。

Workflow is not in the repository's lockfile. Run `gh actions-lock` in the repository and commit the result. If this is a reusable workflow, the maintainer of the reusable workflow needs to run `gh actions-lock` in its repository and commit the result. Workflow file: '.github/workflows/new-run-only.yml'.

ドキュメントにも、Require lockfileは「including workflows with no uses: dependencies」と、アクションを使わないワークフローも止めると書かれています。同じpushで動いたverify-lockfileも、✗ Not pinned .github/workflows/new-run-only.yml / workflow has no lockfile entryと、オンボードし忘れを指摘していました。

続けて、SHAピン留めの強制も有効にしました(「Settings」→「Actions」→「General」の「Require actions to be pinned to a full-length commit SHA」)。この状態で、actions/checkoutをフルSHAで固定したrelease.ymlを、オンボードせずに足しました。これもstartup_failureでした。フルSHAで固定していても、オンボードしていなければRequire lockfileで止まります。

「All workflows」を対象にするなら、リポジトリのワークフローをすべてオンボードしておく必要があります。

新しいワークフローは自分でオンボードする

止まったrelease.ymlを通すため、このワークフローだけをオンボードしました。

gh actions-lock .github/workflows/release.yml

このとき、タグをコメントで添えていたフルSHAの参照は、そのタグの表記に書き換わりました。

.github/workflows/release.yml
-      - uses: actions/checkout@3d3c42e5aac5ba805825da76410c181273ba90b1 # v7.0.1
+      - uses: actions/checkout@v7.0.1

ワークフローとlockfileを同じコミットでpushすると、release.ymlも成功しました。ワークフローを足すときは、gh actions-lock <ワークフロー>を実行し、ワークフローとlockfileを同じコミットに入れる流れになります。フルSHAで固定していた参照はタグの表記になるので、SHAで書かれていることを前提にした仕組み(たとえばSHAかどうかを調べるCIのチェック)があれば、見直す必要があります。

SHAピン留めの強制とどう組み合わせるか

ドキュメントでは、Require lockfileはSHAピン留めの強制とは別のポリシーで、移行中は両方を有効にしてよいとされています。今回も、両方を有効にした状態で次の3つが成功しました。

  • オンボード済みでタグ参照のci.ymlとverify-lockfile.yml
  • Dependabotの更新ジョブ(Dependabot Updates)
  • ci.ymlにactions/setup-node@v4を足してオンボードした後に、Dependabotが開いたactions/setup-nodeを4.4.0から7.1.0に上げるPR(lockfile込み)と、そのPRのチェック

ポリシーの作成画面にも、Dependabotなどの機能はこの保護の対象外と書かれていました。

2つのポリシーは、止める対象が違います。

ポリシー 止めるもの Freeのプライベートリポジトリ
Require lockfile オンボードしていないワークフロー(アクションの有無やSHA固定に関係なく) 強制されない
SHAピン留めの強制 オンボードしていないワークフローの、フルSHAでない参照(Set up jobで失敗) 強制される(SHAピン留めの強制を試した記事で確認)

Require lockfileが強制される環境なら、こちらのほうが範囲が広く、オンボードし忘れたワークフローをまとめて止められます。Freeのプライベートリポジトリでは、SHAピン留めの強制で、オンボードし忘れたワークフローのタグ参照を止めます。フルSHAで書いたワークフローや、アクションを使わないワークフローは動いてしまうので、CIの--verifyで拾います。

まとめ

GAになったworkflow lockfileは、gh actions-lockでオンボードし、CIの--verifyとDependabotを組み合わせると、ワークフローと同じPRで管理できました。lockfileの更新を忘れたPRでは、オンボード済みのワークフローはstartup_failureになるだけで、PRのチェックには出ません。--verifyを入れておかないと、PRのチェックだけでは更新漏れに気付けないので、公式サンプルを使う場合は--pinを最新に上げておきたいところです。新しいワークフローはDependabotがオンボードしないので、自分でgh actions-lock <ワークフロー>を実行します。

オンボードし忘れを止める手段は、プランとリポジトリの公開設定で使い分けます。パブリックリポジトリやTeamプラン以上のプライベートリポジトリではRequire lockfileを、Freeのプライベートリポジトリでは代わりにSHAピン留めの強制を使おうと思います。

誰かの参考になれば幸いです。


参考リンク:

この記事をシェアする

関連記事