gh-actions-lock

module
v0.0.12 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jun 15, 2026 License: MIT

README

gh-actions-lock

Manage your workflow dependencies.

Install

gh extension install github/gh-actions-lock

Usage

Scan every workflow under .github/workflows/ and pin what it can -- pinning each resolvable action to an immutable SHA and updating the lockfile:

gh actions-lock

Scope the scan to a single workflow (same default behavior, one file):

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

By default, already-pinned workflows are trusted from the lockfile -- their reachability isn't re-checked against upstream. To force a full re-verification of every recorded pin (bypassing that fast path):

gh actions-lock --rescan

Read-only check for CI (reports findings, writes nothing):

gh actions-lock --no-fix --json=valid,findings

--no-fix controls whether fixes are applied; --json only selects the output format. Structured results go to stdout, progress to stderr.

How it works

GitHub Actions is a package manager that forgot to ship a lockfile. Your workflows are the manifest -- every uses: line is a dependency, resolved by mutable tag or branch at runtime, on GitHub's servers, with no record of what actually ran. gh-actions-lock supplies the missing half: .github/workflows/actions.lock, the Actions analogue of go.sum or package-lock.json. Each run resolves every direct and transitive dependency to an immutable commit SHA, locks it, and verifies the lock hasn't been tampered with before any of it runs.

A single gh actions-lock invocation walks two paths. The verify path is read-only and always runs: it scans every workflow, resolves each dependency to a commit SHA, and checks the result against the lockfile. The fix path applies pins — rewriting uses: lines and updating the lockfile — for the issues it can safely repair. The phase labels below are exactly what scrolls past in the spinner.

flowchart TD
    Start([gh actions-lock]) --> Scan

    subgraph verify["VERIFY · read-only diagnosis"]
        direction TB
        Scan["🔍 Scanning N workflows<br/><i>discover .github/workflows, parse uses:</i>"]
        Resolve["📦 Resolving actions<br/><i>tags / branches → commit SHAs, recurse transitives</i>"]
        Reach["🛡️ Verifying reachability<br/><i>is the pinned SHA actually in the ref's history?</i>"]
        Analyze["⚖️ Analyzing<br/><i>lockfile vs. live → findings</i>"]
        Scan --> Resolve --> Reach --> Analyze
    end

    Analyze --> Q{"fixable<br/>issues?"}
    Q -- no --> Report["✅ Report findings"]

    subgraph fix["FIX · write path"]
        direction TB
        Plan["🧮 Planning pins<br/><i>narrow tags, reverse-lookup SHAs</i>"]
        Rewrite["✍️ Rewriting workflows<br/><i>uses: line → @&lt;sha&gt; # &lt;ref&gt;</i>"]
        Lock["🔒 Updating lockfile<br/><i>.github/workflows/actions.lock</i>"]
        Plan --> Rewrite --> Lock
    end

    Q -- yes --> Plan
    Lock --> Report

The security guarantee lives in Verifying reachability: a SHA pin is only trustworthy if that commit is reachable from the tag/branch it claims to come from. A SHA that resolves but isn't in the ref's history is an impostor commit -- the fork-network attack gh-actions-lock exists to catch -- and it's flagged rather than silently trusted.

Development

make build              # build
make test               # Go unit tests
make test-integration   # all integration scenarios (stub + live)
make test-stub          # stub scenarios only (no network, fast)
make test-live          # live repo scenarios only (clones real repos)
make test-shell         # interactive REPL (type help inside for commands)
Scenario catalog

All scenarios are defined in test/scenarios/catalog.yml and consumed by both the Go test suite (test/scenarios/catalog_test.go) and the Ruby integration harness (test/integration/run.rb). Add new scenarios to the YAML -- both sides pick them up.

Environment variables
Variable Purpose
GH_TOKEN / GITHUB_TOKEN Auth token for live tests (falls back to gh auth token)
GH_ACTIONS_LOCK_WORKFLOWS_DIR Override the workflows directory to scan (lab/testing use)
KEEP_FIXTURES Keep temp dirs after test runs for debugging

Directories

Path Synopsis
cmd
gh-actions-lock command
Command gh-actions-lock scans workflows and pins GitHub Actions to immutable commit SHAs.
Command gh-actions-lock scans workflows and pins GitHub Actions to immutable commit SHAs.
gh-actions-lock/format
Package format renders check reports for the `check` command.
Package format renders check reports for the `check` command.
internal
config
Package config loads CLI configuration from file and environment.
Package config loads CLI configuration from file and environment.
dep
Package dep defines the working dependency types shared between the resolver and the lockfile.
Package dep defines the working dependency types shared between the resolver and the lockfile.
ghapi
Package ghapi provides a unified GitHub API client that owns both REST and GraphQL connections, retry transport, and profiling instrumentation.
Package ghapi provides a unified GitHub API client that owns both REST and GraphQL connections, retry transport, and profiling instrumentation.
ghapi/httpmock
Package httpmock provides HTTP test fakes for the ghapi client.
Package httpmock provides HTTP test fakes for the ghapi client.
lockfile
Package lockfile manages CLI lockfile state: loading, saving, and converting the on-disk format.
Package lockfile manages CLI lockfile state: loading, saving, and converting the on-disk format.
pin
Package pin implements the two-phase pin lifecycle: Plan builds a complete Record of what to pin (pure computation + network reads), and Commit writes the Record to disk (workflow files + lockfile).
Package pin implements the two-phase pin lifecycle: Plan builds a complete Record of what to pin (pure computation + network reads), and Commit writes the Record to disk (workflow files + lockfile).
pinpool
Package pinpool is a small generic worker pool with a Reporter hook for per-slot UI status.
Package pinpool is a small generic worker pool with a Reporter hook for per-slot UI status.
pipeline
Package pipeline orchestrates the scan, resolve, check, and report flow for a single run.
Package pipeline orchestrates the scan, resolve, check, and report flow for a single run.
pipeline/checks
Package checks implements the structural, misleading-sha, and resolver-bound validators run against parsed workflows.
Package checks implements the structural, misleading-sha, and resolver-bound validators run against parsed workflows.
profile
Package profile captures phase timing, CPU profiles, and HTTP round-trip logs for performance analysis.
Package profile captures phase timing, CPU profiles, and HTTP round-trip logs for performance analysis.
resolve
Package resolve resolves action refs to commit SHAs, recursively discovers transitive dependencies, and verifies commit reachability.
Package resolve resolves action refs to commit SHAs, recursively discovers transitive dependencies, and verifies commit reachability.
syncmap
Package syncmap provides a simple generic mutex-guarded map.
Package syncmap provides a simple generic mutex-guarded map.
tag
Package tag lists tags, classifies versions, and applies release cooldown.
Package tag lists tags, classifies versions, and applies release cooldown.
ui
Package ui provides terminal-aware output formatting for gh-actions-lock.
Package ui provides terminal-aware output formatting for gh-actions-lock.
workflowfile
Package workflowfile owns the parsed workflow YAML representation: loading, extraction of action refs, local composite discovery, and comment-preserving rewriting.
Package workflowfile owns the parsed workflow YAML representation: loading, extraction of action refs, local composite discovery, and comment-preserving rewriting.
test
scenarios
Package scenarios provides a shared scenario catalog consumable by both Go tests and the Ruby integration harness.
Package scenarios provides a shared scenario catalog consumable by both Go tests and the Ruby integration harness.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL