BuildRiot
Sign in

Article · Cloud

Test GitHub Actions lockfiles by moving a nested action’s tag

GitHub’s workflow lockfile preview covers nested action dependencies beyond a top-level commit pin. This guide sets up a controlled moved-tag experiment, separates execution from dependency updates, and explains what to check before enforcing lockfiles.

A warmly lit miniature wooden cabinet shows a red tag moving between nested blue mechanisms connected to separate paper dependency ledgers.
Illustration: BuildRiot (AI-generated)

Key takeaway

Pinning a wrapper action does not necessarily freeze the actions it calls. A controlled test can show whether lockfiles preserve the intended nested commit and whether a team can review and apply updates predictably.

A pinned wrapper leaves a useful test case

GitHub’s workflow dependency lockfile preview, announced October 14, 2026, covers nested actions as well as direct dependencies. A workflow can pin a wrapper action to a full commit hash while the wrapper calls another action through a movable tag. That creates a useful adoption test: keep the wrapper fixed, move the nested action’s tag, and observe which revision executes. Sources: GitHub, GitHub Docs

GitHub stores the dependency graph in.github/workflows/actions.lock, recording resolved commits and numeric owner and repository identities; it checks repository identity at runtime. Every dependency of an onboarded workflow must appear, and locked commits must exist within a source-repository branch. Dependencies inside a reusable workflow follow the defining repository’s lockfile, making shared-workflow repositories a separate adoption task. GitHub’s secure-use guidance recommends lockfiles for repositories adopting them and retains full-length commit pinning guidance for others. Sources: GitHub Docs

Build a nested action with a visible revision marker

Use three disposable repositories under your control: a leaf action, a wrapper action, and a consumer workflow. Commit the following action.yml in the leaf repository as revision A. Create a lightweight major-version tag at that commit, then push the branch and tag. Avoid full semantic-version tags initially: generation can narrow references to more specific versions, changing the condition under test. Sources: GitHub Docs

name: Lockfile leaf probe
description: Emits a recognizable revision marker
runs:
  using: composite
  steps:
    - shell: bash
      run: echo 'LOCKFILE_PROBE=A'

In the wrapper repository, commit the following action.yml and record its full commit hash as P. Substitute your repository owner for the example owner. Keep this wrapper commit unchanged throughout the comparison; only the leaf tag should move.

name: Lockfile wrapper probe
description: Calls a deliberately movable nested dependency
runs:
  using: composite
  steps:
    - uses: LAB/lock-leaf@v1

In the consumer repository, create.github/workflows/probe.yml using the configuration below. Replace the owner and placeholder with the wrapper’s full commit hash. Dispatch the workflow and save its run URL and logs showing revision A. Preserve an unlocked control branch or separate consumer repository, and defer any enforcement policy that would prevent that control from running.

name: Nested dependency probe
on:
  workflow_dispatch:

permissions:
  contents: read

jobs:
  probe:
    runs-on: ubuntu-24.04
    steps:
      - uses: LAB/lock-wrapper@REPLACE_WITH_FULL_WRAPPER_SHA

Lock the baseline, then move only the leaf tag

Install GitHub’s extension and onboard the probe with the commands below; GitHub documents selecting an individual workflow. Review the entire diff because generation may narrow references and migrate local action references. Confirm that both wrapper and leaf appear in the dependency graph, with the leaf locked to A and its major-version reference preserved. Record the tool version, generated schema version, and dependency identities before committing and running the locked baseline. Sources: GitHub Docs

gh extension install github/gh-actions-lock
gh actions-lock .github/workflows/probe.yml
git diff

Next, change only the leaf’s output marker to identify revision B and commit it as a descendant of A on the same branch. In the disposable leaf repository, use the commands below to move the tag and inspect its remote target. Keep A reachable in branch history so the test isolates tag movement from lost commit reachability. Dispatch fresh runs of both consumers without changing their workflow files or the wrapper.

git tag -f v1 HEAD
git push origin HEAD
git push --force origin refs/tags/v1
git ls-remote origin refs/tags/v1

This experiment has not been run; the table below gives expected outcomes to verify, not measured results. GitHub’s extension documentation says branch and partial-version movement does not automatically advance a locked commit. The marker test checks nested-action selection; identical action commits alone do not establish an identical build environment or identical network-fetched inputs. Retain each run’s consumer commit, wrapper hash, leaf tag target, locked leaf hash, runner version and image, run URL, marker, and error text. Sources: GitHub

Table

Expected outcomes for the partial-version tag experiment

TestExpected outcome to verify
Unlocked consumer, wrapper still pinned to PB executes through the nested @v1 reference.
Locked consumer, lockfile unchangedA executes.
Ordinary lock generationLeaf remains locked to A.
Online verification with A still an ancestorVerification accepts the preserved pin.
Explicit relock, reviewed and committedLeaf advances to B; subsequent execution prints B.
These are test hypotheses based on documented pin behavior, with revision A kept reachable in branch history.Sources: GitHub Docs, GitHub

Separate verification from intentional updates

Run each command below in a separate clean copy of the same locked checkout so one operation cannot affect another. Offline verification checks coverage without establishing that the recorded pins are trustworthy. Online verification also checks that preserved branch and partial-version pins remain in the reference’s history. Ordinary generation keeps existing pins, including transitive pins, while explicit relocking re-resolves legitimately moved references. Sources: GitHub

gh actions-lock --verify-local
gh actions-lock --verify
gh actions-lock
gh actions-lock --relock

Save exit codes and diffs for every operation, including successful ones. Inspect whether relocking advances the leaf to B while retaining wrapper P, and whether it changes references or other metadata. Review and commit the update before dispatching the final consumer run. The extension documents all-or-nothing generation writes when an unfixable error occurs, so preserve the working-tree state after failures too. Sources: GitHub

Then repeat the fixture with a full-version leaf tag. The extension documentation says a full-version tag must still point to its locked commit and that failed checks block the run. Its normal pin checks mirror runner checks at job start, making the location and wording of the failure useful evidence. Test lost reachability separately: accepting a moved reference whose old commit is no longer reachable upstream requires an additional explicit option. Sources: GitHub

  1. Retag the full-version fixture after locking; record whether execution stops before the marker step and capture the command-line finding.
  2. Add a dependency to an onboarded workflow without regenerating its lockfile; capture whether coverage checks reject it.
  3. Regenerate from the workflow inputs, review the diff, and rerun to check that coverage is restored.

Make update ownership part of adoption

Follow a successful marker test with an update exercise before broad enforcement. Dependabot regenerates matching lockfile entries for version updates to onboarded workflows, but does not onboard uncovered workflows. Test transitive floating-tag movement separately rather than assuming it triggers an automatic update pull request. Renovate documents experimental support that regenerates existing lockfiles after action updates, skips uncovered workflows, and suppresses narrowing and local-action migration. Those choices can produce different diffs from a default manual invocation. Sources: GitHub, GitHub Docs, Renovate Docs

GitHub recommends piloting enforcement with selected repositories and workflows; Evaluate mode is Enterprise-only. Its enforcement guide recommends pull-request verification and code-owner review of the lockfile backed by required approvals. Check allowlists during the pilot because onboarding switches matching to locked commit hashes, potentially breaking tag-specific entries. Assign an owner to shared-workflow repositories as well as consumers, since their internal dependencies follow their own lockfiles. Sources: GitHub Docs

GitHub cautions that locking does not establish dependency safety; source review and least-privilege tokens remain relevant. Make the pilot’s final exercise a necessary dependency update: identify the revision, review the relock, merge it, and confirm execution. Measure how long that process takes and who can complete it. Use the result to assign update responsibility before expanding enforcement. Sources: GitHub, GitHub Docs

Attribution

Sources

  1. 1GitHubGitHub Actions workflow lockfiles in public previewSource published (UTC)
  2. 2GitHub DocsWorkflow dependency lockfiles
  3. 3GitHubgithub/gh-actions-lock
  4. 4GitHub DocsLocking action dependencies in a repository's workflows
  5. 5GitHub DocsSecure use reference
  6. 6GitHub DocsEnforcing lockfiles for action dependencies
  7. 7Renovate DocsAutomated Dependency Updates for GitHub Actions

Read the original source for full details and context.

Report a problem

Links, dates or what you expected. Do not include passwords or private data.

More on Cloud

All Cloud stories

Cloud

Google Cloud makes spend-cap budgets generally available for four services

Google Cloud made spend-cap budgets generally available on October 13, 2026, according to its release notes. Customers can pause new usage when gross estimated spending, excluding savings and credits, exceeds a configured amount. Supported services are Gemini API, Gemini Enterprise Agent Platform (formerly Vertex AI), Cloud Run and Cloud Run functions. Each cap covers one project and one eligible service for a calendar month; customers can manage caps through the console or Cloud Billing Budget API. Enforcement is delayed, and customers still pay overages. In-flight requests can finish, while persistent compute and storage resources remain billable.

Google Cloud

AI

Oracle adds managed MCP server support for OCI Database Services

Oracle added managed MCP server support for OCI Database Services on October 13, 2026, according to its release notes. The interface lets MCP-compatible AI agents and applications inspect database resources through read-only operations; it cannot modify those resources. It supports four services: Base Database Service, Exadata Database Service on Cloud@Customer, Exadata Database Service on Dedicated Infrastructure and Exadata Database Service on Exascale Infrastructure. Clients connect through generated endpoints using Streamable HTTP, while OCI IAM authenticates clients and enforces existing access policies. Customers can choose which resource categories to expose and enable or disable servers.

Oracle